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

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

1,904 lines 69.3 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\Exception\ForbiddenException;
14 use Payplug\Payplug;
15 use Payplug\PayplugWoocommerce\Admin\Ajax;
16 use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
17 use Payplug\Resource\Payment as PaymentResource;
18 use Payplug\Resource\Refund as RefundResource;
19 use WC_Payment_Gateway_CC;
20 use WC_Payment_Tokens;
21
22 /**
23 * PayPlug WooCommerce Gateway.
24 *
25 * @package Payplug\PayplugWoocommerce\Gateway
26 */
27 class PayplugGateway extends WC_Payment_Gateway_CC
28 {
29
30 /**
31 * @var PayplugGatewayRequirements
32 */
33 private $requirements;
34
35 /**
36 * @var PayplugPermissions
37 */
38 private $permissions;
39
40 /**
41 * @var PayplugResponse
42 */
43 public $response;
44
45 /**
46 * @var PayplugApi
47 */
48 public $api;
49
50 /**
51 * @var \WC_Logger
52 */
53 protected static $log;
54
55 /**
56 * @var bool
57 */
58 protected static $log_enabled;
59
60 /**
61 * @var float
62 */
63 const MIN_AMOUNT = 0.99;
64
65 /**
66 * @var float
67 */
68 const MAX_AMOUNT = 20000;
69
70 /**
71 * @var string
72 */
73 private $payplug_merchant_country = 'FR';
74
75 protected $oney_response;
76 protected $min_oney_price, $oney_thresholds_min;
77 protected $max_oney_price, $oney_thresholds_max;
78
79 /**
80 * Logging method.
81 *
82 * @param string $message Log message.
83 * @param string $level Optional. Default 'info'.
84 * emergency|alert|critical|error|warning|notice|info|debug
85 */
86 public static function log($message, $level = 'info')
87 {
88 if (!self::$log_enabled) {
89 return;
90 }
91
92 if (empty(self::$log)) {
93 self::$log = PayplugWoocommerceHelper::is_pre_30() ? new \WC_Logger() : wc_get_logger();
94 }
95
96 PayplugWoocommerceHelper::is_pre_30()
97 ? self::$log->add('payplug_gateway', $message)
98 : self::$log->log($level, $message, array('source' => 'payplug_gateway'));
99 }
100
101 /**
102 * Construct method
103 *
104 * @return void
105 */
106 public function __construct()
107 {
108 $this->id = 'payplug';
109 $this->icon = '';
110 $this->has_fields = false;
111 $this->method_title = _x('PayPlug', 'Gateway method title', 'payplug');
112 $this->method_description = __('Enable PayPlug for your customers.', 'payplug');
113 $this->supports = array(
114 'products',
115 'refunds',
116 'tokenization',
117 );
118 $this->new_method_label = __('Pay with another credit card', 'payplug');
119
120 $this->init_settings();
121 $this->requirements = new PayplugGatewayRequirements($this);
122 if ($this->user_logged_in()) {
123 $this->init_payplug();
124 }else{
125 delete_option('woocommerce_payplug_settings');
126 set_transient( PayplugWoocommerceHelper::get_transient_key(get_option('woocommerce_payplug_settings', [])), null );
127 }
128
129 $this->title = $this->get_option('title');
130 $this->description = $this->get_option('description');
131 $this->mode = 'yes' === $this->get_option('mode', 'no') ? 'live' : 'test';
132 $this->debug = 'yes' === $this->get_option('debug', 'no');
133 $this->email = $this->get_option('email');
134 $this->payment_method = $this->get_option('payment_method');
135 $this->oneclick = 'yes' === $this->get_option('oneclick', 'no');
136 $this->oney_type = $this->get_option('oney_type', 'with_fees');
137 $oney_range = PayplugWoocommerceHelper::get_min_max_oney();
138 $this->min_oney_price = (isset($oney_range['min'])) ? intval($oney_range['min']) : 100;
139 $this->max_oney_price = (isset($oney_range['max'])) ? intval($oney_range['max']) : 3000;
140 $this->oney_thresholds_min = $this->get_option('oney_thresholds_min', $this->min_oney_price );
141 $this->oney_thresholds_max = $this->get_option('oney_thresholds_max', $this->max_oney_price );
142 $this->init_form_fields();
143 $this->payplug_merchant_country = PayplugWoocommerceHelper::get_payplug_merchant_country();
144 $this->oney_product_animation = $this->get_option('oney_product_animation');
145
146 add_filter('woocommerce_get_customer_payment_tokens', [$this, 'filter_tokens'], 10, 3);
147
148 self::$log_enabled = $this->debug;
149
150 // Ensure the description is not empty to correctly display users's save cards
151 if (empty($this->description) && 0 !== count($this->get_tokens())) {
152 $this->description = ' ';
153 }
154
155 if ('test' === $this->mode) {
156 $this->description .= " \n";
157
158 $this->description .= __('You are in TEST MODE. In test mode you can use the card 4242424242424242 with any valid expiration date and CVC.', 'payplug');
159 $this->description = trim($this->description);
160 }
161
162 add_filter('woocommerce_get_order_item_totals', [$this, 'customize_gateway_title'], 10, 2);
163 add_action('wp_enqueue_scripts', [$this, 'scripts']);
164 add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']);
165 add_action('the_post', [$this, 'validate_payment']);
166 add_action('woocommerce_available_payment_gateways', [$this, 'check_gateway']);
167 }
168
169 /**
170 * Customize gateway title in emails.
171 *
172 * @param array $total_rows
173 * @param \WC_Order $order
174 *
175 * @return array
176 *
177 * @author Clément Boirie
178 */
179 public function customize_gateway_title($total_rows, $order)
180 {
181
182 $get_payment_method = $this->id;
183 if( method_exists($order, "get_payment_method") ) {
184 $get_payment_method = $order->get_payment_method();
185 }
186
187 $payment_method = PayplugWoocommerceHelper::is_pre_30() ? $order->payment_method : $get_payment_method;
188 if (
189 $this->id !== $payment_method
190 || !isset($total_rows['payment_method'])
191 ) {
192 return $total_rows;
193 }
194
195 $total_rows['payment_method']['value'] = __('Credit card', 'payplug');
196
197 return $total_rows;
198 }
199
200 /**
201 * Validate order payment when the user is redirected to the success confirmation page.
202 *
203 * @throws \WC_Data_Exception
204 */
205 public function validate_payment()
206 {
207 if (!is_wc_endpoint_url('order-received') || empty($_GET['key'])) {
208 return;
209 }
210
211 $order_id = wc_get_order_id_by_order_key(wc_clean($_GET['key']));
212 if (empty($order_id)) {
213 return;
214 }
215
216 $order = wc_get_order($order_id);
217 if (!$order instanceof \WC_Order) {
218 return;
219 }
220
221 $payment_method = PayplugWoocommerceHelper::is_pre_30() ? $order->payment_method : $order->get_payment_method();
222 if (!in_array($payment_method, ['payplug', 'oney_x3_with_fees', 'oney_x4_with_fees', 'oney_x3_without_fees', 'oney_x4_without_fees','bancontact', 'apple_pay', 'american_express'])) {
223 return;
224 }
225
226
227 $transaction_id = PayplugWoocommerceHelper::is_pre_30() ? get_post_meta($order_id, '_transaction_id', true) : $order->get_transaction_id();
228 if (empty($transaction_id)) {
229 PayplugGateway::log(sprintf('Order #%s : Missing transaction id.', $order_id), 'error');
230
231 return;
232 }
233
234 try {
235 $payment = $this->api->payment_retrieve($transaction_id);
236 } catch (\Exception $e) {
237 PayplugGateway::log(
238 sprintf(
239 'Order #%s : An error occurred while retrieving the payment data with the message : %s',
240 $order_id,
241 $e->getMessage()
242 )
243 );
244
245 return;
246 }
247
248 //FIXME:: this is being runned 1 time for each gateway,
249 // this comparisson is only needed to only run the process_method one time
250 if($payment_method != $this->id){
251 return;
252 }
253
254 $this->response->process_payment($payment);
255 }
256
257 /**
258 * Get payment icons.
259 *
260 * @return string
261 */
262 public function get_icon()
263 {
264
265 $src = ('it_IT' === get_locale())
266 ? PAYPLUG_GATEWAY_PLUGIN_URL . '/assets/images/logos_scheme_PostePay.svg'
267 : PAYPLUG_GATEWAY_PLUGIN_URL . '/assets/images/logos_scheme_CB.svg';
268
269 $icons = apply_filters('payplug_payment_icons', [
270 'payplug' => sprintf('<img src="%s" alt="Visa & Mastercard" class="payplug-payment-icon" />', esc_url($src)),
271 ]);
272
273 $icons_str = '';
274 foreach ($icons as $icon) {
275 $icons_str .= $icon;
276 }
277
278 return $icons_str;
279 }
280
281 /**
282 * Check if this gateway is enabled
283 */
284 public function is_available()
285 {
286 if ('yes' === $this->enabled) {
287 return $this->requirements->satisfy_requirements() && !empty($this->get_api_key($this->get_current_mode()));
288 }
289
290 return parent::is_available();
291 }
292
293 /**
294 * Load gateway settings.
295 */
296 public function init_settings()
297 {
298 parent::init_settings();
299 $this->enabled = !empty($this->settings['enabled']) && 'yes' === $this->settings['enabled'] ? 'yes' : 'no';
300 }
301
302 /**
303 * Register gateway settings.
304 */
305 public function init_form_fields()
306 {
307 $anchor = esc_html_x( __("More informations", 'payplug'), 'modal', 'payplug' );
308 $domain = __( 'support.payplug.com/hc/fr/articles/4408142346002', 'payplug' );
309 $link = sprintf( ' <a href="https://%s" target="_blank">%s</a>', $domain, $anchor );
310
311
312 $anchor_bancontact = esc_html_x( __("payplug_bancontact_activation_request", 'payplug'), 'modal', 'payplug' );
313 $domain_bancontact = __( 'payplug_bancontact_activation_url', 'payplug' );
314 $bancontact_call_to_action = sprintf( ' <a id="bancontact_call_to_action" href="https://%s" target="_blank">%s</a>', $domain_bancontact, $anchor_bancontact );
315
316 $fields = [
317 'enabled' => [
318 'title' => __('Enable/Disable', 'payplug'),
319 'type' => 'checkbox',
320 'label' => __('Enable PayPlug', 'payplug'),
321 'description' => __('Only Euro payments can be processed with PayPlug.', 'payplug'),
322 'default' => 'no',
323 ],
324 'title' => [
325 'title' => __('Title', 'payplug'),
326 'type' => 'text',
327 'description' => __('The payment solution title displayed to your customers during checkout', 'payplug'),
328 'default' => _x('Credit card checkout', 'Default gateway title', 'payplug'),
329 'desc_tip' => false,
330 ],
331 'description' => [
332 'title' => __('Description', 'payplug'),
333 'type' => 'text',
334 'description' => __('The payment solution description displayed to your customers during checkout', 'payplug'),
335 'default' => '',
336 'desc_tip' => false,
337 ],
338 'title_connexion' => [
339 'title' => __('Connection', 'payplug'),
340 'type' => 'title',
341 ],
342 'email' => [
343 'type' => 'hidden',
344 'default' => '',
345 ],
346 'login' => [
347 'type' => 'login',
348 'default' => '',
349 ],
350 'payplug_test_key' => [
351 'type' => 'hidden',
352 'default' => '',
353 ],
354 'payplug_live_key' => [
355 'type' => 'hidden',
356 'default' => '',
357 ],
358 'payplug_merchant_id' => [
359 'type' => 'hidden',
360 'default' => '',
361 ],
362 'title_testmode' => [
363 'title' => __('Mode', 'payplug'),
364 'type' => 'title',
365 ],
366 'mode' => [
367 'title' => '',
368 'label' => '',
369 'type' => 'yes_no',
370 'yes' => 'Live',
371 'no' => 'Test',
372 'description' => __('In TEST mode, all payments will be simulations and will not generate real transactions.', 'payplug'),
373 'default' => 'no',
374 'hide_label' => true,
375 ],
376 'title_settings' => [
377 'title' => __('Settings', 'payplug'),
378 'type' => 'title',
379 ],
380 'payment_method' => [
381 'title' => __('Payment page', 'payplug'),
382 'type' => 'radio',
383 'options' => array(
384 'redirect' => __('Redirect', 'payplug'),
385 'embedded' => __('Integrated', 'payplug'),
386 ),
387 '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'),
388 'default' => 'redirect',
389 'desc_tip' => false
390 ],
391 'debug' => [
392 'title' => __('Debug', 'payplug'),
393 'type' => 'checkbox',
394 'description' => __('Debug mode saves additional information on your server for each operation done via the PayPlug plugin (Developer setting).', 'payplug'),
395 'label' => __('Activate debug mode', 'payplug'),
396 'default' => 'yes',
397 'desc_tip' => false
398 ],
399 'title_advanced_settings' => [
400 'title' => __('Advanced Settings', 'payplug'),
401 'description' => __(
402 '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>',
403 'payplug'
404 ),
405 'type' => 'title',
406 ],
407 'oneclick' => [
408 'title' => __('One Click Payment', 'payplug'),
409 'type' => 'checkbox',
410 'label' => __('Activate', 'payplug'),
411 'description' => __('Allow your customers to save their credit card information for later purchases.', 'payplug'),
412 'default' => 'no',
413 'desc_tip' => false
414 ],
415 'bancontact' => [
416 'title' => __('payplug_bancontact_activate_title', 'payplug'),
417 'type' => 'checkbox',
418 'label' => __('Activate', 'payplug'),
419 'description' => '<p class="description" id="bancontact_test_mode_description"> '. __('payplug_bancontact_testmode_description', 'payplug') .' </p>' .
420 '<p class="description" id="bancontact_live_mode_description_disabled"> '. __('payplug_bancontact_livemode_description_disabled', 'payplug') .' </p>' .
421 $bancontact_call_to_action,
422 'default' => 'no',
423 ],
424 'apple_pay' => [
425 'title' => __('payplug_apple_pay_activate_title', 'payplug'),
426 'type' => 'checkbox',
427 'label' => __('Activate', 'payplug'),
428 'description' => '<p class="description" id="apple_pay_test_mode_description"> '. __('payplug_apple_pay_testmode_description', 'payplug') .' </p>' .
429 '<p class="description" id="apple_pay_live_mode_description"> '. __('payplug_apple_pay_livemode_description', 'payplug') .' </p>' ,
430 'default' => 'no',
431 ],
432 'american_express' => [
433 'title' => __('payplug_amex_title', 'payplug'),
434 'type' => 'checkbox',
435 'label' => __('payplug_amex_activate', 'payplug'),
436 'description' => '<p class="description" id="amex_test_mode_description"> '. __('payplug_amex_testmode_description', 'payplug') .' </p>' .
437 '<p class="description" id="amex_live_mode_description"> '. __('payplug_amex_livemode_description', 'payplug') .' </p>' ,
438 'default' => 'no',
439 ],
440 'oney' => [
441 'title' => __('3x 4x Oney payments', 'payplug'),
442 'type' => 'checkbox',
443 'label' => __('Activate', 'payplug'),
444 // TRAD
445 'description' => sprintf(__('Allow your customers to split payments into 3 or 4 installments, for orders between %s€ and %s€', 'payplug'), $this->min_oney_price, $this->max_oney_price) . $link,
446 'default' => 'no',
447 'desc_tip' => false
448 ],
449 'oney_type' => [
450 'title' => '',
451 'type' => 'oney_type',
452 'options' => array(
453 'with_fees' => __('Oney with fees', 'payplug'),
454 'without_fees' => __('Oney without fees', 'payplug'),
455 ),
456 'descriptions' => array(
457 'with_fees' => __('The fees are split between you and your customers', 'payplug'),
458 'without_fees' => __('You pay the fees', 'payplug'),
459 ),
460 'description' => '',
461 'default' => 'with_fees',
462 'desc_tip' => false
463 ],
464 'oney_thresholds' => [
465 'title' => '',
466 'type' => 'oney_thresholds',
467 'description' => sprintf(__('I would like to offer guaranteed payment in installments for amounts between %s€ and %s€.', 'payplug'),
468 '<b class="min">' . $this->oney_thresholds_min . '</b>', '<b class="max">' . $this->oney_thresholds_max . '</b>'),
469 'desc_tip' => false
470 ],
471 'oney_thresholds_min' => [
472 'title' => '',
473 'type' => 'hidden',
474 'label' => '',
475 'description' => '',
476 'default' => 'no',
477 ],
478 'oney_thresholds_max' => [
479 'title' => '',
480 'type' => 'hidden',
481 'label' => '',
482 'description' => '',
483 'default' => 'no',
484 ],
485 'oney_product_animation' => [
486 'title' => __('oney_installments_pop_up', 'payplug'),
487 'description' => __('display_the_oney_installments_pop_up_on_the_product_page', 'payplug'),
488 'label' => __('Activate', 'payplug'),
489 'default' => 'no',
490 'desc_tip' => false,
491 'type' => 'oney_product_animation'
492 ],
493 ];
494
495 if ($this->user_logged_in()) {
496 if ($this->permissions->has_permissions(PayplugPermissions::SAVE_CARD)) {
497 unset($fields['title_advanced_settings']);
498 } else if ('live' === $this->get_current_mode()){
499 $fields['oneclick']['disabled'] = true;
500 }
501 }
502
503 /**
504 * Filter PayPlug gateway settings.
505 *
506 * @param array $fields
507 */
508 $fields = apply_filters('payplug_gateway_settings', $fields);
509 $this->form_fields = $fields;
510 }
511
512 /**
513 * Set global configuration for PayPlug instance.
514 */
515 public function init_payplug()
516 {
517 $this->api = new PayplugApi($this);
518 $this->api->init();
519
520 $this->permissions = new PayplugPermissions($this);
521 $this->response = new PayplugResponse($this);
522
523 // Register IPN handler
524 new PayplugIpnResponse($this);
525
526 }
527
528 /**
529 * Embedded payment form scripts.
530 *
531 * Register scripts and additionnal data needed for the
532 * embedded payment form.
533 */
534 public function scripts()
535 {
536 if (!is_cart() && !is_checkout() && !isset($_GET['pay_for_order']) && !is_add_payment_method_page() && !isset($_GET['change_payment_method'])) {
537 return;
538 }
539
540 // If PayPlug is not enabled bail.
541 if ('no' === $this->enabled) {
542 return;
543 }
544
545 // If keys are not set bail.
546 if (empty($this->get_api_key($this->mode))) {
547 PayplugGateway::log('Keys are not set correctly.');
548
549 return;
550 }
551
552 // Register checkout styles.
553 wp_register_style('payplug-checkout', PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/css/payplug-checkout.css', [], PAYPLUG_GATEWAY_VERSION);
554 wp_enqueue_style('payplug-checkout');
555
556 wp_register_script('payplug', 'https://api.payplug.com/js/1/form.latest.js', [], null, true);
557 wp_register_script('payplug-checkout', PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/js/payplug-checkout.js', [
558 'jquery',
559 'payplug'
560 ], PAYPLUG_GATEWAY_VERSION, true);
561 wp_localize_script('payplug-checkout', 'payplug_checkout_params', [
562 'ajax_url' => \WC_AJAX::get_endpoint('payplug_create_order'),
563 'nonce' => [
564 'checkout' => wp_create_nonce('woocommerce-process_checkout'),
565 ],
566 'is_embedded' => 'redirect' !== $this->payment_method
567 ]);
568 wp_enqueue_script('payplug-checkout');
569 }
570
571 /**
572 * Filter saved tokens for the gateway.
573 *
574 * A token will be removed if :
575 * - it doesn't match the current merchant logged in,
576 * - or it doesn't match the current gateway mode,
577 * - or it is expired.
578 *
579 * @param array $tokens
580 * @param int $user_id
581 * @param string $gateway_id
582 *
583 * @return array
584 */
585 public function filter_tokens($tokens, $user_id, $gateway_id)
586 {
587
588 if (!is_user_logged_in() || !class_exists('WC_Payment_Gateway_CC')) {
589 return $tokens;
590 }
591
592 /* @var \WC_Payment_Token_CC $token */
593 foreach ($tokens as $k => $token) {
594
595 if ($this->id !== $token->get_gateway_id()) {
596 continue;
597 }
598
599 // check if token is associated with a merchant id and if it match the current one
600 $token_merchant_id = $token->get_meta('payplug_account', true);
601 if (empty($token_merchant_id) || $this->get_merchant_id() !== $token_merchant_id) {
602 unset($tokens[$k]);
603 continue;
604 }
605
606 // check if token is available for the current gateway mode
607 if ($this->mode !== $token->get_meta('mode', true)) {
608 unset($tokens[$k]);
609 continue;
610 }
611
612 // check if token is not expired
613 $current_month = \absint(date('n'));
614 $current_year = \absint(date('Y'));
615 if ($current_year > (int) $token->get_expiry_year()) {
616 unset($tokens[$k]);
617 continue;
618 }
619
620 if ($current_year === (int) $token->get_expiry_year() && $current_month > (int) $token->get_expiry_month()) {
621 unset($tokens[$k]);
622 continue;
623 }
624 }
625
626 return $tokens;
627 }
628
629 public function payment_fields()
630 {
631 $description = $this->get_description();
632 if (!empty($description)) {
633 echo wpautop(wptexturize($description));
634 }
635
636 if ($this->oneclick_available()) {
637 $this->tokenization_script();
638 $this->saved_payment_methods();
639 }
640 }
641
642 /**
643 * Handle admin display.
644 */
645 public function admin_options()
646 {
647 wp_enqueue_style(
648 'payplug-gateway-style',
649 PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/css/app.css',
650 [],
651 PAYPLUG_GATEWAY_VERSION
652 );
653
654 wp_enqueue_script(
655 'payplug-gateway-admin',
656 PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/js/payplug-admin.js',
657 ['jquery-ui-dialog'],
658 PAYPLUG_GATEWAY_VERSION
659 );
660
661 wp_enqueue_script(
662 'payplug-gateway-admin-bancontact',
663 PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/js/payplug-admin-bancontact.js',
664 ['jquery-ui-dialog'],
665 PAYPLUG_GATEWAY_VERSION
666 );
667
668 wp_enqueue_script(
669 'payplug-gateway-admin-applepay',
670 PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/js/payplug-admin-applepay.js',
671 ['jquery-ui-dialog'],
672 PAYPLUG_GATEWAY_VERSION
673 );
674
675 wp_enqueue_script(
676 'payplug-gateway-admin-amex',
677 PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/js/payplug-admin-amex.js',
678 [],
679 PAYPLUG_GATEWAY_VERSION
680 );
681
682 wp_localize_script('payplug-gateway-admin-bancontact', 'payplug_admin_config', array(
683 'ajax_url' => admin_url('admin-ajax.php'),
684 'has_live_key' => (false === $this->has_api_key('live')) ? false : true,
685 'btn_ok' => _x('Ok', 'modal', 'payplug'),
686 'btn_label' => _x('Cancel', 'modal', 'payplug'),
687 'general_error' => _x('Something went wrong. Please refresh the page and retry.', 'modal', 'payplug'),
688 ));
689
690 wp_localize_script('payplug-gateway-admin', 'payplug_admin_config', array(
691 'ajax_url' => admin_url('admin-ajax.php'),
692 'has_live_key' => (false === $this->has_api_key('live')) ? false : true,
693 'btn_ok' => _x('Ok', 'modal', 'payplug'),
694 'btn_label' => _x('Cancel', 'modal', 'payplug'),
695 'general_error' => _x('Something went wrong. Please refresh the page and retry.', 'modal', 'payplug'),
696 ));
697
698 wp_enqueue_script(
699 'payplug-gateway-admin-oney',
700 PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/js/payplug-admin-oney.js',
701 ['jquery-ui-dialog'],
702 PAYPLUG_GATEWAY_VERSION
703 );
704
705 wp_localize_script('payplug-gateway-admin-oney', 'payplug_admin_config', array(
706 'ajax_url' => admin_url('admin-ajax.php'),
707 'btn_ok' => _x('Ok', 'modal', 'payplug'),
708 'has_live_key' => (false === $this->has_api_key('live')) ? false : true,
709 'min_oney_price' => $this->min_oney_price,
710 'max_oney_price' => $this->max_oney_price,
711 'oney_thresholds_min' =>$this->oney_thresholds_min,
712 'oney_thresholds_max' => $this->oney_thresholds_max,
713 ));
714
715 if ($this->user_logged_in() && false === $this->has_api_key('live')) {
716 add_action('admin_footer', function () {
717 $email = $this->get_option('email');
718 ?>
719 <div id="payplug-refresh-keys-modal" title="<?php echo esc_attr_x('Mode LIVE', 'modal', 'payplug'); ?>">
720 <form id="payplug-refresh-keys-modal__form">
721 <p id="dialog-msg"></p>
722 <p><?php echo esc_html_x('Please enter your PayPlug account password', 'modal', 'payplug'); ?></p>
723 <input type="password" name="password" required title="<?php echo esc_attr_x('Enter your PayPlug account password', 'modal', 'payplug'); ?>" />
724 <input type="hidden" name="email" value="<?php echo esc_attr($email); ?>">
725 <input type="hidden" name="action" value="<?php echo esc_attr(Ajax::REFRESH_KEY_ACTION); ?>">
726 <?php wp_nonce_field(sprintf('%s_%s', $email, Ajax::REFRESH_KEY_ACTION)); ?>
727 <input class="ui-dialog-sronly" type="submit" tabindex="-1">
728 </form>
729 </div>
730 <?php
731 });
732 }
733
734 $payplug_requirements = new PayplugGatewayRequirements($this); ?>
735
736 <h2 class="title--logo"><?php esc_html($this->get_method_title()) ?></h2>
737 <p><?php _e(sprintf('Version %s', PAYPLUG_GATEWAY_VERSION)); ?></p>
738 <div class="payplug-requirements">
739 <?php echo $payplug_requirements->curl_requirement(); ?>
740 <?php echo $payplug_requirements->php_requirement(); ?>
741 <?php echo $payplug_requirements->openssl_requirement(); ?>
742 <?php echo $payplug_requirements->account_requirement(); ?>
743 <?php echo $payplug_requirements->currency_requirement(); ?>
744 <?php echo $payplug_requirements->oney_requirement(); ?>
745 </div>
746 <?php echo wp_kses_post(wpautop($this->get_method_description())); ?>
747
748 <?php if ($this->user_logged_in()) : ?>
749 <table class="form-table">
750 <?php $this->generate_settings_html($this->get_form_fields()); ?>
751 </table>
752 <?php else :
753 $GLOBALS['hide_save_button'] = true; ?>
754 <h3 class="wc-settings-sub-title"><?php _e('Connection', 'payplug'); ?></h3>
755 <table class="form-table">
756 <tbody>
757 <tr valign="top">
758 <th scope="row" class="titledesc">
759 <label for="payplug_email"><?php _e('Email', 'payplug'); ?></label>
760 </th>
761 <td class="forminp">
762 <fieldset>
763 <legend class="screen-reader-text"><span><?php _e('Email', 'payplug'); ?></span></legend>
764 <input class="input-text regular-input" type="text" name="payplug_email" id="payplug_email" value="" placeholder="<?php _e('your@email.com', 'payplug'); ?>" />
765 </fieldset>
766 </td>
767 </tr>
768 <tr valign="top">
769 <th scope="row" class="titledesc">
770 <label for="payplug_password"><?php _e('Password', 'payplug'); ?></label>
771 </th>
772 <td class="forminp">
773 <fieldset>
774 <legend class="screen-reader-text"><span><?php _e('Password', 'payplug'); ?></span>
775 </legend>
776 <input class="input-text regular-input" type="password" name="payplug_password" id="payplug_password" value="" />
777 </fieldset>
778 </td>
779 </tr>
780 <tr valign="top">
781 <td class="forminp">
782 <input id="payplug-login" class="button" type="submit" value="<?php _e('Login', 'payplug'); ?>">
783 <input type="hidden" name="save" value="login">
784 <?php wp_nonce_field('payplug_user_login', '_loginaction'); ?>
785 </td>
786 </tr>
787 </tbody>
788 </table>
789 <?php
790 endif;
791 ?>
792 <div id="payplug-oney-modal" title="<?php echo esc_attr_x('Mode LIVE', 'modal', 'payplug'); ?>">
793 <p>
794 <?php echo esc_html_x('Attention, pour utiliser la méthode de paiement Oney en mode LIVE merci de nous contacter à', 'modal', 'payplug'); ?>
795 <br/>
796 <a href="mailto:support@payplug.com">support@payplug.com</a>
797 </p>
798 </div>
799 <?php
800 }
801
802 /**
803 * Process admin options.
804 *
805 * @return bool
806 */
807 public function process_admin_options()
808 {
809 $data = $this->get_post_data();
810 $oneclick_fieldkey = $this->get_field_key('oneclick');
811
812 // Handle logout process
813 if (
814 isset($data['submit_logout'])
815 && false !== check_admin_referer('payplug_user_logout', '_logoutaction')
816 ) {
817
818 if ($this->permissions) {
819 $this->permissions->clear_permissions();
820 }
821
822 $data = get_option($this->get_option_key());
823 $data['payplug_test_key'] = '';
824 $data['payplug_live_key'] = '';
825 $data['payplug_merchant_id'] = '';
826 $data['enabled'] = 'no';
827 $data['mode'] = 'no';
828 $data['oneclick'] = 'no';
829 update_option(
830 $this->get_option_key(),
831 apply_filters('woocommerce_settings_api_sanitized_fields_' . $this->id, $data)
832 );
833 if("payplug" === $this->id) {
834 \WC_Admin_Settings::add_message(__('Successfully logged out.', 'payplug'));
835 }
836
837 return true;
838 }
839
840 // Handle login process
841 if (
842 isset($data['payplug_email'])
843 && false !== check_admin_referer('payplug_user_login', '_loginaction')
844 ) {
845 $email = $data['payplug_email'];
846 $password = wp_unslash($data['payplug_password']);
847 $response = $this->retrieve_user_api_keys($email, $password);
848 if (is_wp_error($response)) {
849 \WC_Admin_Settings::add_error($response->get_error_message());
850
851 return false;
852 }
853
854 // try to use the api keys to retrieve the merchant id
855 $merchant_id = isset($response['test']) ? $this->retrieve_merchant_id($response['test']) : '';
856
857 $this->init_form_fields();
858 $fields = $this->get_form_fields();
859 $data = [];
860
861 // Load existing values if the user is re-login.
862 foreach ($fields as $key => $field) {
863 if (in_array($field['type'], ['title', 'login'])) {
864 continue;
865 }
866
867 switch ($key) {
868 case 'enabled':
869 $val = 'yes';
870 break;
871 case 'mode':
872 $val = 'no';
873 break;
874 case 'payplug_test_key':
875 $val = !empty($response['test']) ? esc_attr($response['test']) : null;
876 break;
877 case 'payplug_live_key':
878 $val = !empty($response['live']) ? esc_attr($response['live']) : null;
879 break;
880 case 'payplug_merchant_id':
881 $val = esc_attr($merchant_id);
882 break;
883 case 'email':
884 $val = esc_html($email);
885 break;
886 default:
887 $val = $this->get_option($key);
888 }
889
890 $data[$key] = $val;
891 }
892
893 $this->set_post_data($data);
894 update_option(
895 $this->get_option_key(),
896 apply_filters('woocommerce_settings_api_sanitized_fields_' . $this->id, $data)
897 );
898 if("payplug" === $this->id) {
899 \WC_Admin_Settings::add_message(__('Successfully logged in.', 'payplug'));
900 }
901
902 return true;
903 }
904
905 // Don't let user without live key leave TEST mode.
906 $mode_fieldkey = $this->get_field_key('mode');
907 $live_key_fieldkey = $this->get_field_key('payplug_live_key');
908 if (isset($data[$mode_fieldkey]) && '1' === $data[$mode_fieldkey] && empty($data[$live_key_fieldkey])) {
909 $data[$mode_fieldkey] = null;
910 $this->set_post_data($data);
911 \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'));
912 }
913
914 // Check user permissions before activating one-click feature.
915 $oneclick_fieldkey = $this->get_field_key('oneclick');
916 if (
917 isset($data[$oneclick_fieldkey])
918 && '1' === $data[$oneclick_fieldkey]
919 && '1' === $data[$mode_fieldkey]
920 && (!$this->user_logged_in()
921 || false === $this->permissions->has_permissions(PayplugPermissions::SAVE_CARD))
922 ) {
923 $data[$oneclick_fieldkey] = null;
924 \WC_Admin_Settings::add_error(__('Only PREMIUM accounts can enable the One Click option in LIVE mode.', 'payplug'));
925 }
926
927 // Force getAccount to set transient data on live mode
928 if (
929 $mode_fieldkey === "woocommerce_payplug_mode" &&
930 "1" === $data[$mode_fieldkey] &&
931 !empty($data[$live_key_fieldkey])
932 ) {
933 try{
934 $response = Authentication::getAccount(new Payplug($data[$live_key_fieldkey]));
935 } catch (ForbiddenException $e){
936 PayplugGateway::log('Error while saving account : ' . $e->getMessage(), 'error');
937 \WC_Admin_Settings::add_error($e->getMessage());
938 return false;
939 }
940 PayplugWoocommerceHelper::set_transient_data($response, [
941 'mode' => 'yes'
942 ]);
943 }
944
945 // Validate Oney thresholds
946 if($data['woocommerce_payplug_oney_thresholds_min'] < $this->min_oney_price || $data['woocommerce_payplug_oney_thresholds_max'] > $this->max_oney_price){
947 \WC_Admin_Settings::add_error(sprintf(__('The amount must be between %s€ and %s€.', 'payplug'), $this->min_oney_price, $this->max_oney_price));
948 return false;
949 }
950 if($data['woocommerce_payplug_oney_thresholds_min'] > $data['woocommerce_payplug_oney_thresholds_max']){
951 \WC_Admin_Settings::add_error(sprintf(__('Please note that the minimum amount entered is greater than the maximum amount entered.', 'payplug'), $this->min_oney_price, $this->max_oney_price));
952 return false;
953 }
954
955 $this->data = $data;
956 parent::process_admin_options();
957 }
958
959 /**
960 * Process payment.
961 *
962 * @param int $order_id
963 *
964 * @return array
965 * @throws \Exception
966 */
967 public function process_payment($order_id)
968 {
969
970 PayplugGateway::log(sprintf('Processing payment for order #%s', $order_id));
971
972 $order = wc_get_order($order_id);
973 $customer_id = PayplugWoocommerceHelper::is_pre_30() ? $order->customer_user : $order->get_customer_id();
974 $amount = (int) PayplugWoocommerceHelper::get_payplug_amount($order->get_total());
975 $amount = $this->validate_order_amount($amount);
976
977 if (is_wp_error($amount)) {
978 PayplugGateway::log(sprintf('Invalid amount %s for the order.', $order->get_total()), 'error');
979 throw new \Exception($amount->get_error_message());
980 }
981
982 $payment_token_id = (isset($_POST['wc-' . $this->id . '-payment-token']) && 'new' !== $_POST['wc-' . $this->id . '-payment-token'])
983 ? wc_clean($_POST['wc-' . $this->id . '-payment-token'])
984 : false;
985
986 if ($payment_token_id && $this->oneclick_available() && (int) $customer_id > 0) {
987 PayplugGateway::log(sprintf('Payment token found.', $amount));
988
989 return $this->process_payment_with_token($order, $amount, $customer_id, $payment_token_id);
990 }
991
992 return $this->process_standard_payment($order, $amount, $customer_id);
993 }
994
995 /**
996 * @param \WC_Order $order
997 * @param int $amount
998 * @param int $customer_id
999 *
1000 * @return array
1001 * @throws \Exception
1002 */
1003 public function process_standard_payment($order, $amount, $customer_id)
1004 {
1005
1006 $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
1007
1008 try {
1009 $address_data = PayplugAddressData::from_order($order);
1010
1011 $return_url = esc_url_raw($order->get_checkout_order_received_url());
1012
1013 if (!(substr( $return_url, 0, 4 ) === "http")) {
1014 $return_url = get_site_url().$return_url;
1015 }
1016
1017 $payment_data = [
1018 'amount' => $amount,
1019 'currency' => get_woocommerce_currency(),
1020 'allow_save_card' => $this->oneclick_available() && (int) $customer_id > 0,
1021 'billing' => $address_data->get_billing(),
1022 'shipping' => $address_data->get_shipping(),
1023 'hosted_payment' => [
1024 'return_url' => $return_url,
1025 'cancel_url' => esc_url_raw($order->get_cancel_order_url_raw()),
1026 ],
1027 'notification_url' => esc_url_raw(WC()->api_request_url('PayplugGateway')),
1028 'metadata' => [
1029 'order_id' => $order_id,
1030 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
1031 'domain' => $this->limit_length(esc_url_raw(home_url()), 500),
1032 ],
1033 ];
1034
1035 /**
1036 * Filter the payment data before it's used
1037 *
1038 * @param array $payment_data
1039 * @param int $order_id
1040 * @param array $customer_details
1041 * @param PayplugAddressData $address_data
1042 */
1043 $payment_data = apply_filters('payplug_gateway_payment_data', $payment_data, $order_id, [], $address_data);
1044 $payment = $this->api->payment_create($payment_data);
1045
1046 // Save transaction id for the order
1047 PayplugWoocommerceHelper::is_pre_30()
1048 ? update_post_meta($order_id, '_transaction_id', $payment->id)
1049 : $order->set_transaction_id($payment->id);
1050
1051 if (is_callable([$order, 'save'])) {
1052 $order->save();
1053 }
1054
1055 /**
1056 * Fires once a payment has been created.
1057 *
1058 * @param int $order_id Order ID
1059 * @param PaymentResource $payment Payment resource
1060 */
1061 \do_action('payplug_gateway_payment_created', $order_id, $payment);
1062
1063 $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
1064 PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
1065
1066 PayplugGateway::log(sprintf('Payment creation complete for order #%s', $order_id));
1067
1068 return [
1069 'result' => 'success',
1070 'redirect' => $payment->hosted_payment->payment_url,
1071 'cancel' => $payment->hosted_payment->cancel_url,
1072 ];
1073 } catch (HttpException $e) {
1074 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
1075 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
1076 } catch (\Exception $e) {
1077 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
1078 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
1079 }
1080 }
1081
1082 /**
1083 * @param \WC_Order $order
1084 * @param int $amount
1085 * @param int $customer_id
1086 * @param string $token_id
1087 *
1088 * @return array
1089 * @throws \Exception
1090 */
1091 public function process_payment_with_token($order, $amount, $customer_id, $token_id)
1092 {
1093
1094 $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
1095 $payment_token = WC_Payment_Tokens::get($token_id);
1096 if (!$payment_token || (int) $customer_id !== (int) $payment_token->get_user_id()) {
1097 PayplugGateway::log('Could not find the payment token or the payment doesn\'t belong to the current user.', 'error');
1098 throw new \Exception(__('Invalid payment method.', 'payplug'));
1099 }
1100
1101 try {
1102 $address_data = PayplugAddressData::from_order($order);
1103
1104 $return_url = esc_url_raw($order->get_checkout_order_received_url());
1105
1106 if (!(substr( $return_url, 0, 4 ) === "http")) {
1107 $return_url = get_site_url().$return_url;
1108 }
1109
1110 $payment_data = [
1111 'amount' => $amount,
1112 'currency' => get_woocommerce_currency(),
1113 'payment_method' => $payment_token->get_token(),
1114 'allow_save_card' => false,
1115 'billing' => $address_data->get_billing(),
1116 'shipping' => $address_data->get_shipping(),
1117 'initiator' => 'PAYER',
1118 'hosted_payment' => [
1119 'return_url' => $return_url,
1120 'cancel_url' => esc_url_raw($order->get_cancel_order_url_raw()),
1121 ],
1122 'notification_url' => esc_url_raw(WC()->api_request_url('PayplugGateway')),
1123 'metadata' => [
1124 'order_id' => $order_id,
1125 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
1126 'domain' => $this->limit_length(esc_url_raw(home_url()), 500),
1127 ],
1128 ];
1129
1130 /** This filter is documented in src/Gateway/PayplugGateway */
1131 $payment_data = apply_filters('payplug_gateway_payment_data', $payment_data, $order_id, [], $address_data);
1132 $payment = $this->api->payment_create($payment_data);
1133
1134 /** This action is documented in src/Gateway/PayplugGateway */
1135 \do_action('payplug_gateway_payment_created', $order_id, $payment);
1136
1137 $this->response->process_payment($payment, true);
1138
1139 PayplugGateway::log(sprintf('Payment process complete for order #%s', $order_id));
1140
1141 return [
1142 'result' => 'success',
1143 'is_paid' => $payment->__get('is_paid'), // Use for path redirect before DSP2
1144 'redirect' => ($payment->__get('is_paid')) ? $order->get_checkout_order_received_url() : $payment->__get('hosted_payment')->payment_url
1145 ];
1146 } catch (HttpException $e) {
1147 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
1148 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
1149 } catch (\Exception $e) {
1150 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
1151 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
1152 }
1153 }
1154
1155 /**
1156 * Process refund for an order paid with PayPlug gateway.
1157 *
1158 * @param int $order_id
1159 * @param null $amount
1160 * @param string $reason
1161 *
1162 * @return bool|\WP_Error
1163 */
1164 public function process_refund($order_id, $amount = null, $reason = '')
1165 {
1166 PayplugGateway::log(sprintf('Processing refund for order #%s', $order_id));
1167
1168 if( !$this->user_logged_in()){
1169 PayplugGateway::log(__('You must be logged in with your PayPlug account.', 'payplug'), 'error');
1170 return new \WP_Error('process_refund_error', __('You must be logged in with your PayPlug account.', 'payplug'));
1171 }
1172
1173 $order = wc_get_order($order_id);
1174 if (!$order instanceof \WC_Order) {
1175 PayplugGateway::log(sprintf('The order #%s does not exist.', $order_id), 'error');
1176
1177 return new \WP_Error('process_refund_error', sprintf(__('The order %s does not exist.', 'payplug'), $order_id));
1178 }
1179
1180 if ($order->get_status() === "cancelled") {
1181 PayplugGateway::log(sprintf('The order #%s cannot be refund.', $order_id), 'error');
1182
1183 return new \WP_Error('process_refund_error', sprintf(__('The order %s cannot be refund.', 'payplug'), $order_id));
1184 }
1185
1186 $transaction_id = PayplugWoocommerceHelper::is_pre_30() ? get_post_meta($order_id, '_transaction_id', true) : $order->get_transaction_id();
1187 if (empty($transaction_id)) {
1188 PayplugGateway::log(sprintf('The order #%s does not have PayPlug transaction ID associated with it.', $order_id), 'error');
1189
1190 return new \WP_Error('process_refund_error', __('No PayPlug transaction was found for this order. The refund could not be processed.', 'payplug'));
1191 }
1192
1193 $customer_id = PayplugWoocommerceHelper::is_pre_30() ? $order->customer_user : $order->get_customer_id();
1194
1195 $data = [
1196 'metadata' => [
1197 'order_id' => $order_id,
1198 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
1199 'refund_from' => 'woocommerce',
1200 ]
1201 ];
1202
1203 if (!is_null($amount)) {
1204 $data['amount'] = PayplugWoocommerceHelper::get_payplug_amount($amount);
1205 }
1206
1207 if (!empty($reason)) {
1208 $data['metadata']['reason'] = $reason;
1209 }
1210
1211 /**
1212 * Filter the refund data before it's used.
1213 *
1214 * @param array $data
1215 * @param int $order_id
1216 * @param string $transaction_id
1217 */
1218 $data = apply_filters('payplug_gateway_refund_data', $data, $order_id, $transaction_id);
1219
1220 try {
1221 $refund = $this->api->refund_create($transaction_id, $data);
1222
1223 /**
1224 * Fires once a refund has been created.
1225 *
1226 * @param int $order_id Order ID
1227 * @param RefundResource $refund Refund resource
1228 * @param string $transaction_id Transaction id
1229 */
1230 \do_action('payplug_gateway_refund_created', $order_id, $refund, $transaction_id);
1231
1232 $refund_meta_key = sprintf('_pr_%s', wc_clean($refund->id));
1233 if (PayplugWoocommerceHelper::is_pre_30()) {
1234 update_post_meta($order_id, $refund_meta_key, $refund->id);
1235 } else {
1236 $order->add_meta_data($refund_meta_key, $refund->id, true);
1237 $order->save();
1238 }
1239
1240 $note = sprintf(__('Refund %s : Refunded %s', 'payplug'), wc_clean($refund->id), wc_price(((int) $refund->amount) / 100));
1241 if (!empty($refund->metadata['reason'])) {
1242 $note .= sprintf(' (%s)', esc_html($refund->metadata['reason']));
1243 }
1244 $order->add_order_note($note);
1245
1246 try {
1247 $payment = $this->api->payment_retrieve($transaction_id);
1248 $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
1249 PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
1250 } catch (\Exception $e) {
1251 }
1252
1253 PayplugGateway::log('Refund process complete for the order.');
1254
1255 return true;
1256 } catch (HttpException $e) {
1257 PayplugGateway::log(sprintf('Refund request error for the order %s from PayPlug API : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
1258
1259 return new \WP_Error('process_refund_error', __('The transaction could not be refunded. Please try again.', 'payplug'));
1260 } catch (\Exception $e) {
1261 PayplugGateway::log(sprintf('Refund request error for the order %s : %s', $order_id, wc_clean($e->getMessage())), 'error');
1262
1263 return new \WP_Error('process_refund_error', __('The transaction could not be refunded. Please try again.', 'payplug'));
1264 }
1265 }
1266
1267 /**
1268 * Check the order amount to ensure it's on the allowed range.
1269 *
1270 * @param int $amount
1271 *
1272 * @return int|\WP_Error
1273 */
1274 public function validate_order_amount($amount)
1275 {
1276 if (
1277 $amount < PayplugWoocommerceHelper::get_minimum_amount()
1278 || $amount > PayplugWoocommerceHelper::get_maximum_amount()
1279 ) {
1280 return new \WP_Error(
1281 'invalid order amount',
1282 sprintf(__('Payments for this amount (%s) are not authorised with this payment gateway.', 'payplug'), \wc_price($amount / 100))
1283 );
1284 }
1285
1286 return $amount;
1287 }
1288
1289 /**
1290 * Limit string length.
1291 *
1292 * @param string $value
1293 * @param int $maxlength
1294 *
1295 * @return string
1296 */
1297 public function limit_length($value, $maxlength = 100)
1298 {
1299 return (strlen($value) > $maxlength) ? substr($value, 0, $maxlength) : $value;
1300 }
1301
1302 /**
1303 * Get user's keys.
1304 *
1305 * @param string $email
1306 * @param string $password
1307 *
1308 * @return array|\WP_Error
1309 */
1310 public function retrieve_user_api_keys($email, $password)
1311 {
1312 if (empty($email) || empty($password)) {
1313 return new \WP_Error('missing_login_data', __('Please fill all login fields', 'payplug'));
1314 }
1315
1316 try {
1317 $response = Authentication::getKeysByLogin($email, $password);
1318 if (empty($response) || !isset($response['httpResponse']) && "payplug" === $this->id) {
1319 return new \WP_Error('invalid_credentials', __('Invalid credentials.', 'payplug'));
1320 }
1321
1322 return $response['httpResponse']['secret_keys'];
1323 } catch (HttpException $e) {
1324 if("payplug" === $this->id) {
1325 return new \WP_Error('invalid_credentials', __('Invalid credentials.', 'payplug'));
1326 }
1327 }
1328 }
1329
1330 /**
1331 * Get user merchant id.
1332 *
1333 * This method might be called during the login process before the global PayPlug
1334 * configuration is set. In that case you can pass a valid token to make the request.
1335 *
1336 * @param string|null $key
1337 *
1338 * @return string
1339 */
1340 public function retrieve_merchant_id($key = null)
1341 {
1342 try {
1343 $response = !is_null($key) ? Authentication::getAccount(new Payplug($key)) : Authentication::getAccount();
1344 PayplugWoocommerceHelper::set_transient_data($response);
1345 $merchant_id = isset($response['httpResponse']['id']) ? $response['httpResponse']['id'] : '';
1346 } catch (ConfigurationException $e) {
1347 PayplugGateway::log(sprintf('Missing API key for PayPlug client : %s', wc_print_r($e->getMessage(), true)), 'error');
1348
1349 $merchant_id = '';
1350 } catch (HttpException $e) {
1351 PayplugGateway::log(sprintf('Account request error from PayPlug API : %s', wc_print_r($e->getErrorObject(), true)), 'error');
1352
1353 $merchant_id = '';
1354 } catch (\Exception $e) {
1355 PayplugGateway::log(sprintf('Account request error : %s', wc_clean($e->getMessage())), 'error');
1356
1357 $merchant_id = '';
1358 }
1359
1360 return $merchant_id;
1361 }
1362
1363 /**
1364 * Generate Hidden HTML.
1365 *
1366 * @param string $key
1367 * @param array $data
1368 *
1369 * @return string
1370 */
1371 public function generate_hidden_html($key, $data)
1372 {
1373 $field_key = $this->get_field_key($key);
1374 $defaults = array(
1375 'title' => '',
1376 'disabled' => false,
1377 'class' => '',
1378 'css' => '',
1379 'placeholder' => '',
1380 'type' => 'text',
1381 'desc_tip' => false,
1382 'description' => '',
1383 'custom_attributes' => array(),
1384 );
1385
1386 $data = wp_parse_args($data, $defaults);
1387
1388 ob_start();
1389 ?>
1390 <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)); ?>" />
1391 <?php
1392
1393 return ob_get_clean();
1394 }
1395
1396 /**
1397 * Generate Yes/No Input HTML.
1398 *
1399 * @param string $key
1400 * @param array $data
1401 *
1402 * @return string
1403 */
1404 public function generate_yes_no_html($key, $data)
1405 {
1406 $field_key = $this->get_field_key($key);
1407 $defaults = array(
1408 'title' => '',
1409 'no' => 'No',
1410 'yes' => 'Yes',
1411 'disabled' => false,
1412 'class' => '',
1413 'css' => '',
1414 'placeholder' => '',
1415 'type' => 'text',
1416 'desc_tip' => false,
1417 'description' => '',
1418 'custom_attributes' => [],
1419 'hide_label' => false,
1420 );
1421
1422 $data = wp_parse_args($data, $defaults);
1423 $checked = 'yes' === $this->get_option($key) ? '1' : '0';
1424
1425 ob_start();
1426 ?>
1427 <tr valign="top">
1428 <?php if (!$data['hide_label']) : ?>
1429 <th scope="row" class="titledesc">
1430 <label for="<?php echo esc_attr($field_key); ?>">
1431 <?php echo wp_kses_post($data['title']); ?>
1432 <?php echo $this->get_tooltip_html($data); ?>
1433 </label>
1434 </th>
1435 <?php endif; ?>
1436 <td class="forminp">
1437 <fieldset>
1438 <legend class="screen-reader-text"><span><?php echo wp_kses_post($data['title']); ?></span>
1439 </legend>
1440 <div class="radio--custom">
1441 <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); ?>>
1442 <label for="<?php echo esc_attr($field_key); ?>-yes"><?php echo esc_html($data['yes']); ?></label>
1443 </div>
1444 <div class="radio--custom">
1445 <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); ?>>
1446 <label for="<?php echo esc_attr($field_key); ?>-no"><?php echo esc_html($data['no']); ?></label>
1447 </div>
1448 <div id="live-mode-test-p"><?php echo $this->get_description_html($data); ?></div>
1449 </fieldset>
1450 </td>
1451 </tr>
1452 <?php
1453
1454 return ob_get_clean();
1455 }
1456
1457 /**
1458 * Generate Radio Input HTML.
1459 *
1460 * @param string $key
1461 * @param array $data
1462 *
1463 * @return string
1464 */
1465 public function generate_radio_html($key, $data)
1466 {
1467 $field_key = $this->get_field_key($key);
1468 $defaults = array(
1469 'title' => '',
1470 'disabled' => false,
1471 'class' => '',
1472 'css' => '',
1473 'placeholder' => '',
1474 'type' => 'text',
1475 'desc_tip' => false,
1476 'description' => '',
1477 'custom_attributes' => [],
1478 'options' => [],
1479 );
1480
1481 $data = wp_parse_args($data, $defaults);
1482
1483 ob_start();
1484 ?>
1485 <tr valign="top">
1486 <th scope="row" class="titledesc">
1487 <label for="<?php echo esc_attr($field_key); ?>">
1488 <?php echo wp_kses_post($data['title']); ?>
1489 <?php echo $this->get_tooltip_html($data); ?>
1490 </label>
1491 </th>
1492 <td class="forminp">
1493 <fieldset>
1494 <legend class="screen-reader-text"><span><?php echo wp_kses_post($data['title']); ?></span>
1495 </legend>
1496 <?php foreach ($data['options'] as $option_key => $option_value) : ?>
1497 <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); ?>>
1498 <label for="<?php echo esc_attr($field_key); ?>-<?php echo esc_attr($option_key); ?>"><?php echo esc_html($option_value); ?></label>
1499 <?php endforeach; ?>
1500 <?php echo $this->get_description_html($data); ?>
1501 </fieldset>
1502 </td>
1503 </tr>
1504 <?php
1505
1506 return ob_get_clean();
1507 }
1508
1509 /**
1510 * Generate Login HTML.
1511 *
1512 * @param string $key
1513 * @param array $data
1514 *
1515 * @return string
1516 */
1517 public function generate_login_html($key, $data)
1518 {
1519 $field_key = $this->get_field_key($key);
1520 $defaults = [];
1521
1522 $data = wp_parse_args($data, $defaults);
1523
1524 ob_start();
1525 ?>
1526 <tr valign="top">
1527 <td class="forminp">
1528 <p><?php echo $this->get_option('email'); ?></p>
1529 <p>
1530 <input id="payplug-logout" type="submit" name="submit_logout" value="<?php _e('Logout', 'payplug'); ?>">
1531 <input type="hidden" name="save" value="logout">
1532 <?php wp_nonce_field('payplug_user_logout', '_logoutaction'); ?>
1533 |
1534 <a href="https://portal.payplug.com" target="_blank"><?php _e('Go to your PayPlug Portal', 'payplug'); ?></a>
1535 </p>
1536 </td>
1537 </tr>
1538 <?php
1539
1540 return ob_get_clean();
1541 }
1542
1543
1544 /**
1545 * Generate Oney popup option HTML.
1546 *
1547 * @param string $key
1548 * @param array $data
1549 *
1550 * @return string
1551 */
1552 public function generate_oney_product_animation_html($key, $data)
1553 {
1554 $field_key = $this->get_field_key($key);
1555
1556 $defaults = array(
1557 'title' => '',
1558 'disabled' => false,
1559 'class' => '',
1560 'css' => '',
1561 'placeholder' => '',
1562 'type' => 'checkbox',
1563 'desc_tip' => false,
1564 'description' => '',
1565 'custom_attributes' => [],
1566 'options' => [],
1567 );
1568
1569 $data = wp_parse_args($data, $defaults);
1570
1571 ob_start();
1572 ?>
1573 <tr valign="top" id="oney_installments_pop_up">
1574 <th scope="row" class="titledesc">
1575 <label for="<?php echo esc_attr($field_key); ?>">
1576 <?php echo wp_kses_post($data['title']); ?>
1577 <?php echo $this->get_tooltip_html($data); ?>
1578 </label>
1579 </th>
1580 <td class="forminp">
1581 <fieldset>
1582 <legend class="screen-reader-text"><span><?php echo wp_kses_post($data['title']); ?></span></legend>
1583 <label for="woocommerce_payplug_oney_product_animation">
1584 <input class="" type="checkbox" name="woocommerce_payplug_oney_product_animation" id="woocommerce_payplug_oney_product_animation" style="" <?php echo (($this->oney_product_animation == 'yes') ? "checked" : ''); ?>> <?php echo wp_kses_post($data['label']); ?></label><br>
1585 <p class="description"> <?php echo wp_kses_post($data['description']); ?></p>
1586 </fieldset>
1587 </td>
1588 </tr>
1589 <?php
1590
1591 return ob_get_clean();
1592 }
1593
1594 /**
1595 * Generate Oney Type Input HTML.
1596 *
1597 * @param string $key
1598 * @param array $data
1599 *
1600 * @return string
1601 */
1602 public function generate_oney_type_html($key, $data)
1603 {
1604 $field_key = $this->get_field_key($key);
1605 $defaults = array(
1606 'title' => '',
1607 'disabled' => false,
1608 'class' => '',
1609 'css' => '',
1610 'placeholder' => '',
1611 'type' => 'text',
1612 'desc_tip' => false,
1613 'description' => '',
1614 'custom_attributes' => [],
1615 'options' => [],
1616 );
1617
1618 $data = wp_parse_args($data, $defaults);
1619
1620 ob_start();
1621 ?>
1622 <tr valign="top" id="woocommerce_payplug_oney_type">
1623 <th scope="row" class="titledesc" style="padding-top: 0px;">
1624 <label for="<?php echo esc_attr($field_key); ?>">
1625 <?php echo wp_kses_post($data['title']); ?>
1626 <?php echo $this->get_tooltip_html($data); ?>
1627 </label>
1628 </th>
1629 <td class="forminp" style="padding-top: 0px;">
1630 <fieldset>
1631 <legend class="screen-reader-text"><span><?php echo wp_kses_post($data['title']); ?></span>
1632 </legend>
1633 <?php foreach ($data['options'] as $option_key => $option_value) : ?>
1634 <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); ?>>
1635 <label for="<?php echo esc_attr($field_key); ?>-<?php echo esc_attr($option_key); ?>" style="margin-right: 20px !important;">
1636 <span style="font-weight: 500;"><?php echo esc_html($option_value); ?></span>
1637 <span style="color:#646970;"> : <?php echo $data['descriptions'][$option_key] ;?></span>
1638 </label>
1639 <?php endforeach; ?>
1640 <?php echo $this->get_description_html($data); ?>
1641 </fieldset>
1642 </td>
1643 </tr>
1644 <?php
1645
1646 return ob_get_clean();
1647 }
1648
1649 /**
1650 * Generate Oney Thresholds Input HTML.
1651 *
1652 * @param string $key
1653 * @param array $data
1654 *
1655 * @return string
1656 */
1657 public function generate_oney_thresholds_html($key, $data)
1658 {
1659 $field_key = $this->get_field_key($key);
1660 $defaults = array(
1661 'title' => '',
1662 'disabled' => false,
1663 'class' => '',
1664 'css' => '',
1665 'placeholder' => '',
1666 'type' => 'text',
1667 'desc_tip' => false,
1668 'description' => '',
1669 'custom_attributes' => [],
1670 'options' => [],
1671 );
1672
1673 $data = wp_parse_args($data, $defaults);
1674
1675 ob_start();
1676 ?>
1677 <tr valign="top" id="woocommerce_payplug_oney_thresholds">
1678 <th scope="row" class="titledesc" style="padding-top: 0px;">
1679 <label for="<?php echo esc_attr($field_key); ?>">
1680 <?php echo wp_kses_post($data['title']); ?>
1681 <?php echo $this->get_tooltip_html($data); ?>
1682 </label>
1683 </th>
1684 <td class="forminp" style="padding-top: 0px;">
1685 <fieldset>
1686 <div id="oney_thresholds_description"><?php echo $this->get_description_html($data); ?></div>
1687 <input type="number" id="payplug_oney_thresholds_min" min="<?php echo $this->min_oney_price;?>" max="<?php echo $this->max_oney_price;?>" class="payplug-admin-oney-threshold-input">
1688 <b class="d-inline-block">€</b>
1689 <div class="d-inline-block" id="slider-range"></div>
1690 <input type="number" id="payplug_oney_thresholds_max" min="<?php echo $this->min_oney_price;?>" max="<?php echo $this->max_oney_price;?>" class="payplug-admin-oney-threshold-input">
1691 <b class="d-inline-block">€</b>
1692 </fieldset>
1693 </td>
1694 </tr>
1695 <?php
1696
1697 return ob_get_clean();
1698 }
1699
1700 /**
1701 * Validate Radio Field.
1702 *
1703 * Make sure the data is escaped correctly, etc.
1704 *
1705 * @param string $key
1706 * @param string|null $value Posted Value
1707 *
1708 * @return string
1709 */
1710 public function validate_radio_field($key, $value)
1711 {
1712 $value = is_null($value) ? '' : $value;
1713
1714 return wc_clean(stripslashes($value));
1715 }
1716
1717 /**
1718 * Validate Yes/No Field.
1719 *
1720 * @param string $key
1721 * @param string $value Posted Value
1722 *
1723 * @return string
1724 */
1725 public function validate_yes_no_field($key, $value)
1726 {
1727 return ('1' === (string) $value) ? 'yes' : 'no';
1728 }
1729
1730 /**
1731 * Validate Yes/No Field.
1732 *
1733 * @param string $key
1734 * @param string $value Posted Value
1735 *
1736 * @return string
1737 */
1738 public function validate_oney_product_animation_field($key, $value)
1739 {
1740 return ('on' === (string) $value) ? 'yes' : 'no';
1741 }
1742
1743 /**
1744 * Validate Oney Type Field.
1745 *
1746 * Make sure the data is escaped correctly, etc.
1747 *
1748 * @param string $key
1749 * @param string|null $value Posted Value
1750 *
1751 * @return string
1752 */
1753 public function validate_oney_type_field($key, $value)
1754 {
1755 $value = is_null($value) ? 'with_fees' : $value;
1756
1757 return wc_clean(stripslashes($value));
1758 }
1759
1760 /**
1761 * Validate Oney Thresholds Field.
1762 *
1763 * Make sure the data is escaped correctly, etc.
1764 *
1765 * @param string $key
1766 * @param string|null $value Posted Value
1767 *
1768 * @return string
1769 */
1770 public function validate_oney_thresholds_field($key, $value)
1771 {
1772 $value = is_null($value) ? [100, 3000] : $value;
1773
1774 return wc_clean($value);
1775 }
1776
1777 /**
1778 * Get PayPlug gateway mode.
1779 *
1780 * @return string
1781 */
1782 public function get_current_mode()
1783 {
1784 return ('yes' === $this->get_option('mode')) ? 'live' : 'test';
1785 }
1786
1787 /**
1788 * Get user API key.
1789 *
1790 * @param string $mode
1791 *
1792 * @return string
1793 */
1794 public function get_api_key($mode = 'test')
1795 {
1796
1797 switch ($mode) {
1798 case 'test':
1799 $key = $this->get_option('payplug_test_key');
1800 break;
1801 case 'live':
1802 $key = $this->get_option('payplug_live_key');
1803 break;
1804 default:
1805 $key = '';
1806 break;
1807 }
1808
1809 return $key;
1810 }
1811
1812 /**
1813 * Check if an api key exist for a mode.
1814 *
1815 * @param string $mode
1816 *
1817 * @return bool
1818 */
1819 public function has_api_key($mode = 'test')
1820 {
1821 $key = $this->get_api_key($mode);
1822 $key = trim($key);
1823
1824 return !empty($key);
1825 }
1826
1827 /**
1828 * Get current merchant id.
1829 *
1830 * @return string
1831 */
1832 public function get_merchant_id()
1833 {
1834 return $this->get_option('payplug_merchant_id', '');
1835 }
1836
1837 /**
1838 * Check if user is logged in and we have an API key for TEST mode.
1839 *
1840 * @return bool
1841 */
1842 public function user_logged_in()
1843 {
1844 return !empty($this->get_option('payplug_test_key'));
1845 }
1846
1847 /**
1848 * Check if oneclick payment is activated and merchant can use it.
1849 *
1850 * @return bool
1851 */
1852 public function oneclick_available()
1853 {
1854 return $this->user_logged_in()
1855 && $this->oneclick
1856 && $this->permissions->has_permissions(PayplugPermissions::SAVE_CARD);
1857 }
1858
1859 /**
1860 * Check if the gatteway is allowed for the order amount
1861 *
1862 * @param array
1863 * @return array
1864 */
1865 public function check_gateway($gateways)
1866 {
1867 if ( !empty( WC()->cart ) && isset($gateways[$this->id]) && $gateways[$this->id]->id == $this->id) {
1868 $order_amount = $this->get_order_total();
1869 if ($order_amount < self::MIN_AMOUNT || $order_amount > self::MAX_AMOUNT) {
1870 unset($gateways[$this->id]);
1871 }
1872 }
1873 if($this->oney_type == 'with_fees'){
1874 unset($gateways['oney_x3_without_fees']);
1875 unset($gateways['oney_x4_without_fees']);
1876 } else{
1877 unset($gateways['oney_x3_with_fees']);
1878 unset($gateways['oney_x4_with_fees']);
1879 }
1880 return $gateways;
1881 }
1882
1883 /**
1884 * Can the order be refunded via this gateway?
1885 *
1886 *
1887 * @param WC_Order $order Order object.
1888 * @return bool If false, the automatic refund button is hidden in the UI.
1889 */
1890 public function can_refund_order($order)
1891 {
1892 $status = $order->get_status();
1893 return $order && $this->supports('refunds') && $status !== "cancelled" && $status !== "failed";
1894 }
1895
1896 public function getPayplugMerchantCountry(){
1897 return $this->payplug_merchant_country;
1898 }
1899
1900 public function setPayplugMerchantCountry($country){
1901 $this->payplug_merchant_country = $country;
1902 }
1903 }
1904