PluginProbe
PayPlug for WooCommerce (Official) / 2.10.0
PayPlug for WooCommerce (Official) v2.10.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/PayplugWoocommerceRequest.php +339 -575 3.0.0 → 2.10.0 View file →
@@ -2,671 +2,435 @@
2 2
3 3 namespace Payplug\PayplugWoocommerce;
4 4
5 5 // Exit if accessed directly
6 -use Automattic\WooCommerce\Utilities\OrderUtil;
7 -use Payplug\Exception\HttpException;
6 +use Payplug\PayplugWoocommerce\Controller\WC_Payplug_Intent_Controller as PayplugIntent;
8 7 use Payplug\PayplugWoocommerce\Gateway\PayplugAddressData;
9 8 use Payplug\PayplugWoocommerce\Gateway\PayplugGateway;
10 -use Payplug\PayplugWoocommerce\Traits\ServiceGetter;
9 +use WC_Payment_Tokens;
10 +use WP_REST_Request;
11 +use Automattic\WooCommerce\Utilities\OrderUtil;
11 12
12 -if (!defined('ABSPATH')) {
13 - exit;
13 +if ( ! defined( 'ABSPATH' ) ) {
14 + exit;
14 15 }
15 16
16 17 /**
17 18 * Class PayplugWoocommerceRequest
19 + * @package Payplug\PayplugWoocommerce
18 20 */
19 -class PayplugWoocommerceRequest
20 -{
21 - use ServiceGetter;
21 +class PayplugWoocommerceRequest {
22 22
23 - /**
24 - * Gateway settings.
25 - *
26 - * @var array
27 - */
28 - protected $settings;
23 + /**
24 + * Gateway settings.
25 + *
26 + * @var array
27 + */
28 + protected $settings;
29 29
30 - /**
31 - * @var PayplugGateway
32 - */
33 - protected $gateway;
30 + /**
31 + * @var PayplugGateway
32 + */
33 + protected $gateway;
34 34
35 - /**
36 - * PayplugWoocommerceRequest constructor.
37 - */
38 - public function __construct()
39 - {
40 - $this->settings = $this->get_configuration()->get_options();
35 + /**
36 + * PayplugWoocommerceRequest constructor.
37 + */
38 + public function __construct() {
39 + $this->settings = get_option( 'woocommerce_payplug_settings', [] );
40 + if ( empty( $this->settings ) || ! isset( $this->settings['enabled'] ) || 'yes' !== $this->settings['enabled'] ) {
41 + return;
42 + }
41 43
42 - if (empty($this->settings) || !isset($this->settings['enabled']) || !(bool) $this->settings['enabled']) {
43 - return;
44 - }
44 + // Don't load for change payment method page.
45 + if ( isset( $_GET['change_payment_method'] ) ) {
46 + return;
47 + }
45 48
46 - // Don't load for change payment method page.
47 - if (isset($_GET['change_payment_method'])) {
48 - return;
49 - }
49 + add_action( 'template_redirect', [ $this, 'set_session' ] );
50 + add_action( 'wc_ajax_payplug_create_order', [ $this, 'ajax_create_order' ] );
51 + add_action( 'wc_ajax_applepay_update_payment', [ $this, 'applepay_update_payment' ] );
52 + add_action( 'wc_ajax_applepay_get_order_totals', [ $this, 'applepay_get_order_totals' ] );
53 + add_action( 'wc_ajax_payplug_order_review_url', [ $this, 'ajax_create_payment' ] );
54 + add_action( 'wc_ajax_payplug_check_payment', [$this, 'check_payment']);
55 + add_action( 'wc_ajax_payplug_create_intent', [$this, 'create_payment_intent']);
50 56
51 - add_action('template_redirect', [$this, 'set_session']);
52 - add_action('wc_ajax_payplug_create_order', [$this, 'ajax_create_order']);
53 - add_action('wc_ajax_applepay_update_payment', [$this, 'applepay_update_payment']);
54 - add_action('wc_ajax_applepay_get_order_totals', [$this, 'applepay_get_order_totals']);
55 - add_action('wc_ajax_payplug_order_review_url', [$this, 'ajax_create_payment']);
56 - add_action('wc_ajax_payplug_apple_pay_create_order_pay', [$this, 'ajax_apple_pay_create_order_pay']);
57 - add_action('wc_ajax_payplug_check_payment', [$this, 'check_payment']);
58 - add_action('wc_ajax_payplug_create_intent', [$this, 'create_payment_intent']);
59 - }
57 + }
60 58
61 - /**
62 - * Sets the WC customer session if one is not set.
63 - * This is needed so nonces can be verified by AJAX Request.
64 - */
65 - public function set_session(): void
66 - {
67 - if (!is_product() || (isset(WC()->session) && WC()->session->has_session())) {
68 - return;
69 - }
59 + /**
60 + * Sets the WC customer session if one is not set.
61 + * This is needed so nonces can be verified by AJAX Request.
62 + */
63 + public function set_session() {
64 + if ( ! is_product() || ( isset( WC()->session ) && WC()->session->has_session() ) ) {
65 + return;
66 + }
70 67
71 - $session_class = apply_filters('woocommerce_session_handler', 'WC_Session_Handler');
72 - $wc_session = new $session_class();
68 + $session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' );
69 + $wc_session = new $session_class();
73 70
74 - if (version_compare(WC_VERSION, '3.3', '>=')) {
75 - $wc_session->init();
76 - }
71 + if ( version_compare( WC_VERSION, '3.3', '>=' ) ) {
72 + $wc_session->init();
73 + }
77 74
78 - $wc_session->set_customer_session_cookie(true);
79 - }
75 + $wc_session->set_customer_session_cookie( true );
76 + }
80 77
81 - /**
82 - * Create the woocommerce order in the BO
83 - */
84 - public function ajax_create_order(): void
85 - {
86 - if (WC()->cart->is_empty()) {
87 - wp_send_json_error(__('Empty cart', 'payplug'));
88 - }
78 + /**
79 + * Create the woocommerce order in the BO
80 + *
81 + */
82 + public function ajax_create_order() {
83 + if ( WC()->cart->is_empty() ) {
84 + wp_send_json_error( __( 'Empty cart', 'payplug' ) );
85 + }
89 86
90 - if (!defined('WOOCOMMERCE_CHECKOUT')) {
91 - define('WOOCOMMERCE_CHECKOUT', true);
92 - }
87 + if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
88 + define( 'WOOCOMMERCE_CHECKOUT', true );
89 + }
93 90
94 - WC()->checkout()->process_checkout();
91 + WC()->checkout()->process_checkout();
95 92
96 - die(0);
97 - }
93 + die( 0 );
94 + }
98 95
99 - /**
100 - * Process Apple Pay payment for an existing order on the order-pay page.
101 - */
102 - public function ajax_apple_pay_create_order_pay(): void
103 - {
104 - if (!check_ajax_referer('woocommerce-process_checkout', 'woocommerce-process-checkout-nonce', false)) {
105 - wp_send_json([
106 - 'result' => 'failure',
107 - 'messages' => '<ul class="woocommerce-error"><li>' . __('Invalid order.', 'payplug') . '</li></ul>',
108 - ]);
96 + /**
97 + * Create the woocommerce order in the BO
98 + *
99 + */
100 + public function ajax_create_payment() {
109 101
110 - return;
111 - }
102 + if ( WC()->cart->is_empty() ) {
103 + wp_send_json_error( __( 'Empty cart', 'payplug' ) );
104 + }
112 105
113 - $order_id = isset($_POST['order_id']) ? absint(wp_unslash($_POST['order_id'])) : 0;
114 - $order_key = isset($_POST['order_key']) ? wc_clean(wp_unslash($_POST['order_key'])) : '';
106 + if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
107 + define( 'WOOCOMMERCE_CHECKOUT', true );
108 + }
115 109
116 - $order = $order_id ? wc_get_order($order_id) : null;
117 - if (!$order || !hash_equals($order->get_order_key(), $order_key)) {
118 - wp_send_json([
119 - 'result' => 'failure',
120 - 'messages' => '<ul class="woocommerce-error"><li>' . __('Invalid order.', 'payplug') . '</li></ul>',
121 - ]);
110 + $payment_method = $_POST['payment_method'];
122 111
123 - return;
124 - }
112 + //TODO:: check if integrated or embedded is activated, if not go to ajax_create_order as well
113 + if($payment_method === 'payplug'){
114 + $settings = get_option('woocommerce_payplug_settings', []);
115 + $method = $settings['payment_method'];
125 116
126 - // This AJAX request's own URL never carries the order-pay query var (only the page
127 - // that triggered it does), but WC_Payment_Gateway::get_order_total() - used by this
128 - // plugin's own check_gateway() filter on woocommerce_available_payment_gateways to
129 - // enforce per-method amount permissions - reads that query var to know whether to use
130 - // the order's total or the (here empty, on order-pay) cart's. Left unset, it falls
131 - // back to a cart total of 0, which the amount-permission check then rejects, making
132 - // Apple Pay appear unavailable below. Setting it restores the normal, fully validated
133 - // availability check (API key, requirements, amount permissions, etc.).
134 - global $wp_query;
135 - $wp_query->set('order-pay', $order_id);
117 + if($method !== "integrated" && $method !== "popup" ){
118 + $this->ajax_create_order();
119 + }
136 120
137 - $available_gateways = WC()->payment_gateways->get_available_payment_gateways();
138 - if (!isset($available_gateways['apple_pay'])) {
139 - wp_send_json([
140 - 'result' => 'failure',
141 - 'messages' => '<ul class="woocommerce-error"><li>' . __('Apple Pay not available.', 'payplug') . '</li></ul>',
142 - ]);
121 + }else{
122 + $this->ajax_create_order();
123 + }
143 124
144 - return;
145 - }
125 + $https_referer = $_POST['_wp_http_referer'];
126 + $path = parse_url($https_referer);
127 + wp_parse_str($path['query'], $output);
128 + $order_id = $output['order-pay'];
146 129
147 - try {
148 - $result = $available_gateways['apple_pay']->process_payment($order_id);
149 - wp_send_json($result);
150 - } catch (\Exception $e) {
151 - wp_send_json([
152 - 'result' => 'failure',
153 - 'messages' => '<ul class="woocommerce-error"><li>' . esc_html($e->getMessage()) . '</li></ul>',
154 - ]);
155 - }
156 - }
130 + if(is_null($order_id)){
131 + preg_match("/(?<=order-pay\/)\d*/", $path['path'], $matches);
132 + $order_id = $matches[0];
133 + }
157 134
158 - /**
159 - * Create the woocommerce order in the BO
160 - */
161 - public function ajax_create_payment(): void
162 - {
163 - global $wp;
135 + $this->process_order_payment($order_id, $payment_method);
164 136
165 - $https_referer = wc_clean(wp_unslash($_POST['_wp_http_referer'] ?? ''));
166 - $path = wp_parse_url($https_referer) ?: [];
167 - $output = [];
168 - if (!empty($path['query'])) {
169 - wp_parse_str($path['query'], $output);
170 - }
137 + }
171 138
172 - if (isset($output['order-pay'])) {
173 - $order_id = absint($output['order-pay']);
174 - } else {
175 - preg_match('/(?<=order-pay\/)\d*/', $path['path'] ?? '', $matches);
176 - $order_id = !empty($matches[0]) ? absint($matches[0]) : 0;
177 - }
139 + /**
140 + * wordpress class-wc-checkout.php
141 + * We don't need all the other verifications, at this point customer already had the checkout and it's all valid, the order already exists
142 + * We can+t use WP method because it's protected
143 + * Process an order that does require payment.
144 + *
145 + * @since 3.0.0
146 + * @param int $order_id Order ID.
147 + * @param string $payment_method Payment method.
148 + */
149 + protected function process_order_payment( $order_id, $payment_method ) {
150 + $available_gateways = WC()->payment_gateways->get_available_payment_gateways();
178 151
179 - // The referer is client-supplied and can be spoofed: only trust it as an order-pay
180 - // request once the order it names is confirmed real and the key matches, exactly
181 - // like the order-pay AJAX flows below already require (create_payment_intent,
182 - // ajax_apple_pay_create_order_pay). Otherwise fall through as a regular checkout.
183 - $order = $order_id ? wc_get_order($order_id) : false;
184 - if (!$order instanceof \WC_Order || !hash_equals($order->get_order_key(), wc_clean(wp_unslash($output['key'] ?? '')))) {
185 - $order_id = 0;
186 - }
152 + if ( ! isset( $available_gateways[ $payment_method ] ) ) {
153 + return;
154 + }
187 155
188 - // Order-pay repays an existing order, whose line items live on the order itself,
189 - // not the session cart - which is legitimately empty here (the customer already
190 - // completed checkout for it), so only require a non-empty cart on a fresh checkout.
191 - if (empty($order_id) && WC()->cart->is_empty()) {
192 - wp_send_json_error(__('Empty cart', 'payplug'));
193 - }
156 + // Store Order ID in session so it can be re-used after payment failure.
157 + WC()->session->set( 'order_awaiting_payment', $order_id );
194 158
195 - if (!defined('WOOCOMMERCE_CHECKOUT')) {
196 - define('WOOCOMMERCE_CHECKOUT', true);
197 - }
159 + // Process Payment.
160 + $result = $available_gateways[ $payment_method ]->process_payment( $order_id );
198 161
199 - $payment_method = $_POST['payment_method'];
162 + // Redirect to success/confirmation/payment page.
163 + if ( isset( $result['result'] ) && 'success' === $result['result'] ) {
164 + $result['order_id'] = $order_id;
200 165
201 - if ($payment_method === 'payplug' || $payment_method === 'american_express') {
202 - $method = $this->get_configuration()->get_option('payment_methods.configuration.payplug.embedded_mode');
203 - if ('integrated' != $method && 'popup' != $method) {
204 - $this->ajax_create_order();
205 - }
206 - } else {
207 - $this->ajax_create_order();
208 - }
166 + $result = apply_filters( 'woocommerce_payment_successful_result', $result, $order_id );
209 167
210 - $this->process_order_payment($order_id, $payment_method);
211 - }
168 + if ( ! wp_doing_ajax() ) {
169 + // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect
170 + wp_redirect( $result['redirect'] );
171 + exit;
172 + }
212 173
213 - /**
214 - * wordpress class-wc-checkout.php
215 - * We don't need all the other verifications, at this point customer already had the checkout and it's all valid, the order already exists
216 - * We can+t use WP method because it's protected
217 - * Process an order that does require payment.
218 - *
219 - * @since 3.0.0
220 - *
221 - * @param int $order_id Order ID.
222 - * @param string $payment_method Payment method.
223 - */
224 - protected function process_order_payment($order_id, $payment_method): void
225 - {
226 - // This AJAX request's own URL never carries the order-pay query var (only the page
227 - // that triggered it does), but WC_Payment_Gateway::get_order_total() - used by this
228 - // plugin's own check_gateway() filter on woocommerce_available_payment_gateways to
229 - // enforce per-method amount permissions - reads that query var to know whether to use
230 - // the order's total or the (here empty, on order-pay) cart's. Left unset, it falls
231 - // back to a cart total of 0, which the amount-permission check then rejects, making
232 - // every gateway appear unavailable below. Setting it restores the normal, fully
233 - // validated availability check (API key, requirements, amount permissions, etc.).
234 - global $wp_query;
235 - $wp_query->set('order-pay', $order_id);
174 + wp_send_json( $result );
175 + }
176 + }
236 177
237 - $available_gateways = WC()->payment_gateways->get_available_payment_gateways();
238 178
239 - if (!isset($available_gateways[$payment_method])) {
240 - return;
241 - }
242 179
243 - // Store Order ID in session so it can be re-used after payment failure.
244 - WC()->session->set('order_awaiting_payment', $order_id);
180 + /**
181 + * Update Payplug API Payment for Apple Pay
182 + */
183 + public function applepay_update_payment() {
245 184
246 - // Process Payment.
247 - $result = $available_gateways[$payment_method]->process_payment($order_id);
185 + $options = get_option('woocommerce_payplug_settings', []);
186 + $order_id = $_POST['order_id'];
187 + $payment_id = $_POST['payment_id'];
248 188
249 - // Redirect to success/confirmation/payment page.
250 - if (isset($result['result']) && 'success' === $result['result']) {
251 - $result['order_id'] = $order_id;
189 + try{
190 + \Payplug\Payplug::init(array(
191 + 'secretKey' => @$options['payplug_live_key'],
192 + 'apiVersion' => "2019-08-06",
193 + ));
252 194
253 - $result = apply_filters('woocommerce_payment_successful_result', $result, $order_id);
195 + $apple_pay = array();
196 + $apple_pay['payment_token'] = $_POST['payment_token'];
197 + $payment = \Payplug\Payment::retrieve($payment_id);
254 198
255 - if (!wp_doing_ajax()) {
256 - // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect
257 - wp_redirect($result['redirect']);
258 - exit;
259 - }
199 + $data = array( 'apple_pay' => $apple_pay );
200 + $update = $payment->update($data);
260 201
261 - wp_send_json($result);
262 - }
263 - }
202 + wp_send_json_success([ "result" => $update->is_paid ]);
264 203
265 - /**
266 - * Update Payplug API Payment for Apple Pay
267 - */
268 - public function applepay_update_payment(): void
269 - {
270 - $payment_id = $_POST['payment_id'];
271 - $apiService = new \Payplug\PayplugWoocommerce\Service\Api();
272 - $mode = PayplugWoocommerceHelper::check_mode() ? 'live' : 'test';
273 - $bearer_token = $apiService->get_bearer_token($mode);
274 - try {
275 - \Payplug\Payplug::init([
276 - 'secretKey' => $bearer_token,
277 - 'apiVersion' => '2019-08-06',
278 - ]);
279 - } catch (\Exception $e) {
280 - $is_401 = (method_exists($e, 'getCode') && $e->getCode() == 401)
281 - || strpos($e->getMessage(), '401') !== false;
282 - if ($is_401 && $this->try_refresh_jwt($apiService, $mode)) {
283 - try {
284 - \Payplug\Payplug::init([
285 - 'secretKey' => $apiService->get_bearer_token($mode),
286 - 'apiVersion' => '2019-08-06',
287 - ]);
288 - } catch (\Exception $e) {
289 - PayplugWoocommerceHelper::payplug_logout();
290 - wp_send_json_error(__('You have been disconnected from the Payplug module (error 401)', 'payplug'));
204 + }catch (\Exception $e){
205 + wp_send_json_error($e->getMessage());
206 + }
207 + }
291 208
292 - return;
293 - }
294 - } else {
295 - if ($is_401) {
296 - PayplugWoocommerceHelper::payplug_logout();
297 - wp_send_json_error(__('You have been disconnected from the Payplug module (error 401)', 'payplug'));
298 - } else {
299 - wp_send_json_error($e->getMessage());
300 - }
209 + public function applepay_get_order_totals()
210 + {
211 + try {
212 + wp_send_json_success(WC()->cart->total);
301 213
302 - return;
303 - }
304 - }
305 - $apple_pay = [];
306 - $apple_pay['payment_token'] = $_POST['payment_token'];
307 - $payment = \Payplug\Payment::retrieve($payment_id);
308 - $data = ['apple_pay' => $apple_pay];
309 - $update = $payment->update($data);
310 - wp_send_json_success(['result' => $update->is_paid]);
311 - }
214 + } catch (\Exception $e) {
215 + PayplugGateway::log($e->getMessage());
216 + wp_send_json_error($e->getMessage());
217 + }
218 + }
219 + /**
220 + * Limit string length.
221 + *
222 + * @param string $value
223 + * @param int $maxlength
224 + *
225 + * @return string
226 + */
227 + public function limit_length($value, $maxlength = 100)
228 + {
229 + return (strlen($value) > $maxlength) ? substr($value, 0, $maxlength) : $value;
230 + }
312 231
313 - public function applepay_get_order_totals(): void
314 - {
315 - try {
316 - wp_send_json_success(WC()->cart->total);
317 - } catch (\Exception $e) {
318 - PayplugGateway::log($e->getMessage());
319 - wp_send_json_error($e->getMessage());
320 - }
321 - }
232 + public function check_payment() {
322 233
323 - /**
324 - * Empty cart for Apple Pay on product page
325 - */
326 - public function applepay_empty_cart(): void
327 - {
328 - try {
329 - WC()->cart->empty_cart();
330 - wp_send_json_success();
331 - } catch (\Exception $e) {
332 - wp_send_json_error([
333 - 'message' => __('Your order was cancelled.', 'woocommerce'),
334 - ]);
335 - }
336 - }
234 + global $wpdb;
337 235
338 - /**
339 - * Add the product on the current page to the cart for Apple Pay on product page
340 - */
341 - public function applepay_add_to_cart(): void
342 - {
343 - try {
344 - if (!empty($_POST['product_id'])) {
345 - $product_id = $_POST['product_id'];
346 - } else {
347 - $product_id = $_POST['product_variation_id'];
348 - }
236 + $payment_id = $_POST['payment_id'];
349 237
350 - $product_quantity = !empty($_POST['product_quantity']) ? $_POST['product_quantity'] : 1;
238 + if (PayplugWoocommerceHelper::check_mode()) {
239 + $key = PayplugWoocommerceHelper::get_live_key();
240 + } else {
241 + $key = PayplugWoocommerceHelper::get_test_key();
242 + }
351 243
352 - WC()->cart->add_to_cart($product_id, $product_quantity);
353 - wp_send_json_success([
354 - 'total' => WC()->cart->total - WC()->cart->shipping_total,
355 - ]);
356 - } catch (\Exception $e) {
357 - wp_send_json_error([
358 - 'message' => __('Your order was cancelled.', 'woocommerce'),
359 - ]);
360 - }
361 - }
244 + try {
245 + \Payplug\Payplug::init(array(
246 + 'secretKey' => $key,
247 + 'apiVersion' => "2019-08-06",
248 + ));
362 249
363 - /**
364 - * Limit string length.
365 - *
366 - * @param string $value
367 - * @param int $maxlength
368 - *
369 - * @return string
370 - */
371 - public function limit_length($value, $maxlength = 100)
372 - {
373 - return (strlen($value) > $maxlength) ? substr($value, 0, $maxlength) : $value;
374 - }
250 + $payment =\Payplug\Payment::retrieve($payment_id);
375 251
376 - public function check_payment(): void
377 - {
378 - global $wpdb;
379 - $payment_id = $_POST['payment_id'];
380 - if (empty($payment_id)) {
381 - wp_send_json_error(__('Invalid request.', 'payplug'));
382 - }
383 - $apiService = new \Payplug\PayplugWoocommerce\Service\Api();
384 - $mode = PayplugWoocommerceHelper::check_mode() ? 'live' : 'test';
385 - $bearer_token = $apiService->get_bearer_token($mode);
386 - try {
387 - \Payplug\Payplug::init([
388 - 'secretKey' => $bearer_token,
389 - 'apiVersion' => '2019-08-06',
390 - ]);
391 - $payment = \Payplug\Payment::retrieve($payment_id);
392 - } catch (\Exception $e) {
393 - $is_401 = (method_exists($e, 'getCode') && $e->getCode() == 401)
394 - || strpos($e->getMessage(), '401') !== false;
395 - if ($is_401) {
396 - if ($this->try_refresh_jwt($apiService, $mode)) {
397 - try {
398 - \Payplug\Payplug::init([
399 - 'secretKey' => $apiService->get_bearer_token($mode),
400 - 'apiVersion' => '2019-08-06',
401 - ]);
402 - $payment = \Payplug\Payment::retrieve($payment_id);
403 - } catch (\Exception $e) {
404 - PayplugWoocommerceHelper::payplug_logout();
405 - wp_send_json_error(__('You have been disconnected from the Payplug module (error 401)', 'payplug'));
252 + } catch ( \Exception $e ) {
406 253
407 - return;
408 - }
409 - } else {
410 - PayplugWoocommerceHelper::payplug_logout();
411 - wp_send_json_error(__('You have been disconnected from the Payplug module (error 401)', 'payplug'));
254 + $order_id = $this->getOrderFromPaymentId($payment_id);
255 + $order = wc_get_order($order_id);
412 256
413 - return;
414 - }
415 - } else {
416 - $order_id = $this->getOrderFromPaymentId($payment_id);
417 - $order = wc_get_order($order_id);
418 - PayplugGateway::log(
419 - sprintf(
420 - 'Order #%s : An error occurred while retrieving the payment data with the message : %s',
421 - $order_id,
422 - $e->getMessage()
423 - )
424 - );
425 - wp_send_json_error($e->getMessage());
426 - }
427 - }
428 - $order_id = $this->getOrderFromPaymentId($payment_id);
429 - $order = wc_get_order($order_id);
430 - $return_url = esc_url_raw($order->get_checkout_order_received_url());
431 - if ((isset($payment->failure)) && (!empty($payment->failure)) || ($payment->is_paid === false && is_null($payment->paid_at))) {
432 - $order->update_status('failed', __('Order cancelled by customer.', 'woocommerce'));
433 - wp_send_json_error(
434 - [
435 - 'code' => isset($payment->failure->code) ? $payment->failure->code : 500,
436 - 'message' => !empty($payment->failure->message) ? $payment->failure->message : __('payplug_integrated_payment_error', 'payplug'),
437 - 'cancel_url' => esc_url_raw($order->get_cancel_order_url_raw()),
438 - ]
439 - );
440 - }
257 + PayplugGateway::log(
258 + sprintf(
259 + 'Order #%s : An error occurred while retrieving the payment data with the message : %s',
260 + $order_id,
261 + $e->getMessage()
262 + )
263 + );
441 264
442 - wp_send_json_success([
443 - 'payment_id' => $payment->id,
444 - 'result' => 'success',
445 - 'redirect' => !empty($payment->hosted_payment->payment_url) ? $payment->hosted_payment->payment_url : $return_url,
446 - 'cancel' => !empty($payment->hosted_payment->cancel_url) ? $payment->hosted_payment->cancel_url : null,
447 - ]);
448 - }
265 + return wp_send_json_error( $e->getMessage());
266 + }
449 267
450 - /**
451 - * Attempt to regenerate the JWT for the given mode and persist the new token.
452 - *
453 - * @param \Payplug\PayplugWoocommerce\Service\Api $apiService
454 - * @param string $mode
455 - *
456 - * @return bool True if a new JWT was successfully obtained and stored.
457 - */
458 - private function try_refresh_jwt($apiService, $mode)
459 - {
460 - $configuration = $this->get_configuration();
461 - $options = $configuration->get_options();
462 - $oauth_client_data = isset($options['oauth_client_data']) ? json_decode($options['oauth_client_data'], true) : [];
463 - $client_data = isset($oauth_client_data[$mode]) ? $oauth_client_data[$mode] : [];
464 - if (empty($client_data)) {
465 - return false;
466 - }
467 - $new_jwt = $apiService->generate_jwt(
468 - isset($client_data['client_id']) ? $client_data['client_id'] : '',
469 - isset($client_data['client_secret']) ? $client_data['client_secret'] : ''
470 - );
471 - if (empty($new_jwt) || !isset($new_jwt['access_token'])) {
472 - return false;
473 - }
474 - $jwt = isset($options['jwt']) ? json_decode($options['jwt'], true) : [];
475 - $jwt[$mode] = $new_jwt;
476 - $api_keys = isset($options['api_key']) ? json_decode($options['api_key'], true) : [];
477 - $api_keys[$mode] = $new_jwt['access_token'];
478 - $configuration->update_option('jwt', json_encode($jwt));
479 - $configuration->update_option('api_key', json_encode($api_keys));
268 + $order_id = $this->getOrderFromPaymentId($payment_id);
269 + $order = wc_get_order($order_id);
270 + $return_url = esc_url_raw($order->get_checkout_order_received_url());
480 271
481 - return true;
482 - }
272 + if ((isset($payment->failure)) && (!empty($payment->failure)) || ($payment->is_paid === false && is_null($payment->paid_at))) {
483 273
484 - /**
485 - * @param $payment_id
486 - *
487 - * @return int|string|null
488 - */
489 - private function getOrderFromPaymentId($payment_id)
490 - {
491 - global $wpdb;
274 + $order->update_status( 'failed', __( 'Order cancelled by customer.', 'woocommerce' ) );
492 275
493 - if (OrderUtil::custom_orders_table_usage_is_enabled()) {
494 - $orders = wc_get_orders(
495 - [
496 - 'field_query' => [
497 - [
498 - 'key' => 'transaction_id',
499 - 'comparison' => $payment_id,
500 - ],
501 - ],
502 - ]
503 - );
504 - $order = $orders[0];
505 - $order_id = $order->get_id();
506 - } else {
507 - $sql = 'SELECT post_id
508 - FROM $wpdb->postmeta
509 - WHERE meta_key = "_transaction_id" AND meta_value = %s';
510 - $order_id = $wpdb->get_var(
511 - $wpdb->prepare(
512 - $sql,
513 - $payment_id
514 - )
515 - );
516 - }
276 + wp_send_json_error(
277 + [
278 + 'code' => isset($payment->failure->code) ? $payment->failure->code : 500,
279 + 'message' => !empty($payment->failure->message) ? $payment->failure->message :__("payplug_integrated_payment_error", "payplug"),
280 + 'cancel_url' => esc_url_raw($order->get_cancel_order_url_raw())
281 + ]
282 + );
283 + }
517 284
518 - return $order_id;
519 - }
520 285
521 - public function create_payment_intent(): void
522 - {
523 - if (!check_ajax_referer('woocommerce-process_checkout', 'woocommerce-process-checkout-nonce', false)) {
524 - wp_send_json_error(__('Invalid order.', 'payplug'), 403);
286 + wp_send_json_success(array(
287 + 'payment_id' => $payment->id,
288 + 'result' => 'success',
289 + 'redirect' => !empty($payment->hosted_payment->payment_url) ? $payment->hosted_payment->payment_url : $return_url,
290 + 'cancel' => !empty($payment->hosted_payment->cancel_url) ? $payment->hosted_payment->cancel_url : null
291 + ));
525 292
526 - return;
527 - }
293 + }
528 294
529 - $order_id = isset($_POST['order_id']) ? absint(wp_unslash($_POST['order_id'])) : 0;
530 - $this->gateway = $this->get_payplug_gateway(isset($_POST['gateway']) ? wc_clean(wp_unslash($_POST['gateway'])) : '');
531 - $order = wc_get_order($order_id);
295 + /**
296 + * @param $payment_id
297 + * @return int|string|null
298 + */
299 + private function getOrderFromPaymentId( $payment_id){
300 + global $wpdb;
532 301
533 - if (!$order instanceof \WC_Order || !$this->gateway) {
534 - wp_send_json_error(__('Invalid order.', 'payplug'));
302 + if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
303 + $orders = wc_get_orders(
304 + array(
305 + 'field_query' => array(
306 + array(
307 + 'key' => 'transaction_id',
308 + 'comparison' => $payment_id
309 + ),
310 + ),
311 + )
312 + );
313 + $order = $orders[0];
314 + $order_id = $order->get_id();
535 315
536 - return;
537 - }
316 + }else{
538 317
539 - // On order-pay, closing the payment sheet should keep the customer on the order-pay
540 - // page, not cancel the order and send them to the cart like a fresh checkout attempt
541 - // would.
542 - $is_order_pay = is_wc_endpoint_url('order-pay') || !empty($_POST['order_pay_key']);
318 + $sql = "SELECT post_id
319 + FROM $wpdb->postmeta
320 + WHERE meta_key = '_transaction_id' AND meta_value = %s";
321 + $order_id = $wpdb->get_var(
322 + $wpdb->prepare(
323 + $sql,
324 + $payment_id
325 + )
326 + );
327 + }
543 328
544 - if (!empty($_POST['order_pay_key'])) {
545 - $order_pay_key = wc_clean(wp_unslash($_POST['order_pay_key']));
546 - if (!hash_equals($order->get_order_key(), $order_pay_key)) {
547 - wp_send_json_error(__('Invalid order.', 'payplug'));
329 + return $order_id;
330 + }
548 331
549 - return;
550 - }
551 - }
332 + public function create_payment_intent(){
552 333
553 - $cancel_url = $is_order_pay
554 - ? esc_url_raw($order->get_checkout_payment_url())
555 - : esc_url_raw($order->get_cancel_order_url_raw());
334 + $order_id = $_POST["order_id"];
335 + $this->gateway = $this->get_payplug_gateway($_POST['gateway']);
336 + $order = wc_get_order($order_id);
337 + $customer_id = PayplugWoocommerceHelper::is_pre_30() ? $order->customer_user : $order->get_customer_id();
338 + $return_url = esc_url_raw($order->get_checkout_order_received_url());
339 + $address_data = PayplugAddressData::from_order($order);
340 + $amount = (int) PayplugWoocommerceHelper::get_payplug_amount($order->get_total());
341 + $amount = $this->gateway->validate_order_amount($amount);
556 342
557 - $customer_id = PayplugWoocommerceHelper::is_pre_30() ? $order->customer_user : $order->get_customer_id();
558 - $return_url = esc_url_raw($order->get_checkout_order_received_url());
559 - $address_data = PayplugAddressData::from_order($order);
560 - $amount = (int) PayplugWoocommerceHelper::get_payplug_amount($order->get_total());
561 - $amount = $this->gateway->validate_order_amount($amount);
343 + $payment_data = [
344 + 'amount' => $amount,
345 + 'currency' => get_woocommerce_currency(),
346 + 'allow_save_card' => $this->gateway->oneclick_available() && (int) $customer_id > 0,
347 + 'billing' => $address_data->get_billing(),
348 + 'shipping' => $address_data->get_shipping(),
349 + 'hosted_payment' => [
350 + 'return_url' => $return_url,
351 + ],
352 + 'notification_url' => esc_url_raw(WC()->api_request_url('PayplugGateway')),
353 + 'metadata' => [
354 + 'order_id' => $order_id,
355 + 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
356 + 'domain' => $this->limit_length(esc_url_raw(home_url()), 500),
357 + ],
358 + ];
562 359
563 - $payment_data = [
564 - 'amount' => $amount,
565 - 'currency' => get_woocommerce_currency(),
566 - 'allow_save_card' => $this->gateway->save_card_available() && (int) $customer_id > 0,
567 - 'billing' => $address_data->get_billing(),
568 - 'shipping' => $address_data->get_shipping(),
569 - 'hosted_payment' => [
570 - 'return_url' => $return_url,
571 - ],
572 - 'notification_url' => esc_url_raw(WC()->api_request_url('PayplugGateway')),
573 - 'metadata' => [
574 - 'order_id' => $order_id,
575 - 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
576 - 'domain' => $this->limit_length(esc_url_raw(home_url()), 500),
577 - ],
578 - ];
360 + if($this->gateway->id === "apple_pay"){
361 + unset($payment_data["allow_save_card"]);
579 362
580 - if (PayplugWoocommerceHelper::is_checkout_block() && is_checkout()) {
581 - $payment_data['metadata']['woocommerce_block'] = 'CHECKOUT';
582 - } elseif (PayplugWoocommerceHelper::is_cart_block() && is_cart()) {
583 - $payment_data['metadata']['woocommerce_block'] = 'CART';
584 - }
363 + $payment_data["payment_method"] = $this->gateway->id;
364 + $payment_data["payment_context"] = array(
365 + 'apple_pay' => array(
366 + 'domain_name' => $this->gateway->domain_name,
367 + 'application_data' => base64_encode(json_encode(array(
368 + 'apple_pay_domain' => $this->gateway->domain_name,
369 + )))
370 + )
371 + );
372 + $payment_data["hosted_payment"]["cancel_url"] = esc_url_raw($order->get_cancel_order_url_raw());
373 + $payment_data["metadata"]["applepay_workflow"] = "checkout";
374 + }
585 375
586 - if ($this->gateway->id === 'apple_pay') {
587 - unset($payment_data['allow_save_card']);
376 + if($this->gateway->payment_method === 'integrated' && $this->gateway->id === "payplug") {
377 + $payment_data['initiator'] = 'PAYER';
378 + $payment_data['integration'] = 'INTEGRATED_PAYMENT';
379 + unset($payment_data['hosted_payment']['cancel_url']);
380 + }
588 381
589 - $payment_data['payment_method'] = $this->gateway->id;
590 - $payment_data['payment_context'] = [
591 - 'apple_pay' => [
592 - 'domain_name' => $this->gateway->domain_name,
593 - 'application_data' => base64_encode(json_encode([
594 - 'apple_pay_domain' => $this->gateway->domain_name,
595 - ])),
596 - ],
597 - ];
598 - $payment_data['hosted_payment']['cancel_url'] = $cancel_url;
599 - $payment_data['metadata']['applepay_workflow'] = 'checkout';
600 - }
382 + if($this->gateway->payment_method === 'popup' && $this->gateway->id === "american_express") {
383 + $payment_data['payment_method'] = $this->gateway->id;
384 + }
601 385
602 - $method = $this->get_configuration()->get_option('payment_methods.configuration.payplug.embedded_mode');
386 + /**
387 + * Filter the payment data before it's used
388 + *
389 + * @param array $payment_data
390 + * @param int $order_id
391 + * @param array $customer_details
392 + * @param PayplugAddressData $address_data
393 + */
394 + $payment_data = apply_filters('payplug_gateway_payment_data', $payment_data, $order_id, [], $address_data);
603 395
604 - if ('integrated' == $method && $this->gateway->id === 'payplug') {
605 - $payment_data['initiator'] = 'PAYER';
606 - $payment_data['integration'] = 'INTEGRATED_PAYMENT';
607 - unset($payment_data['hosted_payment']['cancel_url']);
608 - }
396 + /**
397 + *
398 + */
399 + $payment = $this->gateway->api->payment_create($payment_data);
609 400
610 - if ('popup' == $method && $this->gateway->id === 'american_express') {
611 - $payment_data['payment_method'] = $this->gateway->id;
612 - }
401 + // Save transaction id on the order
402 + PayplugWoocommerceHelper::is_pre_30() ? update_post_meta($order_id, '_transaction_id', $payment->id) : $order->set_transaction_id($payment->id);
613 403
614 - /**
615 - * Filter the payment data before it's used
616 - *
617 - * @param array $payment_data
618 - * @param int $order_id
619 - * @param array $customer_details
620 - * @param PayplugAddressData $address_data
621 - */
622 - $payment_data = apply_filters('payplug_gateway_payment_data', $payment_data, $order_id, [], $address_data);
404 + if (is_callable([$order, 'save'])) {
405 + $order->save();
406 + }
623 407
624 - try {
625 - $payment = $this->gateway->payplug_api->payment_create($payment_data);
626 - } catch (HttpException $e) {
627 - PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
628 - wp_send_json_error(__('Payment processing failed. Please retry.', 'payplug'));
408 + $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
409 + PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
629 410
630 - return;
631 - } catch (\Exception $e) {
632 - PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
633 - wp_send_json_error(__('Payment processing failed. Please retry.', 'payplug'));
411 + wp_send_json_success(array(
412 + 'payment_id' => $payment->id,
413 + 'merchant_session' => isset($payment->payment_method["merchant_session"]) ? $payment->payment_method["merchant_session"]: null,
414 + 'redirect' => !empty($payment->hosted_payment->payment_url) ? $payment->hosted_payment->payment_url : $return_url,
415 + 'cancel' => esc_url_raw($order->get_cancel_order_url_raw())
416 + ));
417 + }
634 418
635 - return;
636 - }
637 419
638 - // Save transaction id on the order
639 - PayplugWoocommerceHelper::is_pre_30() ? update_post_meta($order_id, '_transaction_id', $payment->id) : $order->set_transaction_id($payment->id);
420 + /**
421 + * Returns an instantiated gateway.
422 + * @return PayplugGateway
423 + */
424 + protected function get_payplug_gateway($id) {
425 + if ( ! isset( $this->gateway ) ) {
426 + $gateways = WC()->payment_gateways()->payment_gateways();
427 + foreach($gateways as $gateway){
428 + if($gateway->id === $id){
429 + return $gateway;
430 + }
431 + }
432 + }
433 + }
640 434
641 - if (is_callable([$order, 'save'])) {
642 - $order->save();
643 - }
644 435
645 - $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
646 - PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
647 -
648 - wp_send_json_success([
649 - 'payment_id' => $payment->id,
650 - 'merchant_session' => isset($payment->payment_method['merchant_session']) ? $payment->payment_method['merchant_session'] : null,
651 - 'redirect' => !empty($payment->hosted_payment->payment_url) ? $payment->hosted_payment->payment_url : $return_url,
652 - 'cancel' => $cancel_url,
653 - ]);
654 - }
655 -
656 - /**
657 - * Returns an instantiated gateway.
658 - *
659 - * @return PayplugGateway
660 - */
661 - protected function get_payplug_gateway($id)
662 - {
663 - if (!isset($this->gateway)) {
664 - $gateways = WC()->payment_gateways()->payment_gateways();
665 - foreach ($gateways as $gateway) {
666 - if ($gateway->id === $id) {
667 - return $gateway;
668 - }
669 - }
670 - }
671 - }
672 436 }