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/PayplugWoocommerceHelper.php +885 -469 1.2.2 → 3.1.0 View file →
@@ -2,515 +2,931 @@
2 2
3 3 namespace Payplug\PayplugWoocommerce;
4 4
5 5 // Exit if accessed directly
6 -if ( ! defined( 'ABSPATH' ) ) {
7 - exit;
6 +if (!defined('ABSPATH')) {
7 + exit;
8 8 }
9 9
10 -use Payplug\Resource\APIResource;
10 +use Payplug\Authentication;
11 +use Payplug\Exception\ForbiddenException;
11 12 use Payplug\Payplug;
12 -use Payplug\Authentication;
13 +use Payplug\PayplugWoocommerce\Gateway\PayplugGateway;
14 +use Payplug\PayplugWoocommerce\Gateway\PayplugGatewayOney3x;
13 15 use Payplug\PayplugWoocommerce\Gateway\PayplugPermissions;
16 +use Payplug\PayplugWoocommerce\Traits\ServiceGetter;
17 +use Payplug\Resource\APIResource;
18 +use WC_Blocks_Utils;
19 +use WC_Subscriptions;
14 20
15 21 /**
16 22 * Helper class.
17 - *
18 - * @package Payplug\PayplugWoocommerce
19 23 */
20 -class PayplugWoocommerceHelper {
24 +class PayplugWoocommerceHelper
25 +{
26 + use ServiceGetter;
21 27
22 - /**
23 - * Check if current WooCommerce version is below 3.0.0
24 - *
25 - * @return bool
26 - */
27 - public static function is_pre_30() {
28 - $wc = function_exists( 'WC' ) ? WC() : $GLOBALS['woocommerce'];
28 + /**
29 + * Check if current WooCommerce version is below 3.0.0
30 + *
31 + * @return bool
32 + */
33 + public static function is_pre_30()
34 + {
35 + $wc = function_exists('WC') ? WC() : $GLOBALS['woocommerce'];
29 36
30 - return version_compare( $wc->version, '3.0.0', '<' );
31 - }
37 + return version_compare($wc->version, '3.0.0', '<');
38 + }
32 39
33 - /**
34 - * Get a URL to the PayPlug gateway settings page.
35 - *
36 - * @return string
37 - */
38 - public static function get_setting_link() {
39 - $use_id_as_section = function_exists( 'WC' ) ? version_compare( WC()->version, '2.6', '>=' ) : false;
40 - $section_slug = $use_id_as_section ? 'payplug' : strtolower( 'PayplugGateway' );
40 + /**
41 + * Get a URL to the PayPlug gateway settings page.
42 + *
43 + * @return string
44 + */
45 + public static function get_setting_link()
46 + {
47 + $use_id_as_section = function_exists('WC') ? version_compare(WC()->version, '2.6', '>=') : false;
48 + $section_slug = $use_id_as_section ? 'payplug' : strtolower('PayplugGateway');
41 49
42 - return admin_url( 'admin.php?page=wc-settings&tab=checkout&section=' . $section_slug );
43 - }
50 + return admin_url('admin.php?page=wc-settings&tab=checkout&section=' . $section_slug);
51 + }
44 52
45 - /**
46 - * Get all country code supported by PayPlug.
47 - *
48 - * Those are ISO 3166-1 alpha-2. You can find more information on https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
49 - *
50 - * @return array
51 - */
52 - public static function get_supported_countries() {
53 - return [
54 - 'AD',
55 - 'AO',
56 - 'AX',
57 - 'BG',
58 - 'BO',
59 - 'BY',
60 - 'CH',
61 - 'CR',
62 - 'DE',
63 - 'EE',
64 - 'FI',
65 - 'GB',
66 - 'GL',
67 - 'GT',
68 - 'HR',
69 - 'IN',
70 - 'JM',
71 - 'KM',
72 - 'KZ',
73 - 'LS',
74 - 'MD',
75 - 'MM',
76 - 'MT',
77 - 'NA',
78 - 'NO',
79 - 'PE',
80 - 'PN',
81 - 'RE',
82 - 'SC',
83 - 'SK',
84 - 'ST',
85 - 'TF',
86 - 'TN',
87 - 'UA',
88 - 'VC',
89 - 'WS',
90 - 'AE',
91 - 'AQ',
92 - 'AZ',
93 - 'BH',
94 - 'BQ',
95 - 'BZ',
96 - 'CI',
97 - 'CU',
98 - 'DJ',
99 - 'EG',
100 - 'FJ',
101 - 'GD',
102 - 'GM',
103 - 'GU',
104 - 'HT',
105 - 'IO',
106 - 'JO',
107 - 'KN',
108 - 'LA',
109 - 'LT',
110 - 'ME',
111 - 'MN',
112 - 'MU',
113 - 'NC',
114 - 'NP',
115 - 'PF',
116 - 'PR',
117 - 'RO',
118 - 'SD',
119 - 'SL',
120 - 'SV',
121 - 'TG',
122 - 'TO',
123 - 'UG',
124 - 'VE',
125 - 'YE',
126 - 'AM',
127 - 'AW',
128 - 'BF',
129 - 'BN',
130 - 'BW',
131 - 'CG',
132 - 'CO',
133 - 'AF',
134 - 'CZ',
135 - 'EC',
136 - 'EU',
137 - 'GA',
138 - 'GI',
139 - 'GS',
140 - 'HN',
141 - 'IM',
142 - 'JE',
143 - 'KI',
144 - 'KY',
145 - 'LR',
146 - 'MC',
147 - 'ML',
148 - 'MS',
149 - 'MZ',
150 - 'NL',
151 - 'PA',
152 - 'PM',
153 - 'QA',
154 - 'SB',
155 - 'SJ',
156 - 'SS',
157 - 'TD',
158 - 'TM',
159 - 'TZ',
160 - 'VA',
161 - 'WF',
162 - 'AR',
163 - 'BA',
164 - 'BI',
165 - 'BR',
166 - 'CA',
167 - 'CK',
168 - 'CV',
169 - 'DK',
170 - 'EH',
171 - 'FK',
172 - 'GE',
173 - 'GN',
174 - 'GW',
175 - 'HU',
176 - 'IQ',
177 - 'JP',
178 - 'KP',
179 - 'LB',
180 - 'LU',
181 - 'MF',
182 - 'MO',
183 - 'MV',
184 - 'NE',
185 - 'NR',
186 - 'PG',
187 - 'PS',
188 - 'RS',
189 - 'SE',
190 - 'SM',
191 - 'SX',
192 - 'TH',
193 - 'TR',
194 - 'UM',
195 - 'VG',
196 - 'YT',
197 - 'AL',
198 - 'AU',
199 - 'BE',
200 - 'BM',
201 - 'BV',
202 - 'CF',
203 - 'CN',
204 - 'CY',
205 - 'DZ',
206 - 'ET',
207 - 'FR',
208 - 'GH',
209 - 'GR',
210 - 'HM',
211 - 'IL',
212 - 'IT',
213 - 'KH',
214 - 'KW',
215 - 'LK',
216 - 'MA',
217 - 'MK',
218 - 'MR',
219 - 'MY',
220 - 'NI',
221 - 'OM',
222 - 'PL',
223 - 'PY',
224 - 'SA',
225 - 'SI',
226 - 'SR',
227 - 'TC',
228 - 'TL',
229 - 'TW',
230 - 'UZ',
231 - 'VU',
232 - 'ZW',
233 - 'AI',
234 - 'AT',
235 - 'BD',
236 - 'BL',
237 - 'BT',
238 - 'CD',
239 - 'CM',
240 - 'CX',
241 - 'DO',
242 - 'ES',
243 - 'FO',
244 - 'GG',
245 - 'GQ',
246 - 'HK',
247 - 'IE',
248 - 'IS',
249 - 'KG',
250 - 'KS',
251 - 'LI',
252 - 'LY',
253 - 'MH',
254 - 'MQ',
255 - 'MX',
256 - 'NG',
257 - 'NZ',
258 - 'PK',
259 - 'PW',
260 - 'RW',
261 - 'SH',
262 - 'SO',
263 - 'SZ',
264 - 'TK',
265 - 'TV',
266 - 'UY',
267 - 'VN',
268 - 'ZM',
269 - 'AG',
270 - 'AS',
271 - 'BB',
272 - 'BJ',
273 - 'BS',
274 - 'CC',
275 - 'CL',
276 - 'CW',
277 - 'DM',
278 - 'ER',
279 - 'FM',
280 - 'GF',
281 - 'GP',
282 - 'GY',
283 - 'ID',
284 - 'IR',
285 - 'KE',
286 - 'KR',
287 - 'LC',
288 - 'LV',
289 - 'MG',
290 - 'MP',
291 - 'MW',
292 - 'NF',
293 - 'NU',
294 - 'PH',
295 - 'PT',
296 - 'RU',
297 - 'SG',
298 - 'SN',
299 - 'SY',
300 - 'TJ',
301 - 'TT',
302 - 'US',
303 - 'VI',
304 - 'ZA'
305 - ];
306 - }
53 + /**
54 + * Get all country code supported by PayPlug.
55 + *
56 + * Those are ISO 3166-1 alpha-2. You can find more information on https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
57 + *
58 + * @return array
59 + */
60 + public static function get_supported_countries()
61 + {
62 + return [
63 + 'AD',
64 + 'AO',
65 + 'AX',
66 + 'BG',
67 + 'BO',
68 + 'BY',
69 + 'CH',
70 + 'CR',
71 + 'DE',
72 + 'EE',
73 + 'FI',
74 + 'GB',
75 + 'GL',
76 + 'GT',
77 + 'HR',
78 + 'IN',
79 + 'JM',
80 + 'KM',
81 + 'KZ',
82 + 'LS',
83 + 'MD',
84 + 'MM',
85 + 'MT',
86 + 'NA',
87 + 'NO',
88 + 'PE',
89 + 'PN',
90 + 'RE',
91 + 'SC',
92 + 'SK',
93 + 'ST',
94 + 'TF',
95 + 'TN',
96 + 'UA',
97 + 'VC',
98 + 'WS',
99 + 'AE',
100 + 'AQ',
101 + 'AZ',
102 + 'BH',
103 + 'BQ',
104 + 'BZ',
105 + 'CI',
106 + 'CU',
107 + 'DJ',
108 + 'EG',
109 + 'FJ',
110 + 'GD',
111 + 'GM',
112 + 'GU',
113 + 'HT',
114 + 'IO',
115 + 'JO',
116 + 'KN',
117 + 'LA',
118 + 'LT',
119 + 'ME',
120 + 'MN',
121 + 'MU',
122 + 'NC',
123 + 'NP',
124 + 'PF',
125 + 'PR',
126 + 'RO',
127 + 'SD',
128 + 'SL',
129 + 'SV',
130 + 'TG',
131 + 'TO',
132 + 'UG',
133 + 'VE',
134 + 'YE',
135 + 'AM',
136 + 'AW',
137 + 'BF',
138 + 'BN',
139 + 'BW',
140 + 'CG',
141 + 'CO',
142 + 'AF',
143 + 'CZ',
144 + 'EC',
145 + 'EU',
146 + 'GA',
147 + 'GI',
148 + 'GS',
149 + 'HN',
150 + 'IM',
151 + 'JE',
152 + 'KI',
153 + 'KY',
154 + 'LR',
155 + 'MC',
156 + 'ML',
157 + 'MS',
158 + 'MZ',
159 + 'NL',
160 + 'PA',
161 + 'PM',
162 + 'QA',
163 + 'SB',
164 + 'SJ',
165 + 'SS',
166 + 'TD',
167 + 'TM',
168 + 'TZ',
169 + 'VA',
170 + 'WF',
171 + 'AR',
172 + 'BA',
173 + 'BI',
174 + 'BR',
175 + 'CA',
176 + 'CK',
177 + 'CV',
178 + 'DK',
179 + 'EH',
180 + 'FK',
181 + 'GE',
182 + 'GN',
183 + 'GW',
184 + 'HU',
185 + 'IQ',
186 + 'JP',
187 + 'KP',
188 + 'LB',
189 + 'LU',
190 + 'MF',
191 + 'MO',
192 + 'MV',
193 + 'NE',
194 + 'NR',
195 + 'PG',
196 + 'PS',
197 + 'RS',
198 + 'SE',
199 + 'SM',
200 + 'SX',
201 + 'TH',
202 + 'TR',
203 + 'UM',
204 + 'VG',
205 + 'YT',
206 + 'AL',
207 + 'AU',
208 + 'BE',
209 + 'BM',
210 + 'BV',
211 + 'CF',
212 + 'CN',
213 + 'CY',
214 + 'DZ',
215 + 'ET',
216 + 'FR',
217 + 'GH',
218 + 'GR',
219 + 'HM',
220 + 'IL',
221 + 'IT',
222 + 'KH',
223 + 'KW',
224 + 'LK',
225 + 'MA',
226 + 'MK',
227 + 'MR',
228 + 'MY',
229 + 'NI',
230 + 'OM',
231 + 'PL',
232 + 'PY',
233 + 'SA',
234 + 'SI',
235 + 'SR',
236 + 'TC',
237 + 'TL',
238 + 'TW',
239 + 'UZ',
240 + 'VU',
241 + 'ZW',
242 + 'AI',
243 + 'AT',
244 + 'BD',
245 + 'BL',
246 + 'BT',
247 + 'CD',
248 + 'CM',
249 + 'CX',
250 + 'DO',
251 + 'ES',
252 + 'FO',
253 + 'GG',
254 + 'GQ',
255 + 'HK',
256 + 'IE',
257 + 'IS',
258 + 'KG',
259 + 'KS',
260 + 'LI',
261 + 'LY',
262 + 'MH',
263 + 'MQ',
264 + 'MX',
265 + 'NG',
266 + 'NZ',
267 + 'PK',
268 + 'PW',
269 + 'RW',
270 + 'SH',
271 + 'SO',
272 + 'SZ',
273 + 'TK',
274 + 'TV',
275 + 'UY',
276 + 'VN',
277 + 'ZM',
278 + 'AG',
279 + 'AS',
280 + 'BB',
281 + 'BJ',
282 + 'BS',
283 + 'CC',
284 + 'CL',
285 + 'CW',
286 + 'DM',
287 + 'ER',
288 + 'FM',
289 + 'GF',
290 + 'GP',
291 + 'GY',
292 + 'ID',
293 + 'IR',
294 + 'KE',
295 + 'KR',
296 + 'LC',
297 + 'LV',
298 + 'MG',
299 + 'MP',
300 + 'MW',
301 + 'NF',
302 + 'NU',
303 + 'PH',
304 + 'PT',
305 + 'RU',
306 + 'SG',
307 + 'SN',
308 + 'SY',
309 + 'TJ',
310 + 'TT',
311 + 'US',
312 + 'VI',
313 + 'ZA',
314 + ];
315 + }
307 316
308 - /**
309 - * Ensure country code is supported by PayPlug.
310 - *
311 - * @param string $country The ISO 3166-1 alpha-2 code for the country
312 - *
313 - * @return bool
314 - * @author Clément Boirie
315 - */
316 - public static function is_country_supported( $country ) {
317 - $country = trim( $country );
318 - if ( empty( $country ) ) {
319 - return false;
320 - }
317 + /**
318 + * Ensure country code is supported by PayPlug.
319 + *
320 + * @param string $country The ISO 3166-1 alpha-2 code for the country
321 + *
322 + * @return bool
323 + *
324 + * @author Clément Boirie
325 + */
326 + public static function is_country_supported($country)
327 + {
328 + $country = trim($country);
329 + if (empty($country)) {
330 + return false;
331 + }
321 332
322 - return in_array( strtoupper( $country ), self::get_supported_countries() );
323 - }
333 + return in_array(strtoupper($country), self::get_supported_countries());
334 + }
324 335
325 - /**
326 - * Get default country.
327 - *
328 - * @return string
329 - */
330 - public static function get_default_country() {
331 - $country = \WC()->countries->get_base_country();
336 + /**
337 + * Get default country.
338 + *
339 + * @return string
340 + */
341 + public static function get_default_country()
342 + {
343 + $country = \WC()->countries->get_base_country();
332 344
333 - return ( self::is_country_supported( $country ) ) ? strtoupper( $country ) : 'FR';
334 - }
345 + return (self::is_country_supported($country)) ? strtoupper($country) : 'FR';
346 + }
335 347
336 - /**
337 - * Get minimum amount allowed by PayPlug.
338 - *
339 - * This amount is in cents.
340 - *
341 - * @return int
342 - */
343 - public static function get_minimum_amount() {
344 - return 99;
345 - }
348 + /**
349 + * Get minimum amount allowed by PayPlug.
350 + *
351 + * This amount is in cents.
352 + *
353 + * @return int
354 + */
355 + public static function get_minimum_amount()
356 + {
357 + return 99;
358 + }
346 359
347 - /**
348 - * Get maximum amount allowed by PayPlug.
349 - *
350 - * This amount is in cents.
351 - *
352 - * @return int
353 - */
354 - public static function get_maximum_amount() {
355 - return 2000000;
356 - }
360 + /**
361 + * Get maximum amount allowed by PayPlug.
362 + *
363 + * This amount is in cents.
364 + *
365 + * @return int
366 + */
367 + public static function get_maximum_amount()
368 + {
369 + return 2000000;
370 + }
357 371
358 - /**
359 - * Convert amount in cents.
360 - *
361 - * @param float $amount
362 - *
363 - * @return int
364 - */
365 - public static function get_payplug_amount( $amount ) {
366 - if ( is_null( $amount ) ) {
367 - return $amount;
368 - }
372 + /**
373 + * Convert amount in cents.
374 + *
375 + * @param float $amount
376 + *
377 + * @return int
378 + */
379 + public static function get_payplug_amount($amount)
380 + {
381 + if (is_null($amount)) {
382 + return $amount;
383 + }
369 384
370 - return absint( wc_format_decimal( ( (float) $amount * 100 ), wc_get_price_decimals() ) );
371 - }
385 + return absint(wc_format_decimal(((float) $amount * 100), wc_get_price_decimals()));
386 + }
372 387
373 - /**
374 - * Extract useful metadata from PayPlug response.
375 - *
376 - * @param APIResource $resource
377 - *
378 - * @return array
379 - */
380 - public static function extract_transaction_metadata( $resource ) {
381 - return [
382 - 'transaction_id' => sanitize_text_field( $resource->id ),
383 - 'paid' => (bool) $resource->is_paid,
384 - 'refunded' => (bool) $resource->is_refunded,
385 - 'amount' => sanitize_text_field( $resource->amount ),
386 - 'amount_refunded' => sanitize_text_field( $resource->amount_refunded ),
387 - '3ds' => (bool) $resource->is_3ds,
388 - 'live' => (bool) $resource->is_live,
389 - 'paid_at' => isset( $resource->hosted_payment->paid_at ) ? sanitize_text_field( $resource->hosted_payment->paid_at ) : sanitize_text_field( $resource->created_at ),
390 - 'card_last4' => sanitize_text_field( $resource->card->last4 ),
391 - 'card_exp_month' => sanitize_text_field( $resource->card->exp_month ),
392 - 'card_exp_year' => sanitize_text_field( $resource->card->exp_year ),
393 - 'card_brand' => sanitize_text_field( $resource->card->brand ),
394 - 'card_country' => sanitize_text_field( $resource->card->country ),
395 - ];
396 - }
388 + /**
389 + * Extract useful metadata from PayPlug response.
390 + *
391 + * @param APIResource $resource
392 + *
393 + * @return array
394 + */
395 + public static function extract_transaction_metadata($resource)
396 + {
397 + // For non-card payment methods (e.g. Oney), the API returns "card": null.
398 + // Accessing null->property throws \Error in PHP 8+, which is not caught by catch(\Exception).
399 + $card = (isset($resource->card) && $resource->card !== null) ? $resource->card : null;
397 400
398 - /**
399 - * @param \WC_Order $order
400 - *
401 - * @return array|bool
402 - * @author Clément Boirie
403 - */
404 - public static function get_transaction_metadata( $order ) {
401 + return [
402 + 'transaction_id' => sanitize_text_field($resource->id),
403 + 'paid' => (bool) $resource->is_paid,
404 + 'refunded' => (bool) $resource->is_refunded,
405 + 'amount' => sanitize_text_field($resource->amount),
406 + 'amount_refunded' => sanitize_text_field($resource->amount_refunded),
407 + '3ds' => (bool) $resource->is_3ds,
408 + 'live' => (bool) $resource->is_live,
409 + 'paid_at' => isset($resource->hosted_payment->paid_at) ? sanitize_text_field($resource->hosted_payment->paid_at) : sanitize_text_field($resource->created_at),
410 + 'card_last4' => $card !== null ? sanitize_text_field($card->last4) : '',
411 + 'card_exp_month' => $card !== null ? sanitize_text_field($card->exp_month) : '',
412 + 'card_exp_year' => $card !== null ? sanitize_text_field($card->exp_year) : '',
413 + 'card_brand' => $card !== null ? sanitize_text_field($card->brand) : '',
414 + 'card_country' => $card !== null ? sanitize_text_field($card->country) : '',
415 + ];
416 + }
405 417
406 - if ( PayplugWoocommerceHelper::is_pre_30() ) {
407 - return get_post_meta( $order->id, '_payplug_metadata', true );
408 - } else {
409 - return $order->get_meta( '_payplug_metadata', true );
410 - }
411 - }
418 + /**
419 + * @param \WC_Order $order
420 + *
421 + * @return array|bool
422 + *
423 + * @author Clément Boirie
424 + */
425 + public static function get_transaction_metadata($order)
426 + {
427 + if (self::is_pre_30()) {
428 + return get_post_meta($order->id, '_payplug_metadata', true);
429 + } else {
430 + return $order->get_meta('_payplug_metadata', true);
431 + }
432 + }
412 433
413 - /**
414 - * Save transaction metadata extracted from PayPlug response.
415 - *
416 - * @param \WC_Order $order
417 - * @param array $metadata
418 - *
419 - * @return void
420 - */
421 - public static function save_transaction_metadata( $order, $metadata ) {
434 + /**
435 + * Save transaction metadata extracted from PayPlug response.
436 + *
437 + * @param \WC_Order $order
438 + * @param array $metadata
439 + *
440 + * @return void
441 + */
442 + public static function save_transaction_metadata($order, $metadata): void
443 + {
444 + if (self::is_pre_30()) {
445 + update_post_meta($order->id, '_payplug_metadata', $metadata);
446 + } else {
447 + $order->add_meta_data('_payplug_metadata', $metadata, true);
448 + $order->save_meta_data();
449 + }
450 + }
422 451
423 - if ( PayplugWoocommerceHelper::is_pre_30() ) {
424 - update_post_meta( $order->id, '_payplug_metadata', $metadata );
425 - } else {
426 - $order->add_meta_data( '_payplug_metadata', $metadata, true );
452 + /**
453 + * Set flag ipn ( in progress / over ) on order
454 + *
455 + * @param \WC_Order $order
456 + * @param array $metadata
457 + * @param bool $flag
458 + *
459 + * @return void
460 + */
461 + public static function set_flag_ipn_order($order, $metadata, $flag): void
462 + {
463 + $metadata['transaction_in_progress'] = $flag;
464 + self::save_transaction_metadata($order, $metadata);
465 + }
427 466
428 - if ( is_callable( [ $order, 'save' ] ) ) {
429 - $order->save();
430 - }
431 - }
432 - }
467 + /**
468 + * Get transient key from payplug option
469 + *
470 + * @return string
471 + */
472 + public static function get_transient_key($options)
473 + {
474 + $transient_key = PayplugGateway::OPTION_NAME . (array_key_exists('mode', $options) && (bool) $options['mode'] ? '_live' : '_test');
433 475
434 - /**
435 - * Get current option from payplug settings
436 - *
437 - * @return array
438 - */
439 - public static function get_account_data_from_options() {
440 - $options = get_option( 'woocommerce_payplug_settings', [] );
441 - $payplug_test_key = ! empty( $options['payplug_test_key'] ) ? $options['payplug_test_key'] : '';
442 - $payplug_live_key = ! empty( $options['payplug_live_key'] ) ? $options['payplug_live_key'] : '';
443 - if(empty($payplug_test_key) && empty($payplug_live_key)) {
444 - return array();
445 - }
446 - $account = Authentication::getAccount(new Payplug($options['mode'] === 'yes' ? $payplug_live_key : $payplug_test_key));
447 - $account['oney'] = $options['oney'];
448 - $account['oneycgv'] = $options['oneycgv'];
449 - return $account;
450 - }
476 + return $transient_key;
477 + }
451 478
452 - /**
453 - * Get min and max for oney payment
454 - *
455 - * @return array
456 - */
457 - public static function get_min_max_oney() {
458 - $account = self::get_account_data_from_options();
459 - if (empty($account)) {
460 - return array();
461 - }
462 - return [
463 - 'min' => floatval($account['httpResponse']['configuration']['oney']['min_amounts']['EUR'])/100,
464 - 'max' => floatval($account['httpResponse']['configuration']['oney']['max_amounts']['EUR'])/100
465 - ];
466 - }
479 + /**
480 + * Get transient live key from payplug option
481 + *
482 + * @return string
483 + */
484 + public static function get_live_transient_key()
485 + {
486 + return PayplugGateway::OPTION_NAME . '_live';
487 + }
467 488
468 - /**
469 - * Check if oney is available with current settings
470 - *
471 - * @return boolean
472 - */
473 - public static function is_oney_available() {
474 - $account = self::get_account_data_from_options();
475 - if (empty($account)) {
476 - return false;
477 - }
478 - return ($account['httpResponse'] && $account['httpResponse']['permissions'][PayplugPermissions::USE_ONEY] == "1" && $account['oney'] === "yes" && $account['oneycgv'] === "yes");
479 - }
489 + /**
490 + * Set transient data for payplug account
491 + *
492 + * @return string
493 + */
494 + public static function set_transient_data($data, $options = null)
495 + {
496 + $options = $options ? $options : self::get_payplug_options();
497 + $transient_key = self::get_transient_key($options);
498 + set_transient($transient_key, isset($data['httpResponse']) ? $data['httpResponse'] : []);
499 + }
480 500
481 - /**
482 - * Check and update value for oney simulation
483 - *
484 - * @return void
485 - */
486 - public static function oney_simulation_values ($keys_array, &$array) {
487 - foreach($keys_array as $key) {
488 - if (array_key_exists($key, $array)) {
489 - $array[$key]['down_payment_amount'] = floatval($array[$key]['down_payment_amount']) / 100;
490 - foreach ($array[$key]['installments'] as $k => $value) {
491 - $array[$key]['installments'][$k]['amount'] = floatval($value['amount']) / 100;
501 + /**
502 + * Get current option from payplug settings
503 + *
504 + * @return array
505 + */
506 + public static function get_account_data_from_options()
507 + {
508 + $options = self::get_payplug_options();
509 + $transient_key = self::get_transient_key($options);
510 + $account = get_transient($transient_key);
511 +
512 + if (empty($account) || !is_array($account)) {
513 + self::set_account_data_from_options();
514 + $account = get_transient($transient_key);
515 + }
516 +
517 + return $account;
518 + }
519 +
520 + /**
521 + * Get current option from payplug settings
522 + *this should replace get_account_data_from_options
523 + *
524 + * @return array
525 + */
526 + public static function generic_get_account_data_from_options($gateway_id)
527 + {
528 + $options = self::get_payplug_options();
529 + $transient_key = self::get_transient_key($options);
530 + $account = get_transient($transient_key);
531 +
532 + //if transient is empty, it goes and get the permissions for the customer to populate it
533 + if (empty($account) || !is_array($account)) {
534 + self::set_account_data_from_options();
535 + $account = get_transient($transient_key);
536 + }
537 +
538 + if (!empty($account)) {
539 + $helper = new self();
540 + $configuration = $helper->get_service('configuration');
541 + $account['permissions']['payplug'] = $configuration->get_option('payment_methods.configuration.payplug.active');
542 + }
543 +
544 + return $account;
545 + }
546 +
547 + /**
548 + * Set current option from payplug settings and api call
549 + *
550 + * @return void
551 + */
552 + public static function set_account_data_from_options()
553 + {
554 + $helper = new self();
555 + $configuration = $helper->get_service('configuration');
556 + $options = $configuration->get_options();
557 +
558 + if (empty($options) || !isset($options['api_key']) || !isset($options['jwt'])) {
559 + return [];
560 + }
561 +
562 + // get_bearer_token() refreshes the JWT if it's close to expiry (OAuth2 accounts).
563 + $mode = (bool) $options['mode'] ? 'live' : 'test';
564 + $key = (string) $helper->get_api()->get_bearer_token($mode);
565 +
566 + if (empty($key)) {
567 + return [];
568 + }
569 +
570 + try {
571 + $parameters_account = Authentication::getAccount(new Payplug($key));
572 + self::set_transient_data($parameters_account, $options);
573 + } catch (\Payplug\Exception\UnauthorizedException $e) {
574 + self::exception_handler_400_logout($e->getCode(), __('payplug_enable_feature', 'payplug'), sprintf('Account request error from PayPlug API : %s <br><b> ' . __('Successfully logged out.', 'payplug') . '</b>', wc_print_r($e->getMessage(), true)));
575 + } catch (\Payplug\Exception\ConfigurationNotSetException $e) {
576 + } catch (\Payplug\Exception\ForbiddenException $e) {
577 + } catch (\Payplug\Exception\ForbiddenException $e) {
578 + return [];
579 + }
580 + }
581 +
582 + /**
583 + * Check if oney is available with current settings
584 + *
585 + * @return bool
586 + */
587 + public static function is_oney_available()
588 + {
589 + $account = self::get_account_data_from_options();
590 + if (!$account) {
591 + return false;
592 + }
593 +
594 + $options = self::get_payplug_options();
595 + $oney_active = (bool) $options['payment_methods']['configuration']['oney']['active'];
596 +
597 + return $account && $account['permissions'][PayplugPermissions::USE_ONEY] == '1' && $oney_active;
598 + }
599 +
600 + /**
601 + * Hide popup for if country_code != payplug country
602 + * https://payplug-prod.atlassian.net/browse/WOOC-249
603 + *
604 + * @return bool
605 + */
606 + public static function show_oney_popup()
607 + {
608 + $account = self::get_account_data_from_options();
609 + if ($account && $account['permissions'][PayplugPermissions::USE_ONEY] == true && $account['country'] == self::getISOCountryCode()) {
610 + return true;
611 + }
612 +
613 + return false;
614 + }
615 +
616 + /**
617 + * @return bool
618 + */
619 + public static function check_order_max_amount($order_total)
620 + {
621 + if ($order_total < PayplugGatewayOney3x::MIN_AMOUNT || $order_total > PayplugGatewayOney3x::MAX_AMOUNT) {
622 + return false;
623 + }
624 +
625 + return true;
626 + }
627 +
628 + /**
629 + * Load translations from plugin languages folder.
630 + *
631 + * @param string $plugin_rel_path
632 + *
633 + * @return bool
634 + */
635 + public static function load_plugin_textdomain($plugin_rel_path)
636 + {
637 + $domain = 'payplug';
638 +
639 + $locale = apply_filters('plugin_locale', is_admin() ? get_user_locale() : get_locale(), $domain);
640 +
641 + $mofile = $domain . '-' . $locale . '.mo';
642 +
643 + $path = WP_PLUGIN_DIR . '/' . trim($plugin_rel_path, '/');
644 +
645 + return load_textdomain($domain, $path . '/' . $mofile);
646 + }
647 +
648 + public static function getISOCountryCode()
649 + {
650 + preg_match('([a-z-]+)', get_locale(), $country);
651 +
652 + return strtoupper($country[0]);
653 + }
654 +
655 + /**
656 + * Get country of the payplug merchant account and save it to the database
657 + *
658 + * @return string payplug merchant account country
659 + */
660 + public static function get_payplug_merchant_country()
661 + {
662 + $data = self::get_payplug_options();
663 +
664 + //in order to reduce the getAccount calls
665 + if (isset($data['payplug_live_key'])) {
666 + if (!isset($data['payplug_merchant_country'])) {
667 + return self::UpdateCountryOption($data);
668 + }
669 +
670 + return $data['payplug_merchant_country'];
671 + }
672 +
673 + $country = wc_get_base_location();
674 +
675 + return $country['country'];
676 + }
677 +
678 + /**
679 + * Update payplug options and return the country
680 + *
681 + * @param $options
682 + *
683 + * @throws \Payplug\Exception\ConfigurationException
684 + *
685 + * @return string
686 + */
687 + public static function UpdateCountryOption($options)
688 + {
689 + if (!isset($options['api_key'])) {
690 + $options['company_iso'] = 'FR';
691 +
692 + return $options['company_iso'];
693 + }
694 +
695 + try {
696 + $api_key = json_decode($options['api_key'], true);
697 +
698 + //fail safe for non activated account
699 + if ((isset($options['mode'])) && $api_key['test']) {
700 + $key = $options['mode'] && !empty($api_key['live']) ? $api_key['live'] : $api_key['test'];
701 + }
702 +
703 + if (empty($api_key['live'])) {
704 + $options['mode'] = false;
705 + }
706 +
707 + if (isset($key) && !empty($key)) {
708 + $response = self::get_account_data_from_options();
709 + }
710 +
711 + if (isset($response['httpResponse']['country'])) {
712 + $options['company_iso'] = $response['httpResponse']['country'];
713 + update_option('woocommerce_payplug_settings', apply_filters('woocommerce_settings_api_sanitized_fields_payplug', $options));
714 + } else {
715 +
716 + //default value for merchant country
717 + $options['company_iso'] = 'FR';
718 + }
719 + } catch (ForbiddenException $e) {
720 + PayplugGateway::log('Error while getting account : ' . $e->getMessage(), 'error');
721 + \WC_Admin_Settings::add_error($e->getMessage());
722 + $options['company_iso'] = 'FR';
723 + }
724 +
725 + return $options['company_iso'];
726 + }
727 +
728 + public static function get_live_key()
729 + {
730 + // get_bearer_token() refreshes the JWT if it's close to expiry (OAuth2 accounts).
731 + return (new self())->get_api()->get_bearer_token('live');
732 + }
733 +
734 + public static function get_test_key()
735 + {
736 + return (new self())->get_api()->get_bearer_token('test');
737 + }
738 +
739 + public static function check_mode()
740 + {
741 + return self::get_payplug_options()['mode'];
742 + }
743 +
744 + /**
745 + * Domain the Integrated Payment SDK should submit card-tokenization requests to. Depends
746 + * on whether the connected merchant account is QA or production, which is a build-time
747 + * distinction (see SECURE_DOMAIN in payplug-config.php), not something this can derive
748 + * from the Test/Live mode toggle at runtime.
749 + *
750 + * @return string
751 + */
752 + public static function get_secure_domain(): string
753 + {
754 + return SECURE_DOMAIN;
755 + }
756 +
757 + /**
758 + * URL of the official Oney widget loader script. Depends on whether the connected
759 + * merchant account is QA or production, which is a build-time distinction (see
760 + * ONEY_LOADER_URL in payplug-config.php), not something this can derive from the
761 + * Test/Live mode toggle at runtime.
762 + *
763 + * @return string
764 + */
765 + public static function get_oney_loader_url(): string
766 + {
767 + return ONEY_LOADER_URL;
768 + }
769 +
770 + public static function payplug_logout(): void
771 + {
772 + $helper = new self();
773 + $helper->get_service('configuration')->clean_option();
774 + set_transient(self::get_transient_key(self::get_payplug_options()), null);
775 + }
776 +
777 + public static function plugin_deactivation(): void
778 + {
779 + $option_name = 'woocommerce_payplug_settings';
780 + delete_option($option_name);
781 + // for site options in Multisite
782 + delete_site_option($option_name);
783 + \Payplug\PayplugWoocommerce\Model\Lock::delete_lock_table();
784 + }
785 +
786 + public static function available_shipping_methods($carriers = [])
787 + {
788 + // Build enabled shipping methods based on active Zone
789 + $enabled_method_types = [];
790 +
791 + if (class_exists('\\WC_Shipping_Zones')) {
792 + // Regular zones
793 + $zones = \WC_Shipping_Zones::get_zones();
794 + foreach ($zones as $zone) {
795 + $methods = isset($zone['shipping_methods']) ? $zone['shipping_methods'] : [];
796 + foreach ($methods as $m) {
797 + if (!empty($m->enabled)) {
798 + $enabled_method_types[$m->id] = true;
799 + }
492 800 }
493 801 }
802 +
803 + // Locations not covered by zones (zone 0)
804 + $defaultZone = new \WC_Shipping_Zone(0);
805 + foreach ($defaultZone->get_shipping_methods(true) as $m) {
806 + if (!empty($m->enabled)) {
807 + $enabled_method_types[$m->id] = true;
808 + }
809 + }
494 810 }
811 +
812 + $shippings = WC()->shipping()->get_shipping_methods();
813 + $shippings_methods = [];
814 +
815 + foreach ($shippings as $shipping) {
816 + // Only keep shipping method types that are currently enabled in at least one zone
817 + if (!isset($enabled_method_types[$shipping->id])) {
818 + continue;
819 + }
820 + $shippings_methods[] = [
821 + 'id_carrier' => $shipping->id,
822 + 'name' => $shipping->method_title,
823 + 'checked' => in_array($shipping->id, $carriers, true),
824 + ];
825 + }
826 +
827 + return $shippings_methods;
495 828 }
496 829
497 - /**
498 - * Load translations from plugin languages folder.
499 - *
500 - * @param string $plugin_rel_path
501 - *
502 - * @return bool
503 - */
504 - public static function load_plugin_textdomain( $plugin_rel_path ) {
830 + public static function get_payplug_options()
831 + {
832 + $helper = new self();
505 833
506 - $domain = 'payplug';
834 + return $helper->get_service('configuration')->get_options();
835 + }
507 836
508 - $locale = apply_filters( 'plugin_locale', is_admin() ? get_user_locale() : get_locale(), $domain );
837 + public static function get_applepay_options()
838 + {
839 + $options = self::get_payplug_options();
840 + $applepay_configuration = $options['payment_methods']['configuration']['apple_pay'];
841 + $applepay_display = json_decode($applepay_configuration['display'], true);
842 + $applepay = [
843 + 'enabled' => (bool) $applepay_configuration['active'],
844 + 'checkout' => (bool) $applepay_display['checkout'],
845 + 'cart' => (bool) $applepay_display['cart'],
846 + 'carriers' => json_decode($applepay_configuration['carriers'], true),
847 + ];
509 848
510 - $mofile = $domain . '-' . $locale . '.mo';
849 + return $applepay;
850 + }
511 851
512 - $path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' );
852 + public static function is_checkout_block()
853 + {
854 + return WC_Blocks_Utils::has_block_in_page(wc_get_page_id('checkout'), 'woocommerce/checkout');
855 + }
513 856
514 - return load_textdomain( $domain, $path . '/' . $mofile );
515 - }
857 + public static function is_cart_block()
858 + {
859 + return WC_Blocks_Utils::has_block_in_page(wc_get_page_id('cart'), 'woocommerce/cart');
860 + }
861 +
862 + public static function is_product_block()
863 + {
864 + return WC_Blocks_Utils::has_block_in_page(wc_get_page_id('product'), 'woocommerce/product');
865 + }
866 +
867 + /**
868 + * Checks if subscriptions are enabled on the site.
869 + *
870 + * @return bool Whether subscriptions is enabled or not.
871 + *
872 + * @since 5.6.0
873 + */
874 + public static function is_subscriptions_enabled()
875 + {
876 + return class_exists('WC_Subscriptions') && class_exists('WC_Subscription') && version_compare(WC_Subscriptions::$version, '2.2.0', '>=');
877 + }
878 +
879 + /**
880 + * Cart has any subscriptions
881 + *
882 + * @return bool
883 + */
884 + public static function is_subscription()
885 + {
886 + if (is_null(WC()->cart)) {
887 + wc_load_cart();
888 + WC()->cart->get_cart_from_session();
889 + }
890 +
891 + if (empty(WC()->cart) || empty(WC()->cart->get_cart())) {
892 + return false;
893 + }
894 +
895 + foreach (WC()->cart->get_cart() as $prod) {
896 + if (empty($prod['product_id'])) {
897 + return false;
898 + }
899 +
900 + $pid = $prod['product_id'];
901 + $product = wc_get_product($pid);
902 +
903 + if ($product->is_type('subscription')) {
904 + return true;
905 + }
906 + }
907 +
908 + return false;
909 + }
910 +
911 + /**
912 + * Handling 400 errors from API (get_account, get_permissions) and return JSON rest response
913 + *
914 + * @param $title
915 + * @param $msg
916 + *
917 + * @return false
918 + */
919 + public static function exception_handler_400_logout($error_code, $title, $msg)
920 + {
921 + if (!empty($error_code) && ($error_code === 401 || $error_code === 403)) {
922 + self::payplug_logout();
923 + wp_send_json_error([
924 + 'title' => $title,
925 + 'msg' => $msg,
926 + 'close' => __('payplug_ok', 'payplug'),
927 + ]);
928 + }
929 +
930 + return false;
931 + }
516 932 }