PluginProbe
PayPlug for WooCommerce (Official) / 2.6.3
PayPlug for WooCommerce (Official) v2.6.3
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) 2.6.3, at src/Gateway/PayplugGateway.php

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