PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.9
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.9
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.9, at app/Modules/Payments/PaymentHelper.php

1,241 lines 46.0 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 getFormPaymentMethods($formId)
615 {
616 $inputs = FormFieldsParser::getInputs($formId, ['element', 'settings']);
617 foreach ($inputs as $field) {
618 if ($field['element'] == 'payment_method') {
619 $methods = ArrayHelper::get($field, 'settings.payment_methods') ?: ArrayHelper::get($field, 'raw.settings.payment_methods');
620 if (is_array($methods)) {
621 return array_filter($methods, function ($method) {
622 return $method['enabled'] == 'yes';
623 });
624 }
625 }
626 }
627 return [];
628 }
629
630 public static function getCustomerEmail($submission, $form = false)
631 {
632
633 $formSettings = PaymentHelper::getFormSettings($submission->form_id, 'admin');
634 $customerEmailField = ArrayHelper::get($formSettings, 'receipt_email');
635
636 if ($customerEmailField) {
637 $email = ArrayHelper::get($submission->response, $customerEmailField);
638 if ($email) {
639 return $email;
640 }
641 }
642
643 $user = get_user_by('ID', get_current_user_id());
644
645 if ($user) {
646 return $user->user_email;
647 }
648
649 if (!$form) {
650 return '';
651 }
652
653 $emailFields = FormFieldsParser::getInputsByElementTypes($form, ['input_email'], ['attributes']);
654
655 foreach ($emailFields as $field) {
656 $fieldName = $field['attributes']['name'];
657 if (!empty($submission->response[$fieldName])) {
658 return $submission->response[$fieldName];
659 }
660 }
661
662 return '';
663
664 }
665
666 static function getCustomerPhoneNumber($submission, $form) {
667 $phoneFields = FormFieldsParser::getInputsByElementTypes($form, ['phone'], ['attributes']);
668
669 foreach ($phoneFields as $field) {
670 $fieldName = $field['attributes']['name'];
671 if (!empty($submission->response[$fieldName])) {
672 return $submission->response[$fieldName];
673 }
674 }
675 return '';
676 }
677
678 /**
679 * Trim a string and append a suffix.
680 *
681 * @param string $string String to trim.
682 * @param integer $chars Amount of characters.
683 * Defaults to 200.
684 * @param string $suffix Suffix.
685 * Defaults to '...'.
686 * @return string
687 */
688 public static function formatPaymentItemString($string, $chars = 200, $suffix = '...')
689 {
690 $string = wp_strip_all_tags($string);
691 if (strlen($string) > $chars) {
692 if (function_exists('mb_substr')) {
693 $string = mb_substr($string, 0, ($chars - mb_strlen($suffix))) . $suffix;
694 } else {
695 $string = substr($string, 0, ($chars - strlen($suffix))) . $suffix;
696 }
697 }
698
699 return html_entity_decode($string, ENT_NOQUOTES, 'UTF-8');
700 }
701
702 /**
703 * Limit length of an arg.
704 *
705 * @param string $string Argument to limit.
706 * @param integer $limit Limit size in characters.
707 * @return string
708 */
709 public static function limitLength($string, $limit = 127)
710 {
711 $str_limit = $limit - 3;
712 if (function_exists('mb_strimwidth')) {
713 if (mb_strlen($string) > $limit) {
714 $string = mb_strimwidth($string, 0, $str_limit) . '...';
715 }
716 } else {
717 if (strlen($string) > $limit) {
718 $string = substr($string, 0, $str_limit) . '...';
719 }
720 }
721 return $string;
722 }
723
724 public static function floatToString($float)
725 {
726 if (!is_float($float)) {
727 return $float;
728 }
729
730 $locale = localeconv();
731 $string = strval($float);
732 $string = str_replace($locale['decimal_point'], '.', $string);
733
734 return $string;
735 }
736
737 public static function convertToCents($amount)
738 {
739 if (!$amount) {
740 return 0;
741 }
742
743 $amount = floatval($amount);
744
745 return intval(round($amount * 100));
746 }
747
748 public static function getCustomerName($submission, $form = false)
749 {
750 $formSettings = PaymentHelper::getFormSettings($submission->form_id, 'admin');
751 $customerNameCode = ArrayHelper::get($formSettings, 'customer_name');
752 if ($customerNameCode) {
753 $customerName = ShortCodeParser::parse($customerNameCode, $submission->id, $submission->response);
754 if ($customerName) {
755 return $customerName;
756 }
757 }
758
759 $user = get_user_by('ID', get_current_user_id());
760
761 if ($user) {
762 $customerName = trim($user->first_name . ' ' . $user->last_name);
763 if (!$customerName) {
764 $customerName = $user->display_name;
765 }
766 if ($customerName) {
767 return $customerName;
768 }
769 }
770
771 if (!$form) {
772 return '';
773 }
774
775 $nameFields = FormFieldsParser::getInputsByElementTypes($form, ['input_name'], ['attributes']);
776
777 $fieldName = false;
778 foreach ($nameFields as $field) {
779 if ($field['element'] === 'input_name') {
780 $fieldName = $field['attributes']['name'];
781 break;
782 }
783 }
784
785 $name = '';
786 if ($fieldName) {
787 if (!empty($submission->response[$fieldName])) {
788 $names = array_filter($submission->response[$fieldName]);
789 return trim(implode(' ', $names));
790 }
791 }
792
793 return $name;
794 }
795
796 public static function getStripeInlineConfig($formId)
797 {
798 $methods = static::getFormPaymentMethods($formId);
799
800 $stripe = ArrayHelper::get($methods, 'stripe');
801 $stripeInlineStyles = ArrayHelper::get(Helper::getFormMeta($formId, '_ff_form_styles', []), 'stripe_inline_element_style', false);
802 if ($stripe) {
803 return apply_filters(
804 'fluentform/stripe_inline_config',
805 [
806 'is_inline' => ArrayHelper::get($stripe, 'settings.embedded_checkout.value') == 'yes',
807 'inline_styles' => $stripeInlineStyles,
808 'verifyZip' => ArrayHelper::get($methods['stripe'], 'settings.verify_zip_code.value') === 'yes',
809 'disable_link' => false
810 ],
811 $formId
812 );
813 }
814
815 return [];
816 }
817
818 public static function log($data, $submission = false, $forceInsert = false)
819 {
820 if (!$forceInsert) {
821 static $paymentSettings;
822 if (!$paymentSettings) {
823 $paymentSettings = self::getPaymentSettings();
824 }
825
826 if (!isset($paymentSettings['debug_log']) || $paymentSettings['debug_log'] != 'yes') {
827 return false;
828 }
829 }
830
831 $defaults = [
832 'component' => 'Payment',
833 'status' => 'info',
834 'created_at' => current_time('mysql')
835 ];
836
837 if ($submission) {
838 $defaults['parent_source_id'] = $submission->form_id;
839 $defaults['source_type'] = 'submission_item';
840 $defaults['source_id'] = $submission->id;
841 } else {
842 $defaults['source_type'] = 'system_log';
843 }
844
845 $data = wp_parse_args($data, $defaults);
846
847 return \FluentForm\App\Models\Log::create($data)->id;
848
849 }
850
851 public static function maybeFireSubmissionActionHok($submission)
852 {
853 if (Helper::getSubmissionMeta($submission->id, 'is_form_action_fired') == 'yes') {
854 return false;
855 }
856
857 $form = \FluentForm\App\Models\Form::find($submission->form_id);
858
859 $formData = $submission->response;
860 if (!is_array($formData)) {
861 $formData = json_decode($formData, true);
862 }
863
864 (new SubmissionHandlerService())->processSubmissionData(
865 $submission->id, $formData, $form
866 );
867 Helper::setSubmissionMeta($submission->id, 'is_form_action_fired', 'yes');
868 return true;
869 }
870
871 public static function loadView($fileName, $data)
872 {
873 // normalize the filename
874 $fileName = str_replace(array('../', './'), '', $fileName);
875
876 $basePath = FLUENTFORM_DIR_PATH . 'app/Views/receipt/';
877 $basePath = apply_filters_deprecated(
878 'fluentform_payment_receipt_template_base_path',
879 [
880 $basePath,
881 $fileName,
882 $data
883 ],
884 FLUENTFORM_FRAMEWORK_UPGRADE,
885 'fluentform/payment_receipt_template_base_path',
886 'Use fluentform/payment_receipt_template_base_path instead of fluentform_payment_receipt_template_base_path.'
887 );
888
889 $basePath = apply_filters('fluentform/payment_receipt_template_base_path', $basePath, $fileName, $data);
890
891 $filePath = $basePath . $fileName . '.php';
892 extract($data);
893 ob_start();
894 include $filePath;
895 return ob_get_clean();
896 }
897
898 public static function recordSubscriptionCancelled($subscription, $vendorData, $logData = [])
899 {
900 \FluentForm\App\Models\Subscription::where('id', $subscription->id)
901 ->update([
902 'status' => 'cancelled',
903 'updated_at' => current_time('mysql')
904 ]);
905
906 $subscription = \FluentForm\App\Models\Subscription::find($subscription->id);
907
908 $submission = \FluentForm\App\Models\Submission::find($subscription->submission_id);
909
910 $logDefaults = [
911 'parent_source_id' => $subscription->form_id,
912 'source_type' => 'submission_item',
913 'source_id' => $subscription->submission_id,
914 'component' => 'Payment',
915 'status' => 'info',
916 'title' => __('Subscription has been cancelled', 'fluentform'),
917 'description' => __('Subscription has been cancelled from ', 'fluentform') . $submission->payment_method
918 ];
919
920 $logs = wp_parse_args($logData, $logDefaults);
921
922 do_action('fluentform/log_data', $logs);
923
924 do_action_deprecated(
925 'fluentform_subscription_payment_canceled',
926 [
927 $subscription,
928 $submission,
929 $vendorData
930 ],
931 FLUENTFORM_FRAMEWORK_UPGRADE,
932 'fluentform/subscription_payment_canceled',
933 'Use fluentform/subscription_payment_canceled instead of fluentform_subscription_payment_canceled.'
934 );
935 // New Payment Made so we have to fire some events here
936 do_action('fluentform/subscription_payment_canceled', $subscription, $submission, $vendorData);
937
938 do_action_deprecated(
939 'fluentform_subscription_payment_canceled_' . $submission->payment_method,
940 [
941 $subscription,
942 $submission,
943 $vendorData
944 ],
945 FLUENTFORM_FRAMEWORK_UPGRADE,
946 'fluentform/subscription_payment_canceled_' . $submission->payment_method,
947 'Use fluentform/subscription_payment_canceled_' . $submission->payment_method . ' instead of fluentform_subscription_payment_canceled_' . $submission->payment_method
948 );
949 do_action('fluentform/subscription_payment_canceled_' . $submission->payment_method, $subscription, $submission, $vendorData);
950 }
951
952 public static function getPaymentSummaryText($plan, $formId, $currency, $withMarkup = true)
953 {
954 $paymentSummaryText = [
955 'has_signup_fee' => __('{first_interval_total} for first {billing_interval} then {subscription_amount} for each {billing_interval}', 'fluentform'),
956 'has_trial' => __('Free for {trial_days} days then {subscription_amount} for each {billing_interval}', 'fluentform'),
957 'onetime_only' => __('One time payment of {first_interval_total}', 'fluentform'),
958 'normal' => __('{subscription_amount} for each {billing_interval}', 'fluentform'),
959 'bill_times' => __(', for {bill_times} installments', 'fluentform'),
960 'single_trial' => __('Free for {trial_days} days then {subscription_amount} one time', 'fluentform')
961 ];
962
963 $paymentSummaryText = apply_filters_deprecated(
964 'fluentform_recurring_payment_summary_texts',
965 [
966 $paymentSummaryText,
967 $plan,
968 $formId
969 ],
970 FLUENTFORM_FRAMEWORK_UPGRADE,
971 'fluentform/recurring_payment_summary_texts',
972 'Use fluentform/recurring_payment_summary_texts instead of fluentform_recurring_payment_summary_texts.'
973 );
974
975 $cases = apply_filters('fluentform/recurring_payment_summary_texts', $paymentSummaryText, $plan, $formId);
976
977 // if is trial
978 $hasTrial = ArrayHelper::get($plan, 'has_trial_days') == 'yes' && ArrayHelper::get($plan, 'trial_days');
979 if ($hasTrial) {
980 $plan['signup_fee'] = 0;
981 }
982
983 $signupFee = 0;
984 $hasSignupFee = ArrayHelper::get($plan, 'has_signup_fee') == 'yes' && ArrayHelper::get($plan, 'signup_fee');
985 if ($hasSignupFee) {
986 $plan['trial_days'] = 0;
987 $signupFee = ArrayHelper::get($plan, 'signup_fee');
988 }
989
990 $firstIntervalTotal = PaymentHelper::formatMoney(
991 PaymentHelper::convertToCents($signupFee + ArrayHelper::get($plan, 'subscription_amount')),
992 $currency
993 );
994
995 if ($signupFee) {
996 $signupFee = PaymentHelper::formatMoney(
997 PaymentHelper::convertToCents($signupFee),
998 $currency
999 );
1000 }
1001
1002 $subscriptionAmount = PaymentHelper::formatMoney(
1003 PaymentHelper::convertToCents(ArrayHelper::get($plan, 'subscription_amount')),
1004 $currency
1005 );
1006
1007 $billingInterval = $plan['billing_interval'];
1008 $billingInterval = ArrayHelper::get(self::getBillingIntervals(), $billingInterval, $billingInterval);
1009 $replaces = array(
1010 '{signup_fee}' => '<span class="ff_bs ffbs_signup_fee">' . $signupFee . '</span>',
1011 '{first_interval_total}' => '<span class="ff_bs ffbs_first_interval_total">' . $firstIntervalTotal . '</span>',
1012 '{subscription_amount}' => '<span class="ff_bs ffbs_subscription_amount">' . $subscriptionAmount . '</span>',
1013 '{billing_interval}' => '<span class="ff_bs ffbs_billing_interval">' . $billingInterval . '</span>',
1014 '{trial_days}' => '<span class="ff_bs ffbs_trial_days">' . $plan['trial_days'] . '</span>',
1015 '{bill_times}' => '<span class="ff_bs ffbs_bill_times">' . ArrayHelper::get($plan, 'bill_times') . '</span>'
1016 );
1017
1018 if (ArrayHelper::get($plan, 'user_input') == 'yes') {
1019 $cases['{subscription_amount}'] = '<span class="ff_dynamic_input_amount">' . $subscriptionAmount . '</span>';
1020 }
1021
1022 foreach ($cases as $textKey => $text) {
1023 $cases[$textKey] = str_replace(array_keys($replaces), array_values($replaces), $text);
1024 }
1025
1026 $customText = '';
1027 if ($hasSignupFee && isset($plan['bill_times']) && $plan['bill_times'] == 1) {
1028 $customText = $cases['onetime_only'];
1029 } else if ($hasSignupFee) {
1030 $customText = $cases['has_signup_fee'];
1031 } else if ($hasTrial) {
1032 if (ArrayHelper::get($plan, 'bill_times') == 1) {
1033 $customText = $cases['single_trial'];
1034 } else {
1035 $customText = $cases['has_trial'];
1036 }
1037 } else if (isset($plan['bill_times']) && $plan['bill_times'] == 1) {
1038 $customText = $cases['onetime_only'];
1039 } else {
1040 $customText = $cases['normal'];
1041 }
1042
1043 if (isset($plan['bill_times']) && $plan['bill_times'] > 1) {
1044 $customText .= $cases['bill_times'];
1045 }
1046 if($withMarkup) {
1047 $class = $plan['is_default'] === 'yes' ? '' : 'hidden_field';
1048 return '<div class="ff_summary_container ff_summary_container_' . $plan['index'] . ' ' . $class . '">' . $customText . '</div>';
1049 }
1050 return $customText;
1051 }
1052
1053 public static function getCustomerAddress($submission)
1054 {
1055 $formSettings = PaymentHelper::getFormSettings($submission->form_id, 'admin');
1056 $customerAddressField = ArrayHelper::get($formSettings, 'customer_address');
1057
1058 if ($customerAddressField) {
1059 return ArrayHelper::get($submission->response, $customerAddressField);
1060 }
1061
1062 return null;
1063 }
1064
1065 public static function getBillingIntervals()
1066 {
1067 return [
1068 'day' => __('day', 'fluentform'),
1069 'week' => __('week', 'fluentform'),
1070 'month' => __('month', 'fluentform'),
1071 'year' => __('year', 'fluentform')
1072 ];
1073 }
1074
1075 public static function getSubscriptionStatuses()
1076 {
1077 return [
1078 'active' => __('active', 'fluentform'),
1079 'trialling' => __('trialling', 'fluentform'),
1080 'failing' => __('failing', 'fluentform'),
1081 'cancelled' => __('cancelled', 'fluentform')
1082 ];
1083 }
1084
1085 public static function getFormInput($formId,$inputType)
1086 {
1087 $form = fluentFormApi()->form($formId);
1088 $fields = FormFieldsParser::getInputsByElementTypes($form, [$inputType], ['attributes']);
1089 if (!empty($fields)) {
1090 $field = array_shift($fields);
1091 return ArrayHelper::get($field, 'attributes.name');
1092 }
1093 return '';
1094 }
1095
1096 /**
1097 * Stable encryption key, decoupled from WordPress salts (which some hosts and
1098 * security plugins rotate, silently breaking salt-encrypted payment keys).
1099 *
1100 * For stronger at-rest protection, define FLUENTFORM_ENCRYPTION_KEY in
1101 * wp-config.php so the key lives on the filesystem, not the database next to
1102 * the ciphertext. Set it BEFORE saving keys — defining it after keys are
1103 * stored makes existing values unreadable and requires re-entering them.
1104 *
1105 * @return string
1106 */
1107 public static function getEncryptionKey()
1108 {
1109 if (defined('FLUENTFORM_ENCRYPTION_KEY') && FLUENTFORM_ENCRYPTION_KEY) {
1110 return FLUENTFORM_ENCRYPTION_KEY;
1111 }
1112
1113 $key = get_option('_fluentform_encryption_key');
1114 if (!$key) {
1115 $key = base64_encode(openssl_random_pseudo_bytes(32)); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
1116 if (!add_option('_fluentform_encryption_key', $key, '', 'no')) {
1117 $key = get_option('_fluentform_encryption_key');
1118 }
1119 }
1120
1121 return $key;
1122 }
1123
1124 public static function encryptKey($value)
1125 {
1126 if(!$value) {
1127 return $value;
1128 }
1129
1130 if ( ! extension_loaded( 'openssl' ) ) {
1131 return $value;
1132 }
1133
1134 $key = self::getEncryptionKey();
1135 $method = 'aes-256-ctr';
1136 $ivlen = openssl_cipher_iv_length( $method );
1137 $iv = openssl_random_pseudo_bytes( $ivlen );
1138
1139 $ciphertext = openssl_encrypt( $value, $method, $key, OPENSSL_RAW_DATA, $iv );
1140 if ( $ciphertext === false ) {
1141 return false;
1142 }
1143
1144 $hmac = hash_hmac( 'sha256', $iv . $ciphertext, $key, true );
1145
1146 return 'v2:' . base64_encode( $iv . $hmac . $ciphertext ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
1147 }
1148
1149 public static function decryptKey( $raw_value ) {
1150
1151 if(!$raw_value) {
1152 return $raw_value;
1153 }
1154
1155 if ( strpos( $raw_value, 'v2:' ) !== 0 ) {
1156 return self::legacyDecryptKey( $raw_value );
1157 }
1158
1159 // A v2 blob is unrecoverable without openssl, so fail loud instead of
1160 // handing the ciphertext back as if it were the key.
1161 if ( ! extension_loaded( 'openssl' ) ) {
1162 return false;
1163 }
1164
1165 $key = self::getEncryptionKey();
1166 $decoded = base64_decode( substr( $raw_value, 3 ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
1167 $method = 'aes-256-ctr';
1168 $ivlen = openssl_cipher_iv_length( $method );
1169 $sha2len = 32;
1170
1171 if ( $decoded === false || strlen( $decoded ) < $ivlen + $sha2len ) {
1172 return false;
1173 }
1174
1175 $iv = substr( $decoded, 0, $ivlen );
1176 $hmac = substr( $decoded, $ivlen, $sha2len );
1177 $ciphertext = substr( $decoded, $ivlen + $sha2len );
1178
1179 // Encrypt-then-MAC: verify integrity (constant time) before decrypting.
1180 $calcmac = hash_hmac( 'sha256', $iv . $ciphertext, $key, true );
1181 if ( ! hash_equals( $hmac, $calcmac ) ) {
1182 return false;
1183 }
1184
1185 $value = openssl_decrypt( $ciphertext, $method, $key, OPENSSL_RAW_DATA, $iv );
1186
1187 return $value !== false ? $value : false;
1188 }
1189
1190 /**
1191 * Reads keys encrypted before v2, i.e. tied to LOGGED_IN_KEY / LOGGED_IN_SALT.
1192 *
1193 * @param string $raw_value
1194 * @return string|bool
1195 */
1196 public static function legacyDecryptKey( $raw_value ) {
1197
1198 if(!$raw_value) {
1199 return $raw_value;
1200 }
1201
1202 if ( ! extension_loaded( 'openssl' ) ) {
1203 return $raw_value;
1204 }
1205
1206 $raw_value = base64_decode( $raw_value, true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
1207
1208 $method = 'aes-256-ctr';
1209 $ivlen = openssl_cipher_iv_length( $method );
1210 $iv = substr( $raw_value, 0, $ivlen );
1211
1212 $raw_value = substr( $raw_value, $ivlen );
1213
1214 $salt = (defined( 'LOGGED_IN_SALT' ) && '' !== LOGGED_IN_SALT) ? LOGGED_IN_SALT : 'this-is-a-fallback-salt-but-not-secure';
1215 $key = ( defined( 'LOGGED_IN_KEY' ) && '' !== LOGGED_IN_KEY ) ? LOGGED_IN_KEY : 'this-is-a-fallback-key-but-not-secure';
1216
1217 $value = openssl_decrypt( $raw_value, $method, $key, 0, $iv );
1218 if ( ! $value || substr( $value, - strlen( $salt ) ) !== $salt ) {
1219 return false;
1220 }
1221
1222 return substr( $value, 0, - strlen( $salt ) );
1223 }
1224
1225 public static function isPlanExpiredAndHidden($plan)
1226 {
1227 if (ArrayHelper::get($plan, 'has_end_date') !== 'yes') {
1228 return false;
1229 }
1230 if (ArrayHelper::get($plan, 'expire_behavior') !== 'hide') {
1231 return false;
1232 }
1233 $endDateStr = ArrayHelper::get($plan, 'subscription_end_date');
1234 if (!$endDateStr) {
1235 return false;
1236 }
1237 $endDate = strtotime($endDateStr . ' +1 day');
1238 return !$endDate || $endDate <= current_time('timestamp');
1239 }
1240 }
1241