PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.14
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.14
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / app / Modules / Payments / PaymentHelper.php

PaymentHelper.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.14, at app/Modules/Payments/PaymentHelper.php

1,266 lines 46.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Modules\Payments;
4
5 if (!defined('ABSPATH')) {
6 exit; // Exit if accessed directly.
7 }
8
9 use FluentForm\App\Helpers\Helper;
10 use FluentForm\App\Modules\Form\FormFieldsParser;
11 use FluentForm\App\Services\FormBuilder\ShortCodeParser;
12 use FluentForm\Framework\Helpers\ArrayHelper;
13 use FluentForm\App\Services\Form\SubmissionHandlerService;
14
15 class PaymentHelper
16 {
17 public static function getFormCurrency($formId)
18 {
19 $settings = self::getFormSettings($formId, 'public');
20 return $settings['currency'];
21 }
22
23 public static function formatMoney($amountInCents, $currency)
24 {
25 $currencySettings = self::getCurrencyConfig(false, $currency);
26 $symbol = \html_entity_decode($currencySettings['currency_sign']);
27 $position = $currencySettings['currency_sign_position'];
28 $decimalSeparator = '.';
29 $thousandSeparator = ',';
30 if ($currencySettings['currency_separator'] != 'dot_comma') {
31 $decimalSeparator = ',';
32 $thousandSeparator = '.';
33 }
34 $decimalPoints = 2;
35 if ((int) round($amountInCents) % 100 == 0 && $currencySettings['decimal_points'] == 0) {
36 $decimalPoints = 0;
37 }
38
39 $amount = number_format($amountInCents / 100, $decimalPoints, $decimalSeparator, $thousandSeparator);
40
41 if ('left' === $position) {
42 return $symbol . $amount;
43 } elseif ('left_space' === $position) {
44 return $symbol . ' ' . $amount;
45 } elseif ('right' === $position) {
46 return $amount . $symbol;
47 } elseif ('right_space' === $position) {
48 return $amount . ' ' . $symbol;
49 }
50 return $amount;
51 }
52
53 /**
54 * Check payment settings available or not
55 * @return bool
56 */
57 public static function hasPaymentSettings()
58 {
59 return !!get_option('__fluentform_payment_module_settings');
60 }
61
62 public static function getFormSettings($formId, $scope = 'public')
63 {
64 static $cachedSettings = [];
65
66 if (isset($cachedSettings[$scope . '_' . $formId])) {
67 return $cachedSettings[$scope . '_' . $formId];
68 }
69
70
71 $defaults = [
72 'currency' => '',
73 'push_meta_to_stripe' => 'no',
74 'receipt_email' => self::getFormInput($formId,'input_email'),
75 'customer_name' => self::getFormInput($formId,'input_name'),
76 'customer_address' => self::getFormInput($formId,'address'),
77 'transaction_type' => 'product',
78 'stripe_checkout_methods' => ['card'],
79 'stripe_meta_data' => [
80 [
81 'item_value' => '',
82 'label' => ''
83 ]
84 ],
85 'stripe_account_type' => 'global',
86 'disable_stripe_payment_receipt' => 'no',
87 'stripe_custom_config' => [
88 'payment_mode' => 'live',
89 'publishable_key' => '',
90 'secret_key' => ''
91 ],
92 'custom_paypal_id' => '',
93 'custom_paypal_mode' => 'live',
94 'paypal_account_type' => 'global'
95 ];
96 $settings = Helper::getFormMeta($formId, '_payment_settings', []);
97 $settings = wp_parse_args($settings, $defaults);
98 if (empty($settings['receipt_email'])) {
99 $settings['receipt_email'] = self::getFormInput($formId, 'input_email');
100 }
101 if (empty($settings['customer_name'])) {
102 $name = self::getFormInput($formId, 'input_name');
103 if (!empty($name)) {
104 $settings['customer_name'] = sprintf('{inputs.%s}', $name);
105 }
106 }
107 if (empty($settings['customer_address'])) {
108 $settings['customer_address'] = self::getFormInput($formId, 'address');
109 }
110
111 $globalSettings = self::getPaymentSettings();
112
113 if (!$settings['currency']) {
114 $settings['currency'] = $globalSettings['currency'];
115 }
116
117 if ($scope == 'public') {
118 $settings = wp_parse_args($settings, $globalSettings);
119 }
120
121
122 $cachedSettings[$scope . '_' . $formId] = $settings;
123
124 return $settings;
125
126 }
127
128 public static function getCurrencyConfig($formId = false, $currency = false)
129 {
130 if ($formId) {
131 $settings = self::getFormSettings($formId, 'public');
132 } else {
133 $settings = self::getPaymentSettings();
134 }
135
136 if ($currency) {
137 $settings['currency'] = $currency;
138 }
139
140 $settings = ArrayHelper::only($settings, ['currency', 'currency_sign_position', 'currency_separator', 'decimal_points']);
141
142 $settings['currency_sign'] = self::getCurrencySymbol($settings['currency']);
143 return $settings;
144 }
145
146 public static function getPaymentSettings()
147 {
148 static $paymentSettings;
149 if ($paymentSettings) {
150 return $paymentSettings;
151 }
152
153 $paymentSettings = get_option('__fluentform_payment_module_settings');
154 $defaults = [
155 'status' => 'no',
156 'currency' => 'USD',
157 'currency_sign_position' => 'left',
158 'currency_separator' => 'dot_comma',
159 'decimal_points' => "2",
160 'business_name' => '',
161 'business_logo' => '',
162 'business_address' => '',
163 'debug_log' => 'no',
164 'all_payments_page_id' => '',
165 'receipt_page_id' => '',
166 'user_can_manage_subscription' => 'yes'
167 ];
168
169 $paymentSettings = wp_parse_args($paymentSettings, $defaults);
170
171 return $paymentSettings;
172 }
173
174 public static function updatePaymentSettings($data)
175 {
176 $existingSettings = self::getPaymentSettings();
177 $settings = wp_parse_args($data, $existingSettings);
178 update_option('__fluentform_payment_module_settings', $settings, 'yes');
179
180 return self::getPaymentSettings();
181 }
182
183 /**
184 * https://support.stripe.com/questions/which-currencies-does-stripe-support
185 */
186 public static function getCurrencies()
187 {
188 $currencies = [
189 'AED' => __('United Arab Emirates Dirham', 'fluentform'),
190 'AFN' => __('Afghan Afghani', 'fluentform'),
191 'ALL' => __('Albanian Lek', 'fluentform'),
192 'AMD' => __('Armenian Dram', 'fluentform'),
193 'ANG' => __('Netherlands Antillean Gulden', 'fluentform'),
194 'AOA' => __('Angolan Kwanza', 'fluentform'),
195 'ARS' => __('Argentine Peso','fluentform'), // non amex
196 'AUD' => __('Australian Dollar', 'fluentform'),
197 'AWG' => __('Aruban Florin', 'fluentform'),
198 'AZN' => __('Azerbaijani Manat', 'fluentform'),
199 'BAM' => __('Bosnia & Herzegovina Convertible Mark', 'fluentform'),
200 'BBD' => __('Barbadian Dollar', 'fluentform'),
201 'BDT' => __('Bangladeshi Taka', 'fluentform'),
202 'BIF' => __('Burundian Franc', 'fluentform'),
203 'BGN' => __('Bulgarian Lev', 'fluentform'),
204 'BMD' => __('Bermudian Dollar', 'fluentform'),
205 'BND' => __('Brunei Dollar', 'fluentform'),
206 'BOB' => __('Bolivian Boliviano', 'fluentform'),
207 'BRL' => __('Brazilian Real', 'fluentform'),
208 'BSD' => __('Bahamian Dollar', 'fluentform'),
209 'BWP' => __('Botswana Pula', 'fluentform'),
210 'BZD' => __('Belize Dollar', 'fluentform'),
211 'CAD' => __('Canadian Dollar', 'fluentform'),
212 'CDF' => __('Congolese Franc', 'fluentform'),
213 'CHF' => __('Swiss Franc', 'fluentform'),
214 'CLP' => __('Chilean Peso', 'fluentform'),
215 'CNY' => __('Chinese Renminbi Yuan', 'fluentform'),
216 'COP' => __('Colombian Peso', 'fluentform'),
217 'CRC' => __('Costa Rican Colón', 'fluentform'),
218 'CVE' => __('Cape Verdean Escudo', 'fluentform'),
219 'CZK' => __('Czech Koruna', 'fluentform'),
220 'DJF' => __('Djiboutian Franc', 'fluentform'),
221 'DKK' => __('Danish Krone', 'fluentform'),
222 'DOP' => __('Dominican Peso', 'fluentform'),
223 'DZD' => __('Algerian Dinar', 'fluentform'),
224 'EGP' => __('Egyptian Pound', 'fluentform'),
225 'ETB' => __('Ethiopian Birr', 'fluentform'),
226 'EUR' => __('Euro', 'fluentform'),
227 'FJD' => __('Fijian Dollar', 'fluentform'),
228 'FKP' => __('Falkland Islands Pound', 'fluentform'),
229 'GBP' => __('British Pound', 'fluentform'),
230 'GEL' => __('Georgian Lari', 'fluentform'),
231 'GHS' => __('Ghanaian Cedi', 'fluentform'),
232 'GIP' => __('Gibraltar Pound', 'fluentform'),
233 'GMD' => __('Gambian Dalasi', 'fluentform'),
234 'GNF' => __('Guinean Franc', 'fluentform'),
235 'GTQ' => __('Guatemalan Quetzal', 'fluentform'),
236 'GYD' => __('Guyanese Dollar', 'fluentform'),
237 'HKD' => __('Hong Kong Dollar', 'fluentform'),
238 'HNL' => __('Honduran Lempira', 'fluentform'),
239 'HRK' => __('Croatian Kuna', 'fluentform'),
240 'HTG' => __('Haitian Gourde', 'fluentform'),
241 'HUF' => __('Hungarian Forint', 'fluentform'),
242 'IDR' => __('Indonesian Rupiah', 'fluentform'),
243 'ILS' => __('Israeli New Sheqel', 'fluentform'),
244 'INR' => __('Indian Rupee', 'fluentform'),
245 'ISK' => __('Icelandic Króna', 'fluentform'),
246 'JMD' => __('Jamaican Dollar', 'fluentform'),
247 'JPY' => __('Japanese Yen', 'fluentform'),
248 'KES' => __('Kenyan Shilling', 'fluentform'),
249 'KGS' => __('Kyrgyzstani Som', 'fluentform'),
250 'KHR' => __('Cambodian Riel', 'fluentform'),
251 'KMF' => __('Comorian Franc', 'fluentform'),
252 'KRW' => __('South Korean Won', 'fluentform'),
253 'KYD' => __('Cayman Islands Dollar', 'fluentform'),
254 'KZT' => __('Kazakhstani Tenge', 'fluentform'),
255 'LAK' => __('Lao Kip', 'fluentform'),
256 'LBP' => __('Lebanese Pound', 'fluentform'),
257 'LKR' => __('Sri Lankan Rupee', 'fluentform'),
258 'LRD' => __('Liberian Dollar', 'fluentform'),
259 'LSL' => __('Lesotho Loti', 'fluentform'),
260 'MAD' => __('Moroccan Dirham', 'fluentform'),
261 'MDL' => __('Moldovan Leu', 'fluentform'),
262 'MGA' => __('Malagasy Ariary', 'fluentform'),
263 'MKD' => __('Macedonian Denar', 'fluentform'),
264 'MNT' => __('Mongolian Tögrög', 'fluentform'),
265 'MOP' => __('Macanese Pataca', 'fluentform'),
266 'MRO' => __('Mauritanian Ouguiya', 'fluentform'),
267 'MUR' => __('Mauritian Rupee', 'fluentform'),
268 'MVR' => __('Maldivian Rufiyaa', 'fluentform'),
269 'MWK' => __('Malawian Kwacha', 'fluentform'),
270 'MXN' => __('Mexican Peso', 'fluentform'),
271 'MYR' => __('Malaysian Ringgit', 'fluentform'),
272 'MZN' => __('Mozambican Metical', 'fluentform'),
273 'NAD' => __('Namibian Dollar', 'fluentform'),
274 'NGN' => __('Nigerian Naira', 'fluentform'),
275 'NIO' => __('Nicaraguan Córdoba', 'fluentform'),
276 'NOK' => __('Norwegian Krone', 'fluentform'),
277 'NPR' => __('Nepalese Rupee', 'fluentform'),
278 'NZD' => __('New Zealand Dollar', 'fluentform'),
279 'PAB' => __('Panamanian Balboa', 'fluentform'),
280 'PEN' => __('Peruvian Nuevo Sol', 'fluentform'),
281 'PGK' => __('Papua New Guinean Kina', 'fluentform'),
282 'PHP' => __('Philippine Peso', 'fluentform'),
283 'PKR' => __('Pakistani Rupee', 'fluentform'),
284 'PLN' => __('Polish Złoty', 'fluentform'),
285 'PYG' => __('Paraguayan Guaraní', 'fluentform'),
286 'QAR' => __('Qatari Riyal', 'fluentform'),
287 'RON' => __('Romanian Leu', 'fluentform'),
288 'RSD' => __('Serbian Dinar', 'fluentform'),
289 'RUB' => __('Russian Ruble', 'fluentform'),
290 'RWF' => __('Rwandan Franc', 'fluentform'),
291 'SAR' => __('Saudi Riyal', 'fluentform'),
292 'SBD' => __('Solomon Islands Dollar', 'fluentform'),
293 'SCR' => __('Seychellois Rupee', 'fluentform'),
294 'SEK' => __('Swedish Krona', 'fluentform'),
295 'SGD' => __('Singapore Dollar', 'fluentform'),
296 'SHP' => __('Saint Helenian Pound', 'fluentform'),
297 'SLL' => __('Sierra Leonean Leone', 'fluentform'),
298 'SOS' => __('Somali Shilling', 'fluentform'),
299 'SRD' => __('Surinamese Dollar', 'fluentform'),
300 'STD' => __('São Tomé and Príncipe Dobra', 'fluentform'),
301 'SVC' => __('Salvadoran Colón', 'fluentform'),
302 'SZL' => __('Swazi Lilangeni', 'fluentform'),
303 'THB' => __('Thai Baht', 'fluentform'),
304 'TJS' => __('Tajikistani Somoni', 'fluentform'),
305 'TOP' => __('Tongan Paʻanga', 'fluentform'),
306 'TRY' => __('Turkish Lira', 'fluentform'),
307 'TTD' => __('Trinidad and Tobago Dollar', 'fluentform'),
308 'TWD' => __('New Taiwan Dollar', 'fluentform'),
309 'TZS' => __('Tanzanian Shilling', 'fluentform'),
310 'UAH' => __('Ukrainian Hryvnia', 'fluentform'),
311 'UGX' => __('Ugandan Shilling', 'fluentform'),
312 'USD' => __('United States Dollar', 'fluentform'),
313 'UYU' => __('Uruguayan Peso', 'fluentform'),
314 'UZS' => __('Uzbekistani Som', 'fluentform'),
315 'VND' => __('Vietnamese Đồng', 'fluentform'),
316 'VUV' => __('Vanuatu Vatu', 'fluentform'),
317 'WST' => __('Samoan Tala', 'fluentform'),
318 'XAF' => __('Central African Cfa Franc', 'fluentform'),
319 'XCD' => __('East Caribbean Dollar', 'fluentform'),
320 'XOF' => __('West African Cfa Franc', 'fluentform'),
321 'XPF' => __('Cfp Franc', 'fluentform'),
322 'YER' => __('Yemeni Rial', 'fluentform'),
323 'ZAR' => __('South African Rand', 'fluentform'),
324 'ZMW' => __('Zambian Kwacha', 'fluentform')
325 ];
326
327 $currencies = apply_filters_deprecated(
328 'fluentform_accepted_currencies',
329 [
330 $currencies
331 ],
332 FLUENTFORM_FRAMEWORK_UPGRADE,
333 'fluentform/accepted_currencies',
334 'Use fluentform/accepted_currencies instead of fluentform_accepted_currencies.'
335 );
336
337 return apply_filters('fluentform/accepted_currencies', $currencies);
338 }
339
340 /**
341 * Get a specific currency symbol
342 *
343 * https://support.stripe.com/questions/which-currencies-does-stripe-support
344 */
345 public static function getCurrencySymbol($currency = '')
346 {
347 if (!$currency) {
348 // If no currency is passed then default it to USD
349 $currency = 'USD';
350 }
351 $currency = strtoupper($currency);
352
353 $symbols = self::getCurrencySymbols();
354 $currency_symbol = isset($symbols[$currency]) ? $symbols[$currency] : '';
355
356 $currency_symbol = apply_filters_deprecated(
357 'fluentform_currency_symbol',
358 [
359 $currency_symbol,
360 $currency
361 ],
362 FLUENTFORM_FRAMEWORK_UPGRADE,
363 'fluentform/currency_symbol',
364 'Use fluentform/currency_symbol instead of fluentform_currency_symbol.'
365 );
366
367 return apply_filters('fluentform/currency_symbol', $currency_symbol, $currency);
368 }
369
370 public static function getCurrencySymbols()
371 {
372 $symbols = [
373 'AED' => '&#x62f;.&#x625;',
374 'AFN' => '&#x60b;',
375 'ALL' => 'L',
376 'AMD' => 'AMD',
377 'ANG' => '&fnof;',
378 'AOA' => 'Kz',
379 'ARS' => '&#36;',
380 'AUD' => '&#36;',
381 'AWG' => '&fnof;',
382 'AZN' => 'AZN',
383 'BAM' => 'KM',
384 'BBD' => '&#36;',
385 'BDT' => '&#2547;&nbsp;',
386 'BGN' => '&#1083;&#1074;.',
387 'BHD' => '.&#x62f;.&#x628;',
388 'BIF' => 'Fr',
389 'BMD' => '&#36;',
390 'BND' => '&#36;',
391 'BOB' => 'Bs.',
392 'BRL' => '&#82;&#36;',
393 'BSD' => '&#36;',
394 'BTC' => '&#3647;',
395 'BTN' => 'Nu.',
396 'BWP' => 'P',
397 'BYR' => 'Br',
398 'BZD' => '&#36;',
399 'CAD' => '&#36;',
400 'CDF' => 'Fr',
401 'CHF' => '&#67;&#72;&#70;',
402 'CLP' => '&#36;',
403 'CNY' => '&yen;',
404 'COP' => '&#36;',
405 'CRC' => '&#x20a1;',
406 'CUC' => '&#36;',
407 'CUP' => '&#36;',
408 'CVE' => '&#36;',
409 'CZK' => '&#75;&#269;',
410 'DJF' => 'Fr',
411 'DKK' => 'DKK',
412 'DOP' => 'RD&#36;',
413 'DZD' => '&#x62f;.&#x62c;',
414 'EGP' => 'EGP',
415 'ERN' => 'Nfk',
416 'ETB' => 'Br',
417 'EUR' => '&euro;',
418 'FJD' => '&#36;',
419 'FKP' => '&pound;',
420 'GBP' => '&pound;',
421 'GEL' => '&#x10da;',
422 'GGP' => '&pound;',
423 'GHS' => '&#x20b5;',
424 'GIP' => '&pound;',
425 'GMD' => 'D',
426 'GNF' => 'Fr',
427 'GTQ' => 'Q',
428 'GYD' => '&#36;',
429 'HKD' => '&#36;',
430 'HNL' => 'L',
431 'HRK' => 'Kn',
432 'HTG' => 'G',
433 'HUF' => '&#70;&#116;',
434 'IDR' => 'Rp',
435 'ILS' => '&#8362;',
436 'IMP' => '&pound;',
437 'INR' => '&#8377;',
438 'IQD' => '&#x639;.&#x62f;',
439 'IRR' => '&#xfdfc;',
440 'ISK' => 'Kr.',
441 'JEP' => '&pound;',
442 'JMD' => '&#36;',
443 'JOD' => '&#x62f;.&#x627;',
444 'JPY' => '&yen;',
445 'KES' => 'KSh',
446 'KGS' => '&#x43b;&#x432;',
447 'KHR' => '&#x17db;',
448 'KMF' => 'Fr',
449 'KPW' => '&#x20a9;',
450 'KRW' => '&#8361;',
451 'KWD' => '&#x62f;.&#x643;',
452 'KYD' => '&#36;',
453 'KZT' => 'KZT',
454 'LAK' => '&#8365;',
455 'LBP' => '&#x644;.&#x644;',
456 'LKR' => '&#xdbb;&#xdd4;',
457 'LRD' => '&#36;',
458 'LSL' => 'L',
459 'LYD' => '&#x644;.&#x62f;',
460 'MAD' => '&#x62f;. &#x645;.',
461 'MDL' => 'L',
462 'MGA' => 'Ar',
463 'MKD' => '&#x434;&#x435;&#x43d;',
464 'MMK' => 'Ks',
465 'MNT' => '&#x20ae;',
466 'MOP' => 'P',
467 'MRO' => 'UM',
468 'MUR' => '&#x20a8;',
469 'MVR' => '.&#x783;',
470 'MWK' => 'MK',
471 'MXN' => '&#36;',
472 'MYR' => '&#82;&#77;',
473 'MZN' => 'MT',
474 'NAD' => '&#36;',
475 'NGN' => '&#8358;',
476 'NIO' => 'C&#36;',
477 'NOK' => '&#107;&#114;',
478 'NPR' => '&#8360;',
479 'NZD' => '&#36;',
480 'OMR' => '&#x631;.&#x639;.',
481 'PAB' => 'B/.',
482 'PEN' => 'S/.',
483 'PGK' => 'K',
484 'PHP' => '&#8369;',
485 'PKR' => '&#8360;',
486 'PLN' => '&#122;&#322;',
487 'PRB' => '&#x440;.',
488 'PYG' => '&#8370;',
489 'QAR' => '&#x631;.&#x642;',
490 'RMB' => '&yen;',
491 'RON' => 'lei',
492 'RSD' => '&#x434;&#x438;&#x43d;.',
493 'RUB' => '&#8381;',
494 'RWF' => 'Fr',
495 'SAR' => '&#x631;.&#x633;',
496 'SBD' => '&#36;',
497 'SCR' => '&#x20a8;',
498 'SDG' => '&#x62c;.&#x633;.',
499 'SEK' => '&#107;&#114;',
500 'SGD' => '&#36;',
501 'SHP' => '&pound;',
502 'SLL' => 'Le',
503 'SOS' => 'Sh',
504 'SRD' => '&#36;',
505 'SSP' => '&pound;',
506 'STD' => 'Db',
507 'SYP' => '&#x644;.&#x633;',
508 'SZL' => 'L',
509 'THB' => '&#3647;',
510 'TJS' => '&#x405;&#x41c;',
511 'TMT' => 'm',
512 'TND' => '&#x62f;.&#x62a;',
513 'TOP' => 'T&#36;',
514 'TRY' => '&#8378;',
515 'TTD' => '&#36;',
516 'TWD' => '&#78;&#84;&#36;',
517 'TZS' => 'Sh',
518 'UAH' => '&#8372;',
519 'UGX' => 'UGX',
520 'USD' => '&#36;',
521 'UYU' => '&#36;',
522 'UZS' => 'UZS',
523 'VEF' => 'Bs F',
524 'VND' => '&#8363;',
525 'VUV' => 'Vt',
526 'WST' => 'T',
527 'XAF' => 'Fr',
528 'XCD' => '&#36;',
529 'XOF' => 'Fr',
530 'XPF' => 'Fr',
531 'YER' => '&#xfdfc;',
532 'ZAR' => '&#82;',
533 'ZMW' => 'ZK',
534 ];
535
536 $symbols = apply_filters_deprecated(
537 'fluentform_currency_symbols',
538 [
539 $symbols
540 ],
541 FLUENTFORM_FRAMEWORK_UPGRADE,
542 'fluentform/currencies_symbols',
543 'Use fluentform/currencies_symbols instead of fluentform_currency_symbols.'
544 );
545
546 return apply_filters('fluentform/currencies_symbols', $symbols);
547 }
548
549 public static function zeroDecimalCurrencies()
550 {
551 $zeroDecimalCurrencies = [
552 'BIF' => esc_html__('Burundian Franc', 'fluentform'),
553 'CLP' => esc_html__('Chilean Peso', 'fluentform'),
554 'DJF' => esc_html__('Djiboutian Franc', 'fluentform'),
555 'GNF' => esc_html__('Guinean Franc', 'fluentform'),
556 'JPY' => esc_html__('Japanese Yen', 'fluentform'),
557 'KMF' => esc_html__('Comorian Franc', 'fluentform'),
558 'KRW' => esc_html__('South Korean Won', 'fluentform'),
559 'MGA' => esc_html__('Malagasy Ariary', 'fluentform'),
560 'PYG' => esc_html__('Paraguayan Guaraní', 'fluentform'),
561 'RWF' => esc_html__('Rwandan Franc', 'fluentform'),
562 'VND' => esc_html__('Vietnamese Dong', 'fluentform'),
563 'VUV' => esc_html__('Vanuatu Vatu', 'fluentform'),
564 'XAF' => esc_html__('Central African Cfa Franc', 'fluentform'),
565 'XOF' => esc_html__('West African Cfa Franc', 'fluentform'),
566 'XPF' => esc_html__('Cfp Franc', 'fluentform'),
567 ];
568
569 $zeroDecimalCurrencies = apply_filters_deprecated(
570 'fluentform_zero_decimal_currencies',
571 [
572 $zeroDecimalCurrencies
573 ],
574 FLUENTFORM_FRAMEWORK_UPGRADE,
575 'fluentform/zero_decimal_currencies',
576 'Use fluentform/zero_decimal_currencies instead of fluentform_zero_decimal_currencies.'
577 );
578
579 return apply_filters('fluentform/zero_decimal_currencies', $zeroDecimalCurrencies);
580 }
581
582 public static function isZeroDecimal($currencyCode)
583 {
584 $currencyCode = strtoupper($currencyCode);
585 $zeroDecimals = self::zeroDecimalCurrencies();
586 return isset($zeroDecimals[$currencyCode]);
587 }
588
589 public static function getPaymentStatuses()
590 {
591 $paymentStatuses = [
592 'paid' => __('Paid', 'fluentform'),
593 'processing' => __('Processing', 'fluentform'),
594 'pending' => __('Pending', 'fluentform'),
595 'failed' => __('Failed', 'fluentform'),
596 'refunded' => __('Refunded', 'fluentform'),
597 'partially-refunded' => __('Partial Refunded', 'fluentform'),
598 'cancelled' => __('Cancelled', 'fluentform')
599 ];
600
601 $paymentStatuses = apply_filters_deprecated(
602 'fluentform_available_payment_statuses',
603 [
604 $paymentStatuses
605 ],
606 FLUENTFORM_FRAMEWORK_UPGRADE,
607 'fluentform/available_payment_statuses',
608 'Use fluentform/available_payment_statuses instead of fluentform_available_payment_statuses.'
609 );
610
611 return apply_filters('fluentform/available_payment_statuses', $paymentStatuses);
612 }
613
614 public static function reversedPaymentStatuses()
615 {
616 return apply_filters('fluentform/reversed_payment_statuses', [
617 'refunded', 'partially-refunded', 'cancelled',
618 ]);
619 }
620
621 public static function isReversedPaymentStatus($status)
622 {
623 $status = is_null($status) ? '' : (string) $status;
624
625 if ('' === $status) {
626 return false;
627 }
628
629 return in_array($status, static::reversedPaymentStatuses(), true);
630 }
631
632 public static function getFormPaymentMethods($formId)
633 {
634 $inputs = FormFieldsParser::getInputs($formId, ['element', 'settings']);
635 foreach ($inputs as $field) {
636 if ($field['element'] == 'payment_method') {
637 $methods = ArrayHelper::get($field, 'settings.payment_methods') ?: ArrayHelper::get($field, 'raw.settings.payment_methods');
638 if (is_array($methods)) {
639 return array_filter($methods, function ($method) {
640 return $method['enabled'] == 'yes';
641 });
642 }
643 }
644 }
645 return [];
646 }
647
648 public static function getCustomerEmail($submission, $form = false)
649 {
650
651 $formSettings = PaymentHelper::getFormSettings($submission->form_id, 'admin');
652 $customerEmailField = ArrayHelper::get($formSettings, 'receipt_email');
653
654 if ($customerEmailField) {
655 $email = ArrayHelper::get($submission->response, $customerEmailField);
656 if ($email) {
657 return $email;
658 }
659 }
660
661 $user = get_user_by('ID', get_current_user_id());
662
663 if ($user) {
664 return $user->user_email;
665 }
666
667 if (!$form) {
668 return '';
669 }
670
671 $emailFields = FormFieldsParser::getInputsByElementTypes($form, ['input_email'], ['attributes']);
672
673 foreach ($emailFields as $field) {
674 $fieldName = $field['attributes']['name'];
675 if (!empty($submission->response[$fieldName])) {
676 return $submission->response[$fieldName];
677 }
678 }
679
680 return '';
681
682 }
683
684 static function getCustomerPhoneNumber($submission, $form) {
685 $phoneFields = FormFieldsParser::getInputsByElementTypes($form, ['phone'], ['attributes']);
686
687 foreach ($phoneFields as $field) {
688 $fieldName = $field['attributes']['name'];
689 if (!empty($submission->response[$fieldName])) {
690 return $submission->response[$fieldName];
691 }
692 }
693 return '';
694 }
695
696 /**
697 * Trim a string and append a suffix.
698 *
699 * @param string $string String to trim.
700 * @param integer $chars Amount of characters.
701 * Defaults to 200.
702 * @param string $suffix Suffix.
703 * Defaults to '...'.
704 * @return string
705 */
706 public static function formatPaymentItemString($string, $chars = 200, $suffix = '...')
707 {
708 $string = wp_strip_all_tags($string);
709 if (strlen($string) > $chars) {
710 if (function_exists('mb_substr')) {
711 $string = mb_substr($string, 0, ($chars - mb_strlen($suffix))) . $suffix;
712 } else {
713 $string = substr($string, 0, ($chars - strlen($suffix))) . $suffix;
714 }
715 }
716
717 return html_entity_decode($string, ENT_NOQUOTES, 'UTF-8');
718 }
719
720 /**
721 * Limit length of an arg.
722 *
723 * @param string $string Argument to limit.
724 * @param integer $limit Limit size in characters.
725 * @return string
726 */
727 public static function limitLength($string, $limit = 127)
728 {
729 $str_limit = $limit - 3;
730 if (function_exists('mb_strimwidth')) {
731 if (mb_strlen($string) > $limit) {
732 $string = mb_strimwidth($string, 0, $str_limit) . '...';
733 }
734 } else {
735 if (strlen($string) > $limit) {
736 $string = substr($string, 0, $str_limit) . '...';
737 }
738 }
739 return $string;
740 }
741
742 public static function floatToString($float)
743 {
744 if (!is_float($float)) {
745 return $float;
746 }
747
748 $locale = localeconv();
749 $string = strval($float);
750 $string = str_replace($locale['decimal_point'], '.', $string);
751
752 return $string;
753 }
754
755 public static function convertToCents($amount)
756 {
757 if (!$amount) {
758 return 0;
759 }
760
761 $amount = floatval($amount);
762
763 return intval(round($amount * 100));
764 }
765
766 public static function getCustomerName($submission, $form = false)
767 {
768 $formSettings = PaymentHelper::getFormSettings($submission->form_id, 'admin');
769 $customerNameCode = ArrayHelper::get($formSettings, 'customer_name');
770 if ($customerNameCode) {
771 $customerName = ShortCodeParser::parse($customerNameCode, $submission->id, $submission->response);
772 if ($customerName) {
773 return $customerName;
774 }
775 }
776
777 $user = get_user_by('ID', get_current_user_id());
778
779 if ($user) {
780 $customerName = trim($user->first_name . ' ' . $user->last_name);
781 if (!$customerName) {
782 $customerName = $user->display_name;
783 }
784 if ($customerName) {
785 return $customerName;
786 }
787 }
788
789 if (!$form) {
790 return '';
791 }
792
793 $nameFields = FormFieldsParser::getInputsByElementTypes($form, ['input_name'], ['attributes']);
794
795 $fieldName = false;
796 foreach ($nameFields as $field) {
797 if ($field['element'] === 'input_name') {
798 $fieldName = $field['attributes']['name'];
799 break;
800 }
801 }
802
803 $name = '';
804 if ($fieldName) {
805 if (!empty($submission->response[$fieldName])) {
806 $names = array_filter($submission->response[$fieldName]);
807 return trim(implode(' ', $names));
808 }
809 }
810
811 return $name;
812 }
813
814 public static function getStripeInlineConfig($formId)
815 {
816 $methods = static::getFormPaymentMethods($formId);
817
818 $stripe = ArrayHelper::get($methods, 'stripe');
819 $stripeInlineStyles = ArrayHelper::get(Helper::getFormMeta($formId, '_ff_form_styles', []), 'stripe_inline_element_style', false);
820 if ($stripe) {
821 return apply_filters(
822 'fluentform/stripe_inline_config',
823 [
824 'is_inline' => ArrayHelper::get($stripe, 'settings.embedded_checkout.value') == 'yes',
825 'inline_styles' => $stripeInlineStyles,
826 'verifyZip' => ArrayHelper::get($methods['stripe'], 'settings.verify_zip_code.value') === 'yes',
827 'disable_link' => false
828 ],
829 $formId
830 );
831 }
832
833 return [];
834 }
835
836 public static function log($data, $submission = false, $forceInsert = false)
837 {
838 if (!$forceInsert) {
839 static $paymentSettings;
840 if (!$paymentSettings) {
841 $paymentSettings = self::getPaymentSettings();
842 }
843
844 if (!isset($paymentSettings['debug_log']) || $paymentSettings['debug_log'] != 'yes') {
845 return false;
846 }
847 }
848
849 $defaults = [
850 'component' => 'Payment',
851 'status' => 'info',
852 'created_at' => current_time('mysql')
853 ];
854
855 if ($submission) {
856 $defaults['parent_source_id'] = $submission->form_id;
857 $defaults['source_type'] = 'submission_item';
858 $defaults['source_id'] = $submission->id;
859 } else {
860 $defaults['source_type'] = 'system_log';
861 }
862
863 $data = wp_parse_args($data, $defaults);
864
865 return \FluentForm\App\Models\Log::create($data)->id;
866
867 }
868
869 public static function maybeFireSubmissionActionHok($submission)
870 {
871 if (Helper::getSubmissionMeta($submission->id, 'is_form_action_fired') == 'yes') {
872 return false;
873 }
874
875 $form = \FluentForm\App\Models\Form::find($submission->form_id);
876
877 if (!apply_filters('fluentform/should_process_submission_actions', true, $submission, $form)) {
878 return false;
879 }
880
881 $formData = $submission->response;
882 if (!is_array($formData)) {
883 $formData = json_decode($formData, true);
884 }
885
886 (new SubmissionHandlerService())->processSubmissionData(
887 $submission->id, $formData, $form
888 );
889 Helper::setSubmissionMeta($submission->id, 'is_form_action_fired', 'yes');
890 return true;
891 }
892
893 public static function loadView($fileName, $data)
894 {
895 // normalize the filename
896 $fileName = str_replace(array('../', './'), '', $fileName);
897
898 $basePath = FLUENTFORM_DIR_PATH . 'app/Views/receipt/';
899 $basePath = apply_filters_deprecated(
900 'fluentform_payment_receipt_template_base_path',
901 [
902 $basePath,
903 $fileName,
904 $data
905 ],
906 FLUENTFORM_FRAMEWORK_UPGRADE,
907 'fluentform/payment_receipt_template_base_path',
908 'Use fluentform/payment_receipt_template_base_path instead of fluentform_payment_receipt_template_base_path.'
909 );
910
911 $basePath = apply_filters('fluentform/payment_receipt_template_base_path', $basePath, $fileName, $data);
912
913 $filePath = $basePath . $fileName . '.php';
914 extract($data);
915 ob_start();
916 include $filePath;
917 return ob_get_clean();
918 }
919
920 public static function recordSubscriptionCancelled($subscription, $vendorData, $logData = [])
921 {
922 \FluentForm\App\Models\Subscription::where('id', $subscription->id)
923 ->update([
924 'status' => 'cancelled',
925 'updated_at' => current_time('mysql')
926 ]);
927
928 $subscription = \FluentForm\App\Models\Subscription::find($subscription->id);
929
930 $submission = \FluentForm\App\Models\Submission::find($subscription->submission_id);
931
932 $logDefaults = [
933 'parent_source_id' => $subscription->form_id,
934 'source_type' => 'submission_item',
935 'source_id' => $subscription->submission_id,
936 'component' => 'Payment',
937 'status' => 'info',
938 'title' => __('Subscription has been cancelled', 'fluentform'),
939 'description' => __('Subscription has been cancelled from ', 'fluentform') . $submission->payment_method
940 ];
941
942 $logs = wp_parse_args($logData, $logDefaults);
943
944 do_action('fluentform/log_data', $logs);
945
946 do_action_deprecated(
947 'fluentform_subscription_payment_canceled',
948 [
949 $subscription,
950 $submission,
951 $vendorData
952 ],
953 FLUENTFORM_FRAMEWORK_UPGRADE,
954 'fluentform/subscription_payment_canceled',
955 'Use fluentform/subscription_payment_canceled instead of fluentform_subscription_payment_canceled.'
956 );
957 // New Payment Made so we have to fire some events here
958 do_action('fluentform/subscription_payment_canceled', $subscription, $submission, $vendorData);
959
960 do_action_deprecated(
961 'fluentform_subscription_payment_canceled_' . $submission->payment_method,
962 [
963 $subscription,
964 $submission,
965 $vendorData
966 ],
967 FLUENTFORM_FRAMEWORK_UPGRADE,
968 'fluentform/subscription_payment_canceled_' . $submission->payment_method,
969 'Use fluentform/subscription_payment_canceled_' . $submission->payment_method . ' instead of fluentform_subscription_payment_canceled_' . $submission->payment_method
970 );
971 do_action('fluentform/subscription_payment_canceled_' . $submission->payment_method, $subscription, $submission, $vendorData);
972 }
973
974 public static function getPaymentSummaryText($plan, $formId, $currency, $withMarkup = true)
975 {
976 $paymentSummaryText = [
977 'has_signup_fee' => __('{first_interval_total} for first {billing_interval} then {subscription_amount} for each {billing_interval}', 'fluentform'),
978 'has_trial' => __('Free for {trial_days} days then {subscription_amount} for each {billing_interval}', 'fluentform'),
979 'onetime_only' => __('One time payment of {first_interval_total}', 'fluentform'),
980 'normal' => __('{subscription_amount} for each {billing_interval}', 'fluentform'),
981 'bill_times' => __(', for {bill_times} installments', 'fluentform'),
982 'single_trial' => __('Free for {trial_days} days then {subscription_amount} one time', 'fluentform')
983 ];
984
985 $paymentSummaryText = apply_filters_deprecated(
986 'fluentform_recurring_payment_summary_texts',
987 [
988 $paymentSummaryText,
989 $plan,
990 $formId
991 ],
992 FLUENTFORM_FRAMEWORK_UPGRADE,
993 'fluentform/recurring_payment_summary_texts',
994 'Use fluentform/recurring_payment_summary_texts instead of fluentform_recurring_payment_summary_texts.'
995 );
996
997 $cases = apply_filters('fluentform/recurring_payment_summary_texts', $paymentSummaryText, $plan, $formId);
998
999 // if is trial
1000 $hasTrial = ArrayHelper::get($plan, 'has_trial_days') == 'yes' && ArrayHelper::get($plan, 'trial_days');
1001 if ($hasTrial) {
1002 $plan['signup_fee'] = 0;
1003 }
1004
1005 $signupFee = 0;
1006 $hasSignupFee = ArrayHelper::get($plan, 'has_signup_fee') == 'yes' && ArrayHelper::get($plan, 'signup_fee');
1007 if ($hasSignupFee) {
1008 $plan['trial_days'] = 0;
1009 $signupFee = ArrayHelper::get($plan, 'signup_fee');
1010 }
1011
1012 $firstIntervalTotal = PaymentHelper::formatMoney(
1013 PaymentHelper::convertToCents($signupFee + ArrayHelper::get($plan, 'subscription_amount')),
1014 $currency
1015 );
1016
1017 if ($signupFee) {
1018 $signupFee = PaymentHelper::formatMoney(
1019 PaymentHelper::convertToCents($signupFee),
1020 $currency
1021 );
1022 }
1023
1024 $subscriptionAmount = PaymentHelper::formatMoney(
1025 PaymentHelper::convertToCents(ArrayHelper::get($plan, 'subscription_amount')),
1026 $currency
1027 );
1028
1029 $billingInterval = $plan['billing_interval'];
1030 $billingInterval = ArrayHelper::get(self::getBillingIntervals(), $billingInterval, $billingInterval);
1031 $billingInterval = esc_html($billingInterval);
1032 $trialDays = esc_html(ArrayHelper::get($plan, 'trial_days'));
1033 $billTimes = esc_html(ArrayHelper::get($plan, 'bill_times'));
1034 $replaces = array(
1035 '{signup_fee}' => '<span class="ff_bs ffbs_signup_fee">' . $signupFee . '</span>',
1036 '{first_interval_total}' => '<span class="ff_bs ffbs_first_interval_total">' . $firstIntervalTotal . '</span>',
1037 '{subscription_amount}' => '<span class="ff_bs ffbs_subscription_amount">' . $subscriptionAmount . '</span>',
1038 '{billing_interval}' => '<span class="ff_bs ffbs_billing_interval">' . $billingInterval . '</span>',
1039 '{trial_days}' => '<span class="ff_bs ffbs_trial_days">' . $trialDays . '</span>',
1040 '{bill_times}' => '<span class="ff_bs ffbs_bill_times">' . $billTimes . '</span>',
1041 );
1042
1043 if (ArrayHelper::get($plan, 'user_input') == 'yes') {
1044 $cases['{subscription_amount}'] = '<span class="ff_dynamic_input_amount">' . $subscriptionAmount . '</span>';
1045 }
1046
1047 foreach ($cases as $textKey => $text) {
1048 $cases[$textKey] = str_replace(array_keys($replaces), array_values($replaces), $text);
1049 }
1050
1051 $customText = '';
1052 if ($hasSignupFee && isset($plan['bill_times']) && $plan['bill_times'] == 1) {
1053 $customText = $cases['onetime_only'];
1054 } else if ($hasSignupFee) {
1055 $customText = $cases['has_signup_fee'];
1056 } else if ($hasTrial) {
1057 if (ArrayHelper::get($plan, 'bill_times') == 1) {
1058 $customText = $cases['single_trial'];
1059 } else {
1060 $customText = $cases['has_trial'];
1061 }
1062 } else if (isset($plan['bill_times']) && $plan['bill_times'] == 1) {
1063 $customText = $cases['onetime_only'];
1064 } else {
1065 $customText = $cases['normal'];
1066 }
1067
1068 if (isset($plan['bill_times']) && $plan['bill_times'] > 1) {
1069 $customText .= $cases['bill_times'];
1070 }
1071 if($withMarkup) {
1072 $class = $plan['is_default'] === 'yes' ? '' : 'hidden_field';
1073 return '<div class="ff_summary_container ff_summary_container_' . esc_attr($plan['index']) . ' ' . $class . '">' . $customText . '</div>';
1074 }
1075 return $customText;
1076 }
1077
1078 public static function getCustomerAddress($submission)
1079 {
1080 $formSettings = PaymentHelper::getFormSettings($submission->form_id, 'admin');
1081 $customerAddressField = ArrayHelper::get($formSettings, 'customer_address');
1082
1083 if ($customerAddressField) {
1084 return ArrayHelper::get($submission->response, $customerAddressField);
1085 }
1086
1087 return null;
1088 }
1089
1090 public static function getBillingIntervals()
1091 {
1092 return [
1093 'day' => __('day', 'fluentform'),
1094 'week' => __('week', 'fluentform'),
1095 'month' => __('month', 'fluentform'),
1096 'year' => __('year', 'fluentform')
1097 ];
1098 }
1099
1100 public static function getSubscriptionStatuses()
1101 {
1102 return [
1103 'active' => __('active', 'fluentform'),
1104 'trialling' => __('trialling', 'fluentform'),
1105 'failing' => __('failing', 'fluentform'),
1106 'cancelled' => __('cancelled', 'fluentform')
1107 ];
1108 }
1109
1110 public static function getFormInput($formId,$inputType)
1111 {
1112 $form = fluentFormApi()->form($formId);
1113 $fields = FormFieldsParser::getInputsByElementTypes($form, [$inputType], ['attributes']);
1114 if (!empty($fields)) {
1115 $field = array_shift($fields);
1116 return ArrayHelper::get($field, 'attributes.name');
1117 }
1118 return '';
1119 }
1120
1121 /**
1122 * Stable encryption key, decoupled from WordPress salts (which some hosts and
1123 * security plugins rotate, silently breaking salt-encrypted payment keys).
1124 *
1125 * For stronger at-rest protection, define FLUENTFORM_ENCRYPTION_KEY in
1126 * wp-config.php so the key lives on the filesystem, not the database next to
1127 * the ciphertext. Set it BEFORE saving keys — defining it after keys are
1128 * stored makes existing values unreadable and requires re-entering them.
1129 *
1130 * @return string
1131 */
1132 public static function getEncryptionKey()
1133 {
1134 if (defined('FLUENTFORM_ENCRYPTION_KEY') && FLUENTFORM_ENCRYPTION_KEY) {
1135 return FLUENTFORM_ENCRYPTION_KEY;
1136 }
1137
1138 $key = get_option('_fluentform_encryption_key');
1139 if (!$key) {
1140 $key = base64_encode(openssl_random_pseudo_bytes(32)); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
1141 if (!add_option('_fluentform_encryption_key', $key, '', 'no')) {
1142 $key = get_option('_fluentform_encryption_key');
1143 }
1144 }
1145
1146 return $key;
1147 }
1148
1149 public static function encryptKey($value)
1150 {
1151 if(!$value) {
1152 return $value;
1153 }
1154
1155 if ( ! extension_loaded( 'openssl' ) ) {
1156 return $value;
1157 }
1158
1159 $key = self::getEncryptionKey();
1160 $method = 'aes-256-ctr';
1161 $ivlen = openssl_cipher_iv_length( $method );
1162 $iv = openssl_random_pseudo_bytes( $ivlen );
1163
1164 $ciphertext = openssl_encrypt( $value, $method, $key, OPENSSL_RAW_DATA, $iv );
1165 if ( $ciphertext === false ) {
1166 return false;
1167 }
1168
1169 $hmac = hash_hmac( 'sha256', $iv . $ciphertext, $key, true );
1170
1171 return 'v2:' . base64_encode( $iv . $hmac . $ciphertext ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
1172 }
1173
1174 public static function decryptKey( $raw_value ) {
1175
1176 if(!$raw_value) {
1177 return $raw_value;
1178 }
1179
1180 if ( strpos( $raw_value, 'v2:' ) !== 0 ) {
1181 return self::legacyDecryptKey( $raw_value );
1182 }
1183
1184 // A v2 blob is unrecoverable without openssl, so fail loud instead of
1185 // handing the ciphertext back as if it were the key.
1186 if ( ! extension_loaded( 'openssl' ) ) {
1187 return false;
1188 }
1189
1190 $key = self::getEncryptionKey();
1191 $decoded = base64_decode( substr( $raw_value, 3 ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
1192 $method = 'aes-256-ctr';
1193 $ivlen = openssl_cipher_iv_length( $method );
1194 $sha2len = 32;
1195
1196 if ( $decoded === false || strlen( $decoded ) < $ivlen + $sha2len ) {
1197 return false;
1198 }
1199
1200 $iv = substr( $decoded, 0, $ivlen );
1201 $hmac = substr( $decoded, $ivlen, $sha2len );
1202 $ciphertext = substr( $decoded, $ivlen + $sha2len );
1203
1204 // Encrypt-then-MAC: verify integrity (constant time) before decrypting.
1205 $calcmac = hash_hmac( 'sha256', $iv . $ciphertext, $key, true );
1206 if ( ! hash_equals( $hmac, $calcmac ) ) {
1207 return false;
1208 }
1209
1210 $value = openssl_decrypt( $ciphertext, $method, $key, OPENSSL_RAW_DATA, $iv );
1211
1212 return $value !== false ? $value : false;
1213 }
1214
1215 /**
1216 * Reads keys encrypted before v2, i.e. tied to LOGGED_IN_KEY / LOGGED_IN_SALT.
1217 *
1218 * @param string $raw_value
1219 * @return string|bool
1220 */
1221 public static function legacyDecryptKey( $raw_value ) {
1222
1223 if(!$raw_value) {
1224 return $raw_value;
1225 }
1226
1227 if ( ! extension_loaded( 'openssl' ) ) {
1228 return $raw_value;
1229 }
1230
1231 $raw_value = base64_decode( $raw_value, true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
1232
1233 $method = 'aes-256-ctr';
1234 $ivlen = openssl_cipher_iv_length( $method );
1235 $iv = substr( $raw_value, 0, $ivlen );
1236
1237 $raw_value = substr( $raw_value, $ivlen );
1238
1239 $salt = (defined( 'LOGGED_IN_SALT' ) && '' !== LOGGED_IN_SALT) ? LOGGED_IN_SALT : 'this-is-a-fallback-salt-but-not-secure';
1240 $key = ( defined( 'LOGGED_IN_KEY' ) && '' !== LOGGED_IN_KEY ) ? LOGGED_IN_KEY : 'this-is-a-fallback-key-but-not-secure';
1241
1242 $value = openssl_decrypt( $raw_value, $method, $key, 0, $iv );
1243 if ( ! $value || substr( $value, - strlen( $salt ) ) !== $salt ) {
1244 return false;
1245 }
1246
1247 return substr( $value, 0, - strlen( $salt ) );
1248 }
1249
1250 public static function isPlanExpiredAndHidden($plan)
1251 {
1252 if (ArrayHelper::get($plan, 'has_end_date') !== 'yes') {
1253 return false;
1254 }
1255 if (ArrayHelper::get($plan, 'expire_behavior') !== 'hide') {
1256 return false;
1257 }
1258 $endDateStr = ArrayHelper::get($plan, 'subscription_end_date');
1259 if (!$endDateStr) {
1260 return false;
1261 }
1262 $endDate = strtotime($endDateStr . ' +1 day');
1263 return !$endDate || $endDate <= current_time('timestamp');
1264 }
1265 }
1266