PluginProbe
PayPlug for WooCommerce (Official) / 2.10.0
PayPlug for WooCommerce (Official) v2.10.0
3.0.0 2.18.0 1.0.17 1.0.18 1.0.19 1.0.20 1.0.21 1.0.22 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.1.0 1.10.0 1.10.1 1.2.1 1.2.10 1.2.11 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 All 101 releases
payplug / src / Controller / ApplePay.php

ApplePay.php in PayPlug for WooCommerce (Official) 2.10.0, at src/Controller/ApplePay.php

545 lines 15.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Payplug\PayplugWoocommerce\Controller;
4
5 use Payplug\Exception\HttpException;
6 use Payplug\PayplugWoocommerce\Gateway\PayplugAddressData;
7 use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
8 use Payplug\PayplugWoocommerce\Gateway\PayplugGateway;
9 use Payplug\Resource\Payment as PaymentResource;
10 use function is_cart;
11 use function is_checkout;
12
13 class ApplePay extends PayplugGateway
14 {
15
16 public $domain_name = "";
17
18 protected $cart=false;
19
20 protected $checkout = false;
21
22 protected $carriers = [];
23
24 const ENABLE_ON_TEST_MODE = false;
25
26 public $image = "apple-pay-checkout.svg";
27
28 public function __construct()
29 {
30
31 parent::__construct();
32
33 /** @var \WC_Settings_API override $id */
34 $this->id = 'apple_pay';
35
36 /** @var \WC_Payment_Gateway overwrite for apple pay settings */
37 $this->method_title = __('payplug_apple_pay_title', 'payplug');
38 $this->method_description = "";
39 $this->has_fields = false;
40
41 $this->title = __('payplug_apple_pay_title', 'payplug');
42 $this->description = '<div id="apple-pay-button-wrapper"><apple-pay-button buttonstyle="black" type="pay" locale="'. get_locale() .'"></apple-pay-button></div>';
43 $this->domain_name = $_SERVER['HTTP_HOST'];
44 $this->enabled = "no";
45
46
47 if( $this->checkApplePay() && is_admin()){
48 $this->enabled = "yes";
49
50 }else if( $this->checkApplePay() && $this->checkDeviceComptability() && $this->isSSL() ){
51
52 if (!is_admin() && $this->get_button_checkout()) {
53 $this->enabled = 'yes';
54 }
55
56
57 if (!is_admin() && is_checkout() && !$this->is_checkout_block() && $this->get_button_checkout()) {
58 $this->add_apple_pay_css();
59 add_action('wp_enqueue_scripts', [$this, 'add_apple_pay_js']);
60 }
61
62 if (!is_admin() && $this->get_button_cart()) {
63 $this->enabled = 'yes';
64 $this->add_apple_pay_css();
65 add_action('woocommerce_proceed_to_checkout', [$this, "add_apple_pay_cart_js"], 15);
66
67 }
68 }
69
70 }
71
72 /**
73 * @return bool|void
74 */
75 public function process_admin_options() {
76 $data = $this->get_post_data();
77 if (isset($data['woocommerce_payplug_mode'])) {
78 if ( $this->get_post_data()['woocommerce_payplug_mode'] === '0' ) {
79 $options = get_option( 'woocommerce_payplug_settings', [] );
80 $options['apple_pay'] = 'no';
81 update_option( 'woocommerce_payplug_settings', apply_filters( 'woocommerce_settings_api_sanitized_fields_payplug', $options ) );
82 }
83 }
84 if (isset($data['woocommerce_payplug_apple_pay'])) {
85 if (($data['woocommerce_payplug_apple_pay'] == 1) && (!$this->checkApplePay())) {
86 add_action( 'admin_notices', [$this ,"display_notice"] );
87 }
88 }
89
90 }
91
92 /**
93 *
94 * Check Apple Pay Authorization
95 *
96 * @return bool
97 */
98
99 public function checkApplePay(){
100 $options = PayplugWoocommerceHelper::get_payplug_options();
101
102 //it's disabled
103 if(isset($options['apple_pay']) && $options['apple_pay'] === "no"){
104 return false;
105 }
106
107 //Amount validations
108 if ( is_cart() && !empty( WC()->cart ) ) {
109 $order_amount = (float) WC()->cart->total;
110 if ($order_amount < self::MIN_AMOUNT || $order_amount > self::MAX_AMOUNT) {
111 return false;
112 }
113 }
114
115 //support legacy applepay
116 if( !isset($options['applepay_checkout']) && !isset($options['applepay_cart']) && isset($options['apple_pay']) && $options['apple_pay'] ==="yes"){
117 $this->set_button_checkout(true);
118 }
119
120 if(isset($options['applepay_checkout']) && $options['applepay_checkout'] === "yes"){
121 $this->set_button_checkout(true);
122 }
123
124 if(isset($options['applepay_cart']) && $options['applepay_cart'] === "yes"){
125 $this->set_button_cart(true);
126 }
127
128 if(isset($options['applepay_carriers']) ){
129 $this->set_carriers($options['applepay_carriers']);
130 }
131
132 $account = PayplugWoocommerceHelper::generic_get_account_data_from_options($this->id);
133 //no auth
134 if(!isset($account['payment_methods']['apple_pay']) || !isset($account['payment_methods']['apple_pay']['allowed_domain_names']) ){
135 return false;
136 }
137
138 //$account has permissions to use apple_pay
139 $auth = isset($account['payment_methods']['apple_pay']['enabled']) && $account['payment_methods']['apple_pay']['enabled'];
140 $auth_domains = in_array(strtr(get_site_url(), array("http://" => "", "https://" => "")), $account['payment_methods']['apple_pay']['allowed_domain_names']);
141
142 //lost auth
143 if(!($auth && $auth_domains)){
144 return false;
145 }
146
147 return true;
148 }
149
150 public function payment_fields()
151 {
152 $description = $this->get_description();
153
154 if (!empty($description)) {
155 echo wpautop(wptexturize($description));
156 }
157 }
158
159 /**
160 * extend the woocommmerce get description to include personalized html
161 *
162 * @return mixed|string|null
163 */
164 public function get_description()
165 {
166 return apply_filters('woocommerce_gateway_description', $this->description, $this->id);
167 }
168 public function add_apple_pay_cart_js(){
169 wp_enqueue_script( 'apple-pay-sdk', 'https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js', array(), false, true );
170 wp_enqueue_script('payplug-apple-pay-cart', PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/js/payplug-apple-pay-cart.js', ['jquery', 'apple-pay-sdk'], PAYPLUG_GATEWAY_VERSION, true);
171 wp_localize_script( 'payplug-apple-pay-cart', 'apple_pay_params',
172 array(
173 'ajax_url_applepay_get_shippings' => \WC_AJAX::get_endpoint('applepay_get_shippings'),
174 'ajax_url_place_order_with_dummy_data' => \WC_AJAX::get_endpoint('place_order_with_dummy_data'),
175 'ajax_url_update_applepay_order' => \WC_AJAX::get_endpoint('update_applepay_order'),
176 'ajax_url_update_applepay_payment' => \WC_AJAX::get_endpoint('update_applepay_payment'),
177 'ajax_url_applepay_get_order_totals' => \WC_AJAX::get_endpoint('applepay_get_order_totals'),
178 'ajax_url_applepay_cancel_order' => \WC_AJAX::get_endpoint('applepay_cancel_order'),
179 'is_cart' => is_cart(),
180 'countryCode' => WC()->customer->get_billing_country(),
181 'currencyCode' => get_woocommerce_currency(),
182 'apple_pay_domain' => $_SERVER['HTTP_HOST']
183 )
184 );
185
186 if($this->checkButtonVisibility()){
187 echo $this->get_description();
188 }
189 }
190
191 /**
192 * Check if the shipping address is a carrier
193 *
194 * @return bool
195 */
196 private function checkButtonVisibility(){
197 $apple_carriers = $this->get_carriers();
198 $allowed = false;
199 $post = $this->get_post_data();
200 $chosen_method = isset($post["shipping_method"][0]) ? $post["shipping_method"][0] : null;
201
202 if( empty($chosen_method) ){
203 $chosen_method = !empty(WC()->session->chosen_shipping_methods[0]) ? WC()->session->chosen_shipping_methods[0] : null;
204 }
205
206 if(!$this->is_shipping_required()){
207 return true;
208 }
209
210 foreach ( WC()->shipping()->get_packages() as $i => $package ) {
211 $available_rates = !empty($package['rates']) ? $package['rates'] : [];
212 if(!empty($available_rates)){
213 foreach($available_rates as $method){
214 if(in_array($method->get_method_id(), $apple_carriers) ){
215 if($chosen_method === $method->get_method_id() . ":" . $method->get_instance_id()){
216 $allowed = true;
217 }
218 }
219 }
220 }
221 }
222
223 return $allowed;
224 }
225
226 /**
227 *
228 * check if the shipping is required or not
229 * @return bool
230 */
231 public function is_shipping_required(){
232 $cart = WC()->cart->get_cart();
233
234 $required = true;
235 foreach ($cart as $cart_item){
236 if(!empty($cart_item['product_id']) ){
237 $product = wc_get_product( $cart_item['product_id'] );
238
239 //not required if it enters here
240 if(!$product->is_virtual() && !$product->is_downloadable()){
241 return true;
242 }
243
244 $required = false;
245 }
246 }
247
248 return $required;
249
250 }
251
252
253 /**
254 * Display unauthorized error
255 *
256 * @return void
257 */
258
259 public static function display_notice() {
260 ?>
261 <div class="notice notice-error is-dismissible">
262 <p><?php echo __( 'payplug_apple_pay_unauthorized_error', 'payplug' ); ?></p>
263 </div>
264 <?php
265 }
266
267 /**
268 * Check User-Agent to make sure it is on Mac OS
269 *
270 * @return bool
271 */
272 public function checkDeviceComptability(){
273 $user_agent = isset($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER['HTTP_USER_AGENT'] : '';
274
275 // Check if the Browser is Safari
276 if (stripos( $user_agent, 'Chrome') !== false) {
277 return false;
278
279 } elseif (stripos( $user_agent, 'Safari') !== false) {
280 // Check if the OS is Mac
281 if(!preg_match('/macintosh|mac os x/i', $user_agent)) {
282 return false;
283 }
284 }
285 return true;
286 }
287
288 /**
289 * Check if SSL
290 *
291 */
292 public function isSSL()
293 {
294 if( !empty( $_SERVER['HTTPS'] ) ) {
295 if ( 'on' == strtolower($_SERVER['HTTPS']) )
296 return true;
297 } elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
298 return true;
299 }
300
301 if( !empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https' )
302 return true;
303
304 return false;
305 }
306
307 /**
308 * Add CSS
309 *
310 */
311 public function add_apple_pay_css() {
312 wp_enqueue_style('payplug-apple-pay', PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/css/payplug-apple-pay.css', [], PAYPLUG_GATEWAY_VERSION);
313 }
314
315 /**
316 * Add JS
317 *
318 */
319 public function add_apple_pay_js() {
320 wp_enqueue_script( 'apple-pay-sdk', 'https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js', array(), false, true );
321 wp_enqueue_script('payplug-apple-pay', PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/js/payplug-apple-pay.js',
322 [
323 'jquery',
324 'apple-pay-sdk'
325 ], PAYPLUG_GATEWAY_VERSION, true);
326 wp_localize_script( 'payplug-apple-pay', 'apple_pay_params',
327 array(
328 'ajax_url_payplug_create_order' => \WC_AJAX::get_endpoint('payplug_create_order'),
329 'ajax_url_applepay_update_payment' => \WC_AJAX::get_endpoint('applepay_update_payment'),
330 'ajax_url_applepay_get_order_totals' => \WC_AJAX::get_endpoint('applepay_get_order_totals'),
331 'countryCode' => WC()->customer->get_billing_country(),
332 'currencyCode' => get_woocommerce_currency(),
333 'total' => WC()->cart->total,
334 'apple_pay_domain' => $this->domain_name
335 )
336 );
337 }
338
339 /**
340 * Get payment icons.
341 *
342 * @return string
343 */
344 public function get_icon()
345 {
346 $available_img = 'apple-pay-checkout.svg';
347 $icons = apply_filters('payplug_payment_icons', [
348 'payplug' => sprintf('<img src="%s" alt="Apple Pay" class="payplug-payment-icon" />', esc_url(PAYPLUG_GATEWAY_PLUGIN_URL . '/assets/images/checkout/' . $available_img)),
349 ]);
350 $icons_str = '';
351 foreach ($icons as $icon) {
352 $icons_str .= $icon;
353 }
354 return $icons_str;
355 }
356
357 /**
358 * if payment was generated by an intend, we shouldn't generate another one and try to pay it, this would generate duplications
359 * @param $order
360 * @return array|null
361 * @throws \Exception
362 */
363 private function process_standard_intent_payment($order){
364
365 if ( !is_wc_endpoint_url('order-pay') &&
366 $this->is_checkout_block() &&
367 !empty($order->get_transaction_id()) ) {
368
369 $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
370
371 try {
372 $payment = $this->api->payment_retrieve($order->get_transaction_id());
373 if (ob_get_length() > 0) {
374 ob_clean();
375 }
376
377 $return_url = esc_url_raw($order->get_checkout_order_received_url());
378
379 wp_send_json_success(
380 array(
381 'payment_id' => $payment->id,
382 'result' => 'success',
383 'redirect' => !empty($payment->hosted_payment->payment_url) ? $payment->hosted_payment->payment_url : $return_url,
384 'cancel' => !empty($payment->hosted_payment->cancel_url) ? $payment->hosted_payment->cancel_url : null
385 )
386 );
387
388 return array("stt" => "OK");
389
390 } catch (HttpException $e) {
391 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
392 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
393 } catch (\Exception $e) {
394 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
395 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
396 }
397 }
398
399 return null;
400 }
401
402
403 /**
404 * @param \WC_Order $order
405 * @param int $amount
406 * @param int $customer_id
407 *
408 * @return array
409 * @throws \Exception
410 */
411 public function process_standard_payment($order, $amount, $customer_id, $workflow = 'checkout')
412 {
413
414 $intent = $this->process_standard_intent_payment($order);
415 if( !empty($intent) ){
416 return $intent;
417 }
418
419 $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
420 try {
421 $address_data = PayplugAddressData::from_order($order);
422
423 $return_url = esc_url_raw($order->get_checkout_order_received_url());
424
425 if (!(substr( $return_url, 0, 4 ) === "http")) {
426 $return_url = get_site_url().$return_url;
427 }
428
429 // delivery_type must be removed in Apple Pay
430 $billing = $address_data->get_billing();
431 unset($billing['delivery_type']);
432 $shipping = $address_data->get_shipping();
433 unset($shipping['delivery_type']);
434
435 $payment_data = [
436 'amount' => $amount,
437 'currency' => get_woocommerce_currency(),
438 'payment_method' => $this->id,
439 'payment_context' => array(
440 'apple_pay' => array(
441 'domain_name' => $this->domain_name,
442 'application_data' => base64_encode(json_encode(array(
443 'apple_pay_domain' => $this->domain_name,
444 )))
445 )
446 ),
447 'billing' => $billing,
448 'shipping' => $shipping,
449 'hosted_payment' => [
450 'return_url' => $return_url,
451 'cancel_url' => esc_url_raw($order->get_cancel_order_url_raw()),
452 ],
453 'notification_url' => esc_url_raw(WC()->api_request_url('PayplugGateway')),
454 'metadata' => [
455 'order_id' => $order_id,
456 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
457 'domain' => $this->domain_name,
458 'applepay_workflow' => $workflow
459 ]
460 ];
461
462 /**
463 * Filter the payment data before it's used
464 *
465 * @param array $payment_data
466 * @param int $order_id
467 * @param array $customer_details
468 * @param PayplugAddressData $address_data
469 */
470 $payment_data = apply_filters('payplug_gateway_payment_data', $payment_data, $order_id, [], $address_data);
471 $payment = $this->api->payment_create($payment_data);
472
473 // Save transaction id for the order
474 PayplugWoocommerceHelper::is_pre_30()
475 ? update_post_meta($order_id, '_transaction_id', $payment->id)
476 : $order->set_transaction_id($payment->id);
477
478 if (is_callable([$order, 'save'])) {
479 $order->save();
480 }
481
482 /**
483 * Fires once a payment has been created.
484 *
485 * @param int $order_id Order ID
486 * @param PaymentResource $payment Payment resource
487 */
488 \do_action('payplug_gateway_payment_created', $order_id, $payment);
489
490 $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
491 PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
492
493 PayplugGateway::log(sprintf('Payment creation complete for order #%s', $order_id));
494
495 return [
496 'result' => 'success',
497 'merchant_session' => $payment->payment_method["merchant_session"],
498 'payment_id' => $payment->id,
499 'cancel_url' => esc_url_raw($order->get_cancel_order_url_raw()),
500 'return_url' => $return_url,
501 ];
502
503 } catch (HttpException $e) {
504 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
505 if($workflow === "cart"){
506 wp_send_json_error(["code" => $e->getCode(), "msg" => __('Payment processing failed. Please retry.', 'payplug'), "order_id" => $order_id ]);
507 }
508 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
509 } catch (\Exception $e) {
510 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
511 if($workflow === "cart"){
512 wp_send_json_error(["code" => $e->getCode(), "msg" => __('Payment processing failed. Please retry.', 'payplug'), "order_id" => $order_id ]);
513 }
514 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
515 }
516
517 }
518
519 private function set_button_checkout($status){
520 $this->checkout = $status;
521 }
522
523 private function set_button_cart($status){
524 $this->cart = $status;
525 }
526
527 private function get_button_checkout(){
528 return $this->checkout;
529 }
530
531 private function get_button_cart(){
532 return $this->cart;
533 }
534
535 private function get_carriers(){
536 return $this->carriers;
537 }
538
539 private function set_carriers($carriers){
540 $this->carriers = $carriers;
541 }
542
543
544 }
545