PluginProbe
PayPlug for WooCommerce (Official) / 2.8.0
PayPlug for WooCommerce (Official) v2.8.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.8.0, at src/Controller/ApplePay.php

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