PluginProbe
PayPlug for WooCommerce (Official) / 1.0.22
PayPlug for WooCommerce (Official) v1.0.22
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 / Gateway / PayplugGateway.php

PayplugGateway.php in PayPlug for WooCommerce (Official) 1.0.22, at src/Gateway/PayplugGateway.php

1,440 lines 51.4 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\Gateway;
4
5 // Exit if accessed directly
6 if (!defined('ABSPATH')) {
7 exit;
8 }
9
10 use Payplug\Authentication;
11 use Payplug\Exception\ConfigurationException;
12 use Payplug\Exception\HttpException;
13 use Payplug\Payplug;
14 use Payplug\PayplugWoocommerce\Admin\Ajax;
15 use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
16 use Payplug\Resource\Payment as PaymentResource;
17 use Payplug\Resource\Refund as RefundResource;
18 use WC_Payment_Gateway_CC;
19 use WC_Payment_Tokens;
20
21 /**
22 * PayPlug WooCommerce Gateway.
23 *
24 * @package Payplug\PayplugWoocommerce\Gateway
25 */
26 class PayplugGateway extends WC_Payment_Gateway_CC
27 {
28
29 /**
30 * @var PayplugGatewayRequirements
31 */
32 private $requirements;
33
34 /**
35 * @var PayplugPermissions
36 */
37 private $permissions;
38
39 /**
40 * @var PayplugResponse
41 */
42 public $response;
43
44 /**
45 * @var PayplugApi
46 */
47 public $api;
48
49 /**
50 * @var \WC_Logger
51 */
52 protected static $log;
53
54 /**
55 * @var bool
56 */
57 protected static $log_enabled;
58
59 /**
60 * @var float
61 */
62 const MIN_AMOUNT = 0.99;
63
64 /**
65 * @var float
66 */
67 const MAX_AMOUNT = 20000;
68
69 /**
70 * Logging method.
71 *
72 * @param string $message Log message.
73 * @param string $level Optional. Default 'info'.
74 * emergency|alert|critical|error|warning|notice|info|debug
75 */
76 public static function log($message, $level = 'info')
77 {
78 if (!self::$log_enabled) {
79 return;
80 }
81
82 if (empty(self::$log)) {
83 self::$log = PayplugWoocommerceHelper::is_pre_30() ? new \WC_Logger() : wc_get_logger();
84 }
85
86 PayplugWoocommerceHelper::is_pre_30()
87 ? self::$log->add('payplug_gateway', $message)
88 : self::$log->log($level, $message, array('source' => 'payplug_gateway'));
89 }
90
91 public function __construct()
92 {
93 $this->id = 'payplug';
94 $this->icon = '';
95 $this->has_fields = false;
96 $this->method_title = _x('PayPlug', 'Gateway method title', 'payplug');
97 $this->method_description = __('Enable PayPlug for your customers.', 'payplug');
98 $this->supports = array(
99 'products',
100 'refunds',
101 'tokenization',
102 );
103 $this->new_method_label = __('Pay with another credit card', 'payplug');
104
105 $this->init_settings();
106 $this->requirements = new PayplugGatewayRequirements($this);
107 if ($this->user_logged_in()) {
108 $this->init_payplug();
109 }
110 $this->init_form_fields();
111
112 $this->title = $this->get_option('title');
113 $this->description = $this->get_option('description');
114 $this->mode = 'yes' === $this->get_option('mode', 'no') ? 'live' : 'test';
115 $this->debug = 'yes' === $this->get_option('debug', 'no');
116 $this->email = $this->get_option('email');
117 $this->payment_method = $this->get_option('payment_method');
118 $this->oneclick = 'yes' === $this->get_option('oneclick', 'no');
119
120 add_filter('woocommerce_get_customer_payment_tokens', [$this, 'filter_tokens'], 10, 3);
121
122 self::$log_enabled = $this->debug;
123
124 // Ensure the description is not empty to correctly display users's save cards
125 if (empty($this->description) && 0 !== count($this->get_tokens())) {
126 $this->description = ' ';
127 }
128
129 if ('test' === $this->mode) {
130 $this->description .= " \n";
131
132 $this->description .= __('You are in TEST MODE. In test mode you can use the card 4242424242424242 with any valid expiration date and CVC.', 'payplug');
133 $this->description = trim($this->description);
134 }
135
136 add_filter('woocommerce_get_order_item_totals', [$this, 'customize_gateway_title'], 10, 2);
137 add_action('wp_enqueue_scripts', [$this, 'scripts']);
138 add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']);
139 add_action('the_post', [$this, 'validate_payment']);
140 add_action('woocommerce_available_payment_gateways', [$this, 'check_gateway']);
141 }
142
143 /**
144 * Customize gateway title in emails.
145 *
146 * @param array $total_rows
147 * @param \WC_Order $order
148 *
149 * @return array
150 *
151 * @author Clément Boirie
152 */
153 public function customize_gateway_title($total_rows, $order)
154 {
155
156 $payment_method = PayplugWoocommerceHelper::is_pre_30() ? $order->payment_method : $order->get_payment_method();
157 if (
158 $this->id !== $payment_method
159 || !isset($total_rows['payment_method'])
160 ) {
161 return $total_rows;
162 }
163
164 $total_rows['payment_method']['value'] = __('Credit card', 'payplug');
165
166 return $total_rows;
167 }
168
169 /**
170 * Validate order payment when the user is redirected to the success confirmation page.
171 *
172 * @throws \WC_Data_Exception
173 */
174 public function validate_payment()
175 {
176 if (!is_wc_endpoint_url('order-received') || empty($_GET['key'])) {
177 return;
178 }
179
180 $order_id = wc_get_order_id_by_order_key(wc_clean($_GET['key']));
181 if (empty($order_id)) {
182 return;
183 }
184
185 $order = wc_get_order($order_id);
186 if (!$order instanceof \WC_Order) {
187 return;
188 }
189
190 $payment_method = PayplugWoocommerceHelper::is_pre_30() ? $order->payment_method : $order->get_payment_method();
191 if ('payplug' !== $payment_method) {
192 return;
193 }
194
195 $transaction_id = PayplugWoocommerceHelper::is_pre_30() ? get_post_meta($order_id, '_transaction_id', true) : $order->get_transaction_id();
196 if (empty($transaction_id)) {
197 PayplugGateway::log(sprintf('Order #%s : Missing transaction id.', $order_id), 'error');
198
199 return;
200 }
201
202 try {
203 $payment = $this->api->payment_retrieve($transaction_id);
204 } catch (\Exception $e) {
205 PayplugGateway::log(
206 sprintf(
207 'Order #%s : An error occurred while retrieving the payment data with the message : %s',
208 $order_id,
209 $e->getMessage()
210 )
211 );
212
213 return;
214 }
215
216 $this->response->process_payment($payment);
217 }
218
219 /**
220 * Get payment icons.
221 *
222 * @return string
223 */
224 public function get_icon()
225 {
226
227 $src = ('it_IT' === get_locale())
228 ? PAYPLUG_GATEWAY_PLUGIN_URL . '/assets/images/logos_scheme_PostePay.svg'
229 : PAYPLUG_GATEWAY_PLUGIN_URL . '/assets/images/logos_scheme_CB.svg';
230
231 $icons = apply_filters('payplug_payment_icons', [
232 'payplug' => sprintf('<img src="%s" alt="Visa & Mastercard" class="payplug-payment-icon" />', esc_url($src)),
233 ]);
234
235 $icons_str = '';
236 foreach ($icons as $icon) {
237 $icons_str .= $icon;
238 }
239
240 return $icons_str;
241 }
242
243 /**
244 * Check if this gateway is enabled
245 */
246 public function is_available()
247 {
248 if ('yes' === $this->enabled) {
249 return $this->requirements->satisfy_requirements() && !empty($this->get_api_key($this->get_current_mode()));
250 }
251
252 return parent::is_available();
253 }
254
255 /**
256 * Load gateway settings.
257 */
258 public function init_settings()
259 {
260 parent::init_settings();
261 $this->enabled = !empty($this->settings['enabled']) && 'yes' === $this->settings['enabled'] ? 'yes' : 'no';
262 }
263
264 /**
265 * Register gateway settings.
266 */
267 public function init_form_fields()
268 {
269 $fields = [
270 'enabled' => [
271 'title' => __('Enable/Disable', 'payplug'),
272 'type' => 'checkbox',
273 'label' => __('Enable PayPlug', 'payplug'),
274 'description' => __('Only Euro payments can be processed with PayPlug.', 'payplug'),
275 'default' => 'no',
276 ],
277 'title' => [
278 'title' => __('Title', 'payplug'),
279 'type' => 'text',
280 'description' => __('The payment solution title displayed during checkout.', 'payplug'),
281 'default' => _x('Credit card checkout', 'Default gateway title', 'payplug'),
282 'desc_tip' => true,
283 ],
284 'description' => [
285 'title' => __('Description', 'payplug'),
286 'type' => 'text',
287 'description' => __('The payment solution description displayed during checkout.', 'payplug'),
288 'default' => '',
289 'desc_tip' => true,
290 ],
291 'title_connexion' => [
292 'title' => __('Connection', 'payplug'),
293 'type' => 'title',
294 ],
295 'email' => [
296 'type' => 'hidden',
297 'default' => '',
298 ],
299 'login' => [
300 'type' => 'login',
301 'default' => '',
302 ],
303 'payplug_test_key' => [
304 'type' => 'hidden',
305 'default' => '',
306 ],
307 'payplug_live_key' => [
308 'type' => 'hidden',
309 'default' => '',
310 ],
311 'payplug_merchant_id' => [
312 'type' => 'hidden',
313 'default' => '',
314 ],
315 'title_testmode' => [
316 'title' => __('Mode', 'payplug'),
317 'type' => 'title',
318 ],
319 'mode' => [
320 'title' => '',
321 'label' => '',
322 'type' => 'yes_no',
323 'yes' => 'Live',
324 'no' => 'Test',
325 'description' => __('In TEST mode, all payments will be simulations and will not generate real transactions.', 'payplug'),
326 'default' => 'no',
327 'hide_label' => true,
328 ],
329 'title_settings' => [
330 'title' => __('Settings', 'payplug'),
331 'type' => 'title',
332 ],
333 'payment_method' => [
334 'title' => __('Payment page', 'payplug'),
335 'type' => 'radio',
336 'description' => __('Customers will be redirected to a PayPlug payment page to finalize the transaction, or payments will be performed in an embeddable payment form on your website.', 'payplug'),
337 'default' => 'redirect',
338 'desc_tip' => true,
339 'options' => array(
340 'redirect' => __('Redirect', 'payplug'),
341 'embedded' => __('Integrated', 'payplug'),
342 ),
343 ],
344 'debug' => [
345 'title' => __('Debug', 'payplug'),
346 'type' => 'checkbox',
347 'description' => __('Debug mode saves additional information on your server for each operation done via the PayPlug plugin (Developer setting).', 'payplug'),
348 'label' => __('Activate debug mode', 'payplug'),
349 'default' => 'yes',
350 'desc_tip' => true,
351 ],
352 'title_advanced_settings' => [
353 'title' => __('Advanced Settings', 'payplug'),
354 'description' => __(
355 'Your current offer does not allow this option. Try it on TEST mode. More information <a href="https://www.payplug.com/pricing" target="_blank">here.</a>',
356 'payplug'
357 ),
358 'type' => 'title',
359 ],
360 'oneclick' => [
361 'title' => __('One Click Payment', 'payplug'),
362 'type' => 'checkbox',
363 'label' => __('Activate', 'payplug'),
364 'description' => __('Allow your customers to save their credit card information for later purchases.', 'payplug'),
365 'default' => 'no',
366 'desc_tip' => true
367 ],
368 ];
369
370 if ($this->user_logged_in() && !$this->permissions->has_permissions(PayplugPermissions::SAVE_CARD) && 'live' === $this->get_current_mode()) {
371 $fields['oneclick']['disabled'] = true;
372 }
373
374 /**
375 * Filter PayPlug gateway settings.
376 *
377 * @param array $fields
378 */
379 $fields = apply_filters('payplug_gateway_settings', $fields);
380 $this->form_fields = $fields;
381 }
382
383 /**
384 * Set global configuration for PayPlug instance.
385 */
386 public function init_payplug()
387 {
388 $this->api = new PayplugApi($this);
389 $this->api->init();
390
391 $this->permissions = new PayplugPermissions($this);
392 $this->response = new PayplugResponse($this);
393
394 // Register IPN handler
395 new PayplugIpnResponse($this);
396 }
397
398 /**
399 * Embedded payment form scripts.
400 *
401 * Register scripts and additionnal data needed for the
402 * embedded payment form.
403 */
404 public function scripts()
405 {
406 if (!is_cart() && !is_checkout() && !isset($_GET['pay_for_order']) && !is_add_payment_method_page() && !isset($_GET['change_payment_method'])) {
407 return;
408 }
409
410 // If PayPlug is not enabled bail.
411 if ('no' === $this->enabled) {
412 return;
413 }
414
415 // If keys are not set bail.
416 if (empty($this->get_api_key($this->mode))) {
417 PayplugGateway::log('Keys are not set correctly.');
418
419 return;
420 }
421
422 // Register checkout styles.
423 wp_register_style('payplug-checkout', PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/css/payplug-checkout.css', [], PAYPLUG_GATEWAY_VERSION);
424 wp_enqueue_style('payplug-checkout');
425
426
427 // Register scripts for embedded payment form.
428 if ('embedded' !== $this->payment_method) {
429 return;
430 }
431
432 wp_register_script('payplug', 'https://api.payplug.com/js/1/form.latest.js', [], null, true);
433 wp_register_script('payplug-checkout', PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/js/payplug-checkout.js', [
434 'jquery',
435 'payplug'
436 ], PAYPLUG_GATEWAY_VERSION, true);
437 wp_localize_script('payplug-checkout', 'payplug_checkout_params', [
438 'ajax_url' => \WC_AJAX::get_endpoint('payplug_create_order'),
439 'nonce' => [
440 'checkout' => wp_create_nonce('woocommerce-process_checkout'),
441 ],
442 ]);
443 wp_enqueue_script('payplug-checkout');
444 }
445
446 /**
447 * Filter saved tokens for the gateway.
448 *
449 * A token will be removed if :
450 * - it doesn't match the current merchant logged in,
451 * - or it doesn't match the current gateway mode,
452 * - or it is expired.
453 *
454 * @param array $tokens
455 * @param int $user_id
456 * @param string $gateway_id
457 *
458 * @return array
459 */
460 public function filter_tokens($tokens, $user_id, $gateway_id)
461 {
462
463 if (!is_user_logged_in() || !class_exists('WC_Payment_Gateway_CC')) {
464 return $tokens;
465 }
466
467 /* @var \WC_Payment_Token_CC $token */
468 foreach ($tokens as $k => $token) {
469
470 if ($this->id !== $token->get_gateway_id()) {
471 continue;
472 }
473
474 // check if token is associated with a merchant id and if it match the current one
475 $token_merchant_id = $token->get_meta('payplug_account', true);
476 if (empty($token_merchant_id) || $this->get_merchant_id() !== $token_merchant_id) {
477 unset($tokens[$k]);
478 continue;
479 }
480
481 // check if token is available for the current gateway mode
482 if ($this->mode !== $token->get_meta('mode', true)) {
483 unset($tokens[$k]);
484 continue;
485 }
486
487 // check if token is not expired
488 $current_month = \absint(date('n'));
489 $current_year = \absint(date('Y'));
490 if ($current_year > (int) $token->get_expiry_year()) {
491 unset($tokens[$k]);
492 continue;
493 }
494
495 if ($current_year === (int) $token->get_expiry_year() && $current_month >= (int) $token->get_expiry_month()) {
496 unset($tokens[$k]);
497 continue;
498 }
499 }
500
501 return $tokens;
502 }
503
504 public function payment_fields()
505 {
506 $description = $this->get_description();
507 if (!empty($description)) {
508 echo wpautop(wptexturize($description));
509 }
510
511 if ($this->oneclick_available()) {
512 $this->tokenization_script();
513 $this->saved_payment_methods();
514 }
515 }
516
517 /**
518 * Handle admin display.
519 */
520 public function admin_options()
521 {
522 wp_enqueue_style(
523 'payplug-gateway-style',
524 PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/css/app.css',
525 [],
526 PAYPLUG_GATEWAY_VERSION
527 );
528
529 wp_enqueue_script(
530 'payplug-gateway-admin',
531 PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/js/payplug-admin.js',
532 ['jquery-ui-dialog'],
533 PAYPLUG_GATEWAY_VERSION
534 );
535
536 wp_localize_script('payplug-gateway-admin', 'payplug_admin_config', array(
537 'ajax_url' => admin_url('admin-ajax.php'),
538 'has_live_key' => (false === $this->has_api_key('live')) ? false : true,
539 'btn_ok' => _x('Ok', 'modal', 'payplug'),
540 'btn_label' => _x('Cancel', 'modal', 'payplug'),
541 'general_error' => _x('Something went wrong. Please refresh the page and retry.', 'modal', 'payplug'),
542 ));
543
544 if ($this->user_logged_in() && false === $this->has_api_key('live')) {
545
546 add_action('admin_footer', function () {
547 $email = $this->get_option('email');
548 ?>
549 <div id="payplug-refresh-keys-modal" title="<?php echo esc_attr_x('Mode LIVE', 'modal', 'payplug'); ?>">
550 <form id="payplug-refresh-keys-modal__form">
551 <p id="dialog-msg"></p>
552 <p><?php echo esc_html_x('Please enter your PayPlug account password', 'modal', 'payplug'); ?></p>
553 <input type="password" name="password" required title="<?php echo esc_attr_x('Enter your PayPlug account password', 'modal', 'payplug'); ?>" />
554 <input type="hidden" name="email" value="<?php echo esc_attr($email); ?>">
555 <input type="hidden" name="action" value="<?php echo esc_attr(Ajax::REFRESH_KEY_ACTION); ?>">
556 <?php wp_nonce_field(sprintf('%s_%s', $email, Ajax::REFRESH_KEY_ACTION)); ?>
557 <input class="ui-dialog-sronly" type="submit" tabindex="-1">
558 </form>
559 </div>
560 <?php
561 });
562 }
563
564 $payplug_requirements = new PayplugGatewayRequirements($this); ?>
565
566 <h2 class="title--logo"><?php esc_html($this->get_method_title()) ?></h2>
567 <p><?php _e(sprintf('Version %s', PAYPLUG_GATEWAY_VERSION)); ?></p>
568 <div class="payplug-requirements">
569 <?php echo $payplug_requirements->curl_requirement(); ?>
570 <?php echo $payplug_requirements->php_requirement(); ?>
571 <?php echo $payplug_requirements->openssl_requirement(); ?>
572 <?php echo $payplug_requirements->account_requirement(); ?>
573 <?php echo $payplug_requirements->currency_requirement(); ?>
574 </div>
575 <?php echo wp_kses_post(wpautop($this->get_method_description())); ?>
576
577 <?php if ($this->user_logged_in()) : ?>
578 <table class="form-table">
579 <?php $this->generate_settings_html($this->get_form_fields()); ?>
580 </table>
581 <?php else :
582 $GLOBALS['hide_save_button'] = true; ?>
583 <h3 class="wc-settings-sub-title"><?php _e('Connection', 'payplug'); ?></h3>
584 <table class="form-table">
585 <tbody>
586 <tr valign="top">
587 <th scope="row" class="titledesc">
588 <label for="payplug_email"><?php _e('Email', 'payplug'); ?></label>
589 </th>
590 <td class="forminp">
591 <fieldset>
592 <legend class="screen-reader-text"><span><?php _e('Email', 'payplug'); ?></span></legend>
593 <input class="input-text regular-input" type="text" name="payplug_email" id="payplug_email" value="" placeholder="<?php _e('your@email.com', 'payplug'); ?>" />
594 </fieldset>
595 </td>
596 </tr>
597 <tr valign="top">
598 <th scope="row" class="titledesc">
599 <label for="payplug_password"><?php _e('Password', 'payplug'); ?></label>
600 </th>
601 <td class="forminp">
602 <fieldset>
603 <legend class="screen-reader-text"><span><?php _e('Password', 'payplug'); ?></span>
604 </legend>
605 <input class="input-text regular-input" type="password" name="payplug_password" id="payplug_password" value="" />
606 </fieldset>
607 </td>
608 </tr>
609 <tr valign="top">
610 <td class="forminp">
611 <input class="button" type="submit" value="<?php _e('Login', 'payplug'); ?>">
612 <input type="hidden" name="save" value="login">
613 <?php wp_nonce_field('payplug_user_login', '_loginaction'); ?>
614 </td>
615 </tr>
616 </tbody>
617 </table>
618 <?php
619 endif;
620 }
621
622 /**
623 * Process admin options.
624 *
625 * @return bool
626 */
627 public function process_admin_options()
628 {
629 $data = $this->get_post_data();
630
631 // Handle logout process
632 if (
633 isset($data['submit_logout'])
634 && false !== check_admin_referer('payplug_user_logout', '_logoutaction')
635 ) {
636
637 if ($this->permissions) {
638 $this->permissions->clear_permissions();
639 }
640
641 $data = get_option($this->get_option_key());
642 $data['payplug_test_key'] = '';
643 $data['payplug_live_key'] = '';
644 $data['payplug_merchant_id'] = '';
645 $data['enabled'] = 'no';
646 $data['mode'] = 'no';
647 $data['oneclick'] = 'no';
648 update_option(
649 $this->get_option_key(),
650 apply_filters('woocommerce_settings_api_sanitized_fields_' . $this->id, $data)
651 );
652 \WC_Admin_Settings::add_message(__('Successfully logged out.', 'payplug'));
653
654 return true;
655 }
656
657 // Handle login process
658 if (
659 isset($data['payplug_email'])
660 && false !== check_admin_referer('payplug_user_login', '_loginaction')
661 ) {
662 $email = $data['payplug_email'];
663 $password = wp_unslash($data['payplug_password']);
664 $response = $this->retrieve_user_api_keys($email, $password);
665 if (is_wp_error($response)) {
666 \WC_Admin_Settings::add_error($response->get_error_message());
667
668 return false;
669 }
670
671 // try to use the api keys to retrieve the merchant id
672 $merchant_id = isset($response['test']) ? $this->retrieve_merchant_id($response['test']) : '';
673
674 $this->init_form_fields();
675 $fields = $this->get_form_fields();
676 $data = [];
677
678 // Load existing values if the user is re-login.
679 foreach ($fields as $key => $field) {
680 if (in_array($field['type'], ['title', 'login'])) {
681 continue;
682 }
683
684 switch ($key) {
685 case 'enabled':
686 $val = 'yes';
687 break;
688 case 'mode':
689 $val = 'no';
690 break;
691 case 'payplug_test_key':
692 $val = esc_attr($response['test']);
693 break;
694 case 'payplug_live_key':
695 $val = esc_attr($response['live']);
696 break;
697 case 'payplug_merchant_id':
698 $val = esc_attr($merchant_id);
699 break;
700 case 'email':
701 $val = esc_html($email);
702 break;
703 default:
704 $val = $this->get_option($key);
705 }
706
707 $data[$key] = $val;
708 }
709
710 $this->set_post_data($data);
711 update_option(
712 $this->get_option_key(),
713 apply_filters('woocommerce_settings_api_sanitized_fields_' . $this->id, $data)
714 );
715 \WC_Admin_Settings::add_message(__('Successfully logged in.', 'payplug'));
716
717 return true;
718 }
719
720 // Don't let user without live key leave TEST mode.
721 $mode_fieldkey = $this->get_field_key('mode');
722 $live_key_fieldkey = $this->get_field_key('payplug_live_key');
723 if (isset($data[$mode_fieldkey]) && '1' === $data[$mode_fieldkey] && empty($data[$live_key_fieldkey])) {
724 $data[$mode_fieldkey] = '0';
725 $this->set_post_data($data);
726 \WC_Admin_Settings::add_error(__('Your account does not support LIVE mode at the moment, it must be validated first. If your account has already been validated, please log out and log in again.', 'payplug'));
727 }
728
729 // Check user permissions before activating one-click feature.
730 $oneclick_fieldkey = $this->get_field_key('oneclick');
731 if (
732 isset($data[$oneclick_fieldkey])
733 && '1' === $data[$oneclick_fieldkey]
734 && (!$this->user_logged_in()
735 || false === $this->permissions->has_permissions(PayplugPermissions::SAVE_CARD))
736 ) {
737 $data[$oneclick_fieldkey] = '0';
738 \WC_Admin_Settings::add_error(__('Only PREMIUM accounts can enable the One Click option in LIVE mode.', 'payplug'));
739 }
740
741 parent::process_admin_options();
742 }
743
744 /**
745 * Process payment.
746 *
747 * @param int $order_id
748 *
749 * @return array
750 * @throws \Exception
751 */
752 public function process_payment($order_id)
753 {
754
755 PayplugGateway::log(sprintf('Processing payment for order #%s', $order_id));
756
757 $order = wc_get_order($order_id);
758 $customer_id = PayplugWoocommerceHelper::is_pre_30() ? $order->customer_user : $order->get_customer_id();
759 $amount = (int) PayplugWoocommerceHelper::get_payplug_amount($order->get_total());
760 $amount = $this->validate_order_amount($amount);
761 if (is_wp_error($amount)) {
762 PayplugGateway::log(sprintf('Invalid amount %s for the order.', $order->get_total()), 'error');
763 throw new \Exception($amount->get_error_message());
764 }
765
766 $payment_token_id = (isset($_POST['wc-' . $this->id . '-payment-token']) && 'new' !== $_POST['wc-' . $this->id . '-payment-token'])
767 ? wc_clean($_POST['wc-' . $this->id . '-payment-token'])
768 : false;
769
770 if ($payment_token_id && $this->oneclick_available() && (int) $customer_id > 0) {
771 PayplugGateway::log(sprintf('Payment token found.', $amount));
772
773 return $this->process_payment_with_token($order, $amount, $customer_id, $payment_token_id);
774 }
775
776 return $this->process_standard_payment($order, $amount, $customer_id);
777 }
778
779 /**
780 * @param \WC_Order $order
781 * @param int $amount
782 * @param int $customer_id
783 *
784 * @return array
785 * @throws \Exception
786 */
787 public function process_standard_payment($order, $amount, $customer_id)
788 {
789
790 $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
791
792 try {
793 $address_data = PayplugAddressData::from_order($order);
794
795 $payment_data = [
796 'amount' => $amount,
797 'currency' => get_woocommerce_currency(),
798 'allow_save_card' => $this->oneclick_available() && (int) $customer_id > 0,
799 'billing' => $address_data->get_billing(),
800 'shipping' => $address_data->get_shipping(),
801 'hosted_payment' => [
802 'return_url' => esc_url_raw($order->get_checkout_order_received_url()),
803 'cancel_url' => esc_url_raw($order->get_cancel_order_url_raw()),
804 ],
805 'notification_url' => esc_url_raw(WC()->api_request_url('PayplugGateway')),
806 'metadata' => [
807 'order_id' => $order_id,
808 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
809 'domain' => $this->limit_length(esc_url_raw(home_url()), 500),
810 ],
811 ];
812
813 /**
814 * Filter the payment data before it's used
815 *
816 * @param array $payment_data
817 * @param int $order_id
818 * @param array $customer_details
819 * @param PayplugAddressData $address_data
820 */
821 $payment_data = apply_filters('payplug_gateway_payment_data', $payment_data, $order_id, [], $address_data);
822 $payment = $this->api->payment_create($payment_data);
823
824 // Save transaction id for the order
825 PayplugWoocommerceHelper::is_pre_30()
826 ? update_post_meta($order_id, '_transaction_id', $payment->id)
827 : $order->set_transaction_id($payment->id);
828
829 if (is_callable([$order, 'save'])) {
830 $order->save();
831 }
832
833 /**
834 * Fires once a payment has been created.
835 *
836 * @param int $order_id Order ID
837 * @param PaymentResource $payment Payment resource
838 */
839 \do_action('payplug_gateway_payment_created', $order_id, $payment);
840
841 $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
842 PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
843
844 PayplugGateway::log(sprintf('Payment creation complete for order #%s', $order_id));
845
846 return [
847 'result' => 'success',
848 'redirect' => $payment->hosted_payment->payment_url,
849 'cancel' => $payment->hosted_payment->cancel_url,
850 ];
851 } catch (HttpException $e) {
852 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
853 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
854 } catch (\Exception $e) {
855 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
856 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
857 }
858 }
859
860 /**
861 * @param \WC_Order $order
862 * @param int $amount
863 * @param int $customer_id
864 * @param string $token_id
865 *
866 * @return array
867 * @throws \Exception
868 */
869 public function process_payment_with_token($order, $amount, $customer_id, $token_id)
870 {
871
872 $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
873 $payment_token = WC_Payment_Tokens::get($token_id);
874 if (!$payment_token || (int) $customer_id !== (int) $payment_token->get_user_id()) {
875 PayplugGateway::log('Could not find the payment token or the payment doesn\'t belong to the current user.', 'error');
876 throw new \Exception(__('Invalid payment method.', 'payplug'));
877 }
878
879 try {
880 $address_data = PayplugAddressData::from_order($order);
881
882 $payment_data = [
883 'amount' => $amount,
884 'currency' => get_woocommerce_currency(),
885 'payment_method' => $payment_token->get_token(),
886 'billing' => $address_data->get_billing(),
887 'shipping' => $address_data->get_shipping(),
888 'notification_url' => esc_url_raw(WC()->api_request_url('PayplugGateway')),
889 'metadata' => [
890 'order_id' => $order_id,
891 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
892 'domain' => $this->limit_length(esc_url_raw(home_url()), 500),
893 ],
894 ];
895
896 /** This filter is documented in src/Gateway/PayplugGateway */
897 $payment_data = apply_filters('payplug_gateway_payment_data', $payment_data, $order_id, [], $address_data);
898 $payment = $this->api->payment_create($payment_data);
899
900 /** This action is documented in src/Gateway/PayplugGateway */
901 \do_action('payplug_gateway_payment_created', $order_id, $payment);
902
903 $this->response->process_payment($payment, true);
904
905 PayplugGateway::log(sprintf('Payment process complete for order #%s', $order_id));
906
907 return [
908 'result' => 'success',
909 'redirect' => $order->get_checkout_order_received_url(),
910 ];
911 } catch (HttpException $e) {
912 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
913 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
914 } catch (\Exception $e) {
915 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
916 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
917 }
918 }
919
920 /**
921 * Process refund for an order paid with PayPlug gateway.
922 *
923 * @param int $order_id
924 * @param null $amount
925 * @param string $reason
926 *
927 * @return bool|\WP_Error
928 */
929 public function process_refund($order_id, $amount = null, $reason = '')
930 {
931 PayplugGateway::log(sprintf('Processing refund for order #%s', $order_id));
932
933 $order = wc_get_order($order_id);
934 if (!$order instanceof \WC_Order) {
935 PayplugGateway::log(sprintf('The order #%s does not exist.', $order_id), 'error');
936
937 return new \WP_Error('process_refund_error', sprintf(__('The order %s does not exist.', 'payplug'), $order_id));
938 }
939
940 if ($order->get_status() === "cancelled") {
941 PayplugGateway::log(sprintf('The order #%s cannot be refund.', $order_id), 'error');
942
943 return new \WP_Error('process_refund_error', sprintf(__('The order %s cannot be refund.', 'payplug'), $order_id));
944 }
945
946 $transaction_id = PayplugWoocommerceHelper::is_pre_30() ? get_post_meta($order_id, '_transaction_id', true) : $order->get_transaction_id();
947 if (empty($transaction_id)) {
948 PayplugGateway::log(sprintf('The order #%s does not have PayPlug transaction ID associated with it.', $order_id), 'error');
949
950 return new \WP_Error('process_refund_error', __('No PayPlug transaction was found for this order. The refund could not be processed.', 'payplug'));
951 }
952
953 $customer_id = PayplugWoocommerceHelper::is_pre_30() ? $order->customer_user : $order->get_customer_id();
954
955 $data = [
956 'metadata' => [
957 'order_id' => $order_id,
958 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
959 'refund_from' => 'woocommerce',
960 ]
961 ];
962
963 if (!is_null($amount)) {
964 $data['amount'] = PayplugWoocommerceHelper::get_payplug_amount($amount);
965 }
966
967 if (!empty($reason)) {
968 $data['metadata']['reason'] = $reason;
969 }
970
971 /**
972 * Filter the refund data before it's used.
973 *
974 * @param array $data
975 * @param int $order_id
976 * @param string $transaction_id
977 */
978 $data = apply_filters('payplug_gateway_refund_data', $data, $order_id, $transaction_id);
979
980 try {
981 $refund = $this->api->refund_create($transaction_id, $data);
982
983 /**
984 * Fires once a refund has been created.
985 *
986 * @param int $order_id Order ID
987 * @param RefundResource $refund Refund resource
988 * @param string $transaction_id Transaction id
989 */
990 \do_action('payplug_gateway_refund_created', $order_id, $refund, $transaction_id);
991
992 $refund_meta_key = sprintf('_pr_%s', wc_clean($refund->id));
993 if (PayplugWoocommerceHelper::is_pre_30()) {
994 update_post_meta($order_id, $refund_meta_key, $refund->id);
995 } else {
996 $order->add_meta_data($refund_meta_key, $refund->id, true);
997 $order->save();
998 }
999
1000 $note = sprintf(__('Refund %s : Refunded %s', 'payplug'), wc_clean($refund->id), wc_price(((int) $refund->amount) / 100));
1001 if (!empty($refund->metadata['reason'])) {
1002 $note .= sprintf(' (%s)', esc_html($refund->metadata['reason']));
1003 }
1004 $order->add_order_note($note);
1005
1006 try {
1007 $payment = $this->api->payment_retrieve($transaction_id);
1008 $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
1009 PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
1010 } catch (\Exception $e) {
1011 }
1012
1013 PayplugGateway::log('Refund process complete for the order.');
1014
1015 return true;
1016 } catch (HttpException $e) {
1017 PayplugGateway::log(sprintf('Refund request error for the order %s from PayPlug API : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
1018
1019 return new \WP_Error('process_refund_error', __('The transaction could not be refunded. Please try again.', 'payplug'));
1020 } catch (\Exception $e) {
1021 PayplugGateway::log(sprintf('Refund request error for the order %s : %s', $order_id, wc_clean($e->getMessage())), 'error');
1022
1023 return new \WP_Error('process_refund_error', __('The transaction could not be refunded. Please try again.', 'payplug'));
1024 }
1025 }
1026
1027 /**
1028 * Check the order amount to ensure it's on the allowed range.
1029 *
1030 * @param int $amount
1031 *
1032 * @return int|\WP_Error
1033 */
1034 public function validate_order_amount($amount)
1035 {
1036 if (
1037 $amount < PayplugWoocommerceHelper::get_minimum_amount()
1038 || $amount > PayplugWoocommerceHelper::get_maximum_amount()
1039 ) {
1040 return new \WP_Error(
1041 'invalid order amount',
1042 sprintf(__('Payments for this amount (%s) are not authorised with this payment gateway.', 'payplug'), \wc_price($amount / 100))
1043 );
1044 }
1045
1046 return $amount;
1047 }
1048
1049 /**
1050 * Limit string length.
1051 *
1052 * @param string $value
1053 * @param int $maxlength
1054 *
1055 * @return string
1056 */
1057 public function limit_length($value, $maxlength = 100)
1058 {
1059 return (strlen($value) > $maxlength) ? substr($value, 0, $maxlength) : $value;
1060 }
1061
1062 /**
1063 * Get user's keys.
1064 *
1065 * @param string $email
1066 * @param string $password
1067 *
1068 * @return array|\WP_Error
1069 */
1070 public function retrieve_user_api_keys($email, $password)
1071 {
1072 if (empty($email) || empty($password)) {
1073 return new \WP_Error('missing_login_data', __('Please fill all login fields', 'payplug'));
1074 }
1075
1076 try {
1077 $response = Authentication::getKeysByLogin($email, $password);
1078 if (empty($response) || !isset($response['httpResponse'])) {
1079 return new \WP_Error('invalid_credentials', __('Invalid credentials.', 'payplug'));
1080 }
1081
1082 return $response['httpResponse']['secret_keys'];
1083 } catch (HttpException $e) {
1084 return new \WP_Error('invalid_credentials', __('Invalid credentials.', 'payplug'));
1085 }
1086 }
1087
1088 /**
1089 * Get user merchant id.
1090 *
1091 * This method might be called during the login process before the global PayPlug
1092 * configuration is set. In that case you can pass a valid token to make the request.
1093 *
1094 * @param string|null $key
1095 *
1096 * @return string
1097 */
1098 public function retrieve_merchant_id($key = null)
1099 {
1100 try {
1101 $response = !is_null($key) ? Authentication::getAccount(new Payplug($key)) : Authentication::getAccount();
1102 $merchant_id = isset($response['httpResponse']['id']) ? $response['httpResponse']['id'] : '';
1103 } catch (ConfigurationException $e) {
1104 PayplugGateway::log(sprintf('Missing API key for PayPlug client : %s', wc_print_r($e->getMessage(), true)), 'error');
1105
1106 $merchant_id = '';
1107 } catch (HttpException $e) {
1108 PayplugGateway::log(sprintf('Account request error from PayPlug API : %s', wc_print_r($e->getErrorObject(), true)), 'error');
1109
1110 $merchant_id = '';
1111 } catch (\Exception $e) {
1112 PayplugGateway::log(sprintf('Account request error : %s', wc_clean($e->getMessage())), 'error');
1113
1114 $merchant_id = '';
1115 }
1116
1117 return $merchant_id;
1118 }
1119
1120 /**
1121 * Generate Hidden HTML.
1122 *
1123 * @param string $key
1124 * @param array $data
1125 *
1126 * @return string
1127 */
1128 public function generate_hidden_html($key, $data)
1129 {
1130 $field_key = $this->get_field_key($key);
1131 $defaults = array(
1132 'title' => '',
1133 'disabled' => false,
1134 'class' => '',
1135 'css' => '',
1136 'placeholder' => '',
1137 'type' => 'text',
1138 'desc_tip' => false,
1139 'description' => '',
1140 'custom_attributes' => array(),
1141 );
1142
1143 $data = wp_parse_args($data, $defaults);
1144
1145 ob_start();
1146 ?>
1147 <input type="<?php echo esc_attr($data['type']); ?>" name="<?php echo esc_attr($field_key); ?>" id="<?php echo esc_attr($field_key); ?>" value="<?php echo esc_attr($this->get_option($key)); ?>" />
1148 <?php
1149
1150 return ob_get_clean();
1151 }
1152
1153 /**
1154 * Generate Yes/No Input HTML.
1155 *
1156 * @param string $key
1157 * @param array $data
1158 *
1159 * @return string
1160 */
1161 public function generate_yes_no_html($key, $data)
1162 {
1163 $field_key = $this->get_field_key($key);
1164 $defaults = array(
1165 'title' => '',
1166 'no' => 'No',
1167 'yes' => 'Yes',
1168 'disabled' => false,
1169 'class' => '',
1170 'css' => '',
1171 'placeholder' => '',
1172 'type' => 'text',
1173 'desc_tip' => false,
1174 'description' => '',
1175 'custom_attributes' => [],
1176 'hide_label' => false,
1177 );
1178
1179 $data = wp_parse_args($data, $defaults);
1180 $checked = 'yes' === $this->get_option($key) ? '1' : '0';
1181
1182 ob_start();
1183 ?>
1184 <tr valign="top">
1185 <?php if (!$data['hide_label']) : ?>
1186 <th scope="row" class="titledesc">
1187 <label for="<?php echo esc_attr($field_key); ?>">
1188 <?php echo wp_kses_post($data['title']); ?>
1189 <?php echo $this->get_tooltip_html($data); ?>
1190 </label>
1191 </th>
1192 <?php endif; ?>
1193 <td class="forminp">
1194 <fieldset>
1195 <legend class="screen-reader-text"><span><?php echo wp_kses_post($data['title']); ?></span>
1196 </legend>
1197 <div class="radio--custom">
1198 <input class="radio radio-yes <?php echo esc_attr($data['class']); ?>" type="radio" name="<?php echo esc_attr($field_key); ?>" id="<?php echo esc_attr($field_key); ?>-yes" value="1" <?php checked('1', $checked); ?> <?php disabled($data['disabled'], true); ?> <?php echo $this->get_custom_attribute_html($data); ?>>
1199 <label for="<?php echo esc_attr($field_key); ?>-yes"><?php echo esc_html($data['yes']); ?></label>
1200 </div>
1201 <div class="radio--custom">
1202 <input class="radio radio-no <?php echo esc_attr($data['class']); ?>" type="radio" name="<?php echo esc_attr($field_key); ?>" id="<?php echo esc_attr($field_key); ?>-no" value="0" <?php checked('0', $checked); ?> <?php disabled($data['disabled'], true); ?> <?php echo $this->get_custom_attribute_html($data); ?>>
1203 <label for="<?php echo esc_attr($field_key); ?>-no"><?php echo esc_html($data['no']); ?></label>
1204 </div>
1205 <?php echo $this->get_description_html($data); ?>
1206 </fieldset>
1207 </td>
1208 </tr>
1209 <?php
1210
1211 return ob_get_clean();
1212 }
1213
1214 /**
1215 * Generate Radio Input HTML.
1216 *
1217 * @param string $key
1218 * @param array $data
1219 *
1220 * @return string
1221 */
1222 public function generate_radio_html($key, $data)
1223 {
1224 $field_key = $this->get_field_key($key);
1225 $defaults = array(
1226 'title' => '',
1227 'disabled' => false,
1228 'class' => '',
1229 'css' => '',
1230 'placeholder' => '',
1231 'type' => 'text',
1232 'desc_tip' => false,
1233 'description' => '',
1234 'custom_attributes' => [],
1235 'options' => [],
1236 );
1237
1238 $data = wp_parse_args($data, $defaults);
1239
1240 ob_start();
1241 ?>
1242 <tr valign="top">
1243 <th scope="row" class="titledesc">
1244 <label for="<?php echo esc_attr($field_key); ?>">
1245 <?php echo wp_kses_post($data['title']); ?>
1246 <?php echo $this->get_tooltip_html($data); ?>
1247 </label>
1248 </th>
1249 <td class="forminp">
1250 <fieldset>
1251 <legend class="screen-reader-text"><span><?php echo wp_kses_post($data['title']); ?></span>
1252 </legend>
1253 <?php foreach ($data['options'] as $option_key => $option_value) : ?>
1254 <input class="radio <?php echo esc_attr($data['class']); ?>" type="radio" name="<?php echo esc_attr($field_key); ?>" id="<?php echo esc_attr($field_key); ?>-<?php echo esc_attr($option_key); ?>" value="<?php echo esc_attr($option_key); ?>" <?php checked($option_key, $this->get_option($key)); ?> <?php disabled($data['disabled'], true); ?> <?php echo $this->get_custom_attribute_html($data); ?>>
1255 <label for="<?php echo esc_attr($field_key); ?>-<?php echo esc_attr($option_key); ?>"><?php echo esc_html($option_value); ?></label>
1256 <?php endforeach; ?>
1257 </fieldset>
1258 </td>
1259 </tr>
1260 <?php
1261
1262 return ob_get_clean();
1263 }
1264
1265 /**
1266 * Generate Login HTML.
1267 *
1268 * @param string $key
1269 * @param array $data
1270 *
1271 * @return string
1272 */
1273 public function generate_login_html($key, $data)
1274 {
1275 $field_key = $this->get_field_key($key);
1276 $defaults = [];
1277
1278 $data = wp_parse_args($data, $defaults);
1279
1280 ob_start();
1281 ?>
1282 <tr valign="top">
1283 <td class="forminp">
1284 <p><?php echo $this->get_option('email'); ?></p>
1285 <p>
1286 <input type="submit" name="submit_logout" value="<?php _e('Logout', 'payplug'); ?>">
1287 <input type="hidden" name="save" value="logout">
1288 <?php wp_nonce_field('payplug_user_logout', '_logoutaction'); ?>
1289 |
1290 <a href="https://portal.payplug.com" target="_blank"><?php _e('Go to your PayPlug Portal', 'payplug'); ?></a>
1291 </p>
1292 </td>
1293 </tr>
1294 <?php
1295
1296 return ob_get_clean();
1297 }
1298
1299 /**
1300 * Validate Radio Field.
1301 *
1302 * Make sure the data is escaped correctly, etc.
1303 *
1304 * @param string $key
1305 * @param string|null $value Posted Value
1306 *
1307 * @return string
1308 */
1309 public function validate_radio_field($key, $value)
1310 {
1311 $value = is_null($value) ? '' : $value;
1312
1313 return wc_clean(stripslashes($value));
1314 }
1315
1316 /**
1317 * Validate Yes/No Field.
1318 *
1319 * @param string $key
1320 * @param string $value Posted Value
1321 *
1322 * @return string
1323 */
1324 public function validate_yes_no_field($key, $value)
1325 {
1326 return ('1' === (string) $value) ? 'yes' : 'no';
1327 }
1328
1329 /**
1330 * Get PayPlug gateway mode.
1331 *
1332 * @return string
1333 */
1334 public function get_current_mode()
1335 {
1336 return ('yes' === $this->get_option('mode')) ? 'live' : 'test';
1337 }
1338
1339 /**
1340 * Get user API key.
1341 *
1342 * @param string $mode
1343 *
1344 * @return string
1345 */
1346 public function get_api_key($mode = 'test')
1347 {
1348
1349 switch ($mode) {
1350 case 'test':
1351 $key = $this->get_option('payplug_test_key');
1352 break;
1353 case 'live':
1354 $key = $this->get_option('payplug_live_key');
1355 break;
1356 default:
1357 $key = '';
1358 break;
1359 }
1360
1361 return $key;
1362 }
1363
1364 /**
1365 * Check if an api key exist for a mode.
1366 *
1367 * @param string $mode
1368 *
1369 * @return bool
1370 */
1371 public function has_api_key($mode = 'test')
1372 {
1373 $key = $this->get_api_key($mode);
1374 $key = trim($key);
1375
1376 return !empty($key);
1377 }
1378
1379 /**
1380 * Get current merchant id.
1381 *
1382 * @return string
1383 */
1384 public function get_merchant_id()
1385 {
1386 return $this->get_option('payplug_merchant_id', '');
1387 }
1388
1389 /**
1390 * Check if user is logged in and we have an API key for TEST mode.
1391 *
1392 * @return bool
1393 */
1394 public function user_logged_in()
1395 {
1396 return !empty($this->get_option('payplug_test_key'));
1397 }
1398
1399 /**
1400 * Check if oneclick payment is activated and merchant can use it.
1401 *
1402 * @return bool
1403 */
1404 public function oneclick_available()
1405 {
1406 return $this->user_logged_in()
1407 && $this->oneclick
1408 && $this->permissions->has_permissions(PayplugPermissions::SAVE_CARD);
1409 }
1410
1411 /**
1412 * Check if the gatteway is allowed for the order amount
1413 *
1414 * @param array
1415 * @return array
1416 */
1417 public function check_gateway($gateways)
1418 {
1419 if (isset($gateways[$this->id]) && $gateways[$this->id]->id == $this->id) {
1420 $order_amount = $this->get_order_total();
1421 if ($order_amount < self::MIN_AMOUNT || $order_amount > self::MAX_AMOUNT) {
1422 unset($gateways[$this->id]);
1423 }
1424 }
1425 return $gateways;
1426 }
1427
1428 /**
1429 * Can the order be refunded via this gateway?
1430 *
1431 *
1432 * @param WC_Order $order Order object.
1433 * @return bool If false, the automatic refund button is hidden in the UI.
1434 */
1435 public function can_refund_order($order)
1436 {
1437 return $order && $this->supports('refunds') && $order->get_status() !== "cancelled";
1438 }
1439 }
1440