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