PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
← All changes | app/Providers/FrontendAssetsProvider.php +358 -9 3.0.6 → 3.0.16 View file →
@@ -30,8 +30,50 @@
30 30 add_action('wp_enqueue_scripts', [$this, 'enqueueAssets']);
31 31 }
32 32
33 33 /**
34 + * Resolve the effective trip-listing card layout for one listing.
35 + *
36 + * The site-wide Design setting (`frontend_listing_card_layout`) is the
37 + * default; a shortcode/block may pass a per-instance override. Anything that
38 + * is not a concrete layout (empty, "inherit", or an unknown value) falls
39 + * back to the global setting, so existing shortcodes/blocks are unchanged.
40 + *
41 + * @param string $override Per-instance override (card_layout / cardLayout).
42 + * @return string One of: standard | compact_mobile | compact_all.
43 + */
44 + public static function resolveListingLayout(string $override = ''): string
45 + {
46 + $override = strtolower(trim($override));
47 + if (in_array($override, ['standard', 'compact_mobile', 'compact_all'], true)) {
48 + return $override;
49 + }
50 +
51 + $global = \Yatra\Services\SettingsService::getString('frontend_listing_card_layout', 'standard');
52 + return in_array($global, ['standard', 'compact_mobile', 'compact_all'], true) ? $global : 'standard';
53 + }
54 +
55 + /**
56 + * Map a resolved layout to the container CSS class(es) the listing CSS keys
57 + * off. Placed on the listing container (archive .yatra-listing-page, or the
58 + * shortcode/block wrapper) so each listing can carry its own layout and an
59 + * override never leaks into other listings on the same page.
60 + *
61 + * @param string $layout standard | compact_mobile | compact_all
62 + * @return string Space-separated class list ('' for standard).
63 + */
64 + public static function listingLayoutClasses(string $layout): string
65 + {
66 + if ($layout === 'compact_mobile') {
67 + return 'yatra-listing-compact';
68 + }
69 + if ($layout === 'compact_all') {
70 + return 'yatra-listing-compact yatra-listing-compact--all';
71 + }
72 + return '';
73 + }
74 +
75 + /**
34 76 * Register Font Awesome (optional) and common.css so block editor + shortcode styles can
35 77 * depend on `yatra-common` (shared @keyframes: yatra-spin, yatra-shimmer, etc.).
36 78 */
37 79 /**
@@ -286,14 +328,22 @@
286 328 'yatra',
287 329 YATRA_PLUGIN_PATH . 'i18n/languages'
288 330 );
289 331 }
332 + // Wishlist "Login" should send guests to the configured
333 + // My Account page (Settings → Permalink slug), not the raw
334 + // wp-login.php screen. Fall back to wp_login_url() only when
335 + // no account base is configured so the button never dead-ends.
336 + $yatraAccountBase = \Yatra\Services\SettingsService::getAccountBase();
337 + $yatraAccountLoginUrl = $yatraAccountBase !== ''
338 + ? home_url('/' . trim($yatraAccountBase, '/') . '/')
339 + : wp_login_url();
290 340 wp_localize_script('yatra-listing-wishlist', 'yatraWishlistConfig', [
291 341 'enabled' => true,
292 342 'restUrl' => rest_url('yatra/v1'),
293 343 'nonce' => wp_create_nonce('wp_rest'),
294 344 'isLoggedIn' => is_user_logged_in(),
295 - 'loginUrl' => wp_login_url(),
345 + 'loginUrl' => $yatraAccountLoginUrl,
296 346 'i18n' => [
297 347 'loginRequired' => __('Login Required', 'yatra'),
298 348 'loginPrompt' => __('Please login to save trips to your wishlist.', 'yatra'),
299 349 'login' => __('Login', 'yatra'),
@@ -386,8 +436,13 @@
386 436 );
387 437 }
388 438 }
389 439
440 + // International phone-number widget (country flag + dial code) used by
441 + // the booking form's tel fields.
442 + $this->enqueuePhoneInputAssets();
443 + $this->enqueueCountrySelectAssets();
444 +
390 445 // Mobile sticky-sidebar + flatpickr init for the single-trip page. Lives in a
391 446 // dedicated file rather than as inline <script> in the partial because
392 447 // WordPress core's `convert_chars` filter (hooked to the_content) rewrites the
393 448 // `&&` operators inside inline scripts as `&#038;&#038;` — JS parsers don't
@@ -437,8 +492,16 @@
437 492 'tripId' => $trip_id,
438 493 'tripSlug' => $trip_slug,
439 494 'wishlistEnabled' => \Yatra\Services\SettingsService::wishlistEnabled(),
440 495 'isLoggedIn' => is_user_logged_in(),
496 + // Wishlist "Login" (guest) → the configured My Account page
497 + // (Settings → Permalink slug), NOT wp-login.php. Without this key
498 + // trip.js falls back to a hardcoded '/wp-login.php'. Falls back to
499 + // wp_login_url() only when no account base slug is configured.
500 + 'loginUrl' => (function () {
501 + $base = \Yatra\Services\SettingsService::getAccountBase();
502 + return $base !== '' ? home_url('/' . trim($base, '/') . '/') : wp_login_url();
503 + })(),
441 504 // Regional settings
442 505 'timezone' => \Yatra\Services\SettingsService::getString('timezone', 'UTC'),
443 506 'dateFormat' => \Yatra\Services\SettingsService::getString('date_format', 'Y-m-d'),
444 507 'timeFormat' => \Yatra\Services\SettingsService::getString('time_format', 'H:i'),
@@ -445,9 +508,9 @@
445 508 // Currency/settings
446 509 'currency' => \Yatra\Services\SettingsService::getCurrency(),
447 510 'currencyPosition' => \Yatra\Services\SettingsService::getString('currency_position', 'left'),
448 511 'currency_position' => \Yatra\Services\SettingsService::getString('currency_position', 'left'),
449 - 'decimalPlaces' => (int) \Yatra\Services\SettingsService::getString('currency_decimals', '2'),
512 + 'decimalPlaces' => \Yatra\Services\SettingsService::getPriceDecimals(),
450 513 'thousandSeparator' => \Yatra\Services\SettingsService::getString('thousand_separator', ','),
451 514 'decimalSeparator' => \Yatra\Services\SettingsService::getString('decimal_separator', '.'),
452 515 'basePrice' => 0.0,
453 516 'currencySymbol' => function_exists('yatra_get_currency_symbol')
@@ -518,8 +581,106 @@
518 581 ));
519 582 }
520 583
521 584 /**
585 + * Enqueue the country selector widget (assets/js/country-select.js +
586 + * assets/css/country-select.css).
587 + *
588 + * Upgrades every `type => country` field (Country, Nationality, on both the
589 + * contact and traveler sections) into a searchable dropdown showing the
590 + * national flag, matching the phone country-code control. Purely additive:
591 + * the underlying <select> still renders and submits, so a site that never
592 + * loads this script behaves exactly as before.
593 + *
594 + * Idempotent, so it is safe to call from every path that renders the form.
595 + *
596 + * @return void
597 + */
598 + private function enqueueCountrySelectAssets(): void
599 + {
600 + if (wp_script_is('yatra-country-select', 'enqueued')) {
601 + return;
602 + }
603 +
604 + $css = YATRA_PLUGIN_PATH . 'assets/css/country-select.css';
605 + if (file_exists($css)) {
606 + wp_enqueue_style(
607 + 'yatra-country-select',
608 + YATRA_PLUGIN_URL . 'assets/css/country-select.css',
609 + [],
610 + YATRA_VERSION . '.' . filemtime($css)
611 + );
612 + }
613 +
614 + $js = YATRA_PLUGIN_PATH . 'assets/js/country-select.js';
615 + if (!file_exists($js)) {
616 + return;
617 + }
618 +
619 + wp_enqueue_script(
620 + 'yatra-country-select',
621 + YATRA_PLUGIN_URL . 'assets/js/country-select.js',
622 + [],
623 + YATRA_VERSION . '.' . filemtime($js),
624 + true
625 + );
626 +
627 + wp_localize_script('yatra-country-select', 'yatraCountrySelectData', [
628 + 'i18n' => [
629 + 'search' => __('Search country', 'yatra'),
630 + 'noResults' => __('No matches', 'yatra'),
631 + ],
632 + ]);
633 + }
634 +
635 + /**
636 + * Enqueue the international phone-number widget (assets/js/phone-input.js +
637 + * assets/css/phone-input.css) and localize its country + dial-code dataset.
638 + *
639 + * Self-contained (reads its own `yatraPhoneData` global) and idempotent, so
640 + * it can be called from every path that renders the booking form. Country
641 + * data is the single source of truth in {@see FormatHelper}.
642 + *
643 + * @return void
644 + */
645 + private function enqueuePhoneInputAssets(): void
646 + {
647 + if (wp_script_is('yatra-phone-input', 'enqueued')) {
648 + return;
649 + }
650 +
651 + $css = YATRA_PLUGIN_PATH . 'assets/css/phone-input.css';
652 + if (file_exists($css)) {
653 + wp_enqueue_style(
654 + 'yatra-phone-input',
655 + YATRA_PLUGIN_URL . 'assets/css/phone-input.css',
656 + [],
657 + YATRA_VERSION . '.' . filemtime($css)
658 + );
659 + }
660 +
661 + $js = YATRA_PLUGIN_PATH . 'assets/js/phone-input.js';
662 + if (!file_exists($js)) {
663 + return;
664 + }
665 + wp_enqueue_script(
666 + 'yatra-phone-input',
667 + YATRA_PLUGIN_URL . 'assets/js/phone-input.js',
668 + [],
669 + YATRA_VERSION . '.' . filemtime($js),
670 + true
671 + );
672 + wp_localize_script('yatra-phone-input', 'yatraPhoneData', [
673 + 'countries' => \Yatra\Helpers\FormatHelper::getPhoneCountries(),
674 + 'priority' => \Yatra\Helpers\FormatHelper::getPhonePriority(),
675 + 'i18n' => [
676 + 'search' => __('Search country', 'yatra'),
677 + 'noResults' => __('No matches', 'yatra'),
678 + ],
679 + ]);
680 + }
681 +
682 + /**
522 683 * Enqueue activity listing specific assets
523 684 *
524 685 * @return void
525 686 */
@@ -573,20 +734,71 @@
573 734 YATRA_VERSION . '.' . filemtime($bookingCss)
574 735 );
575 736 }
576 737
738 + // Flatpickr — used by booking.js to upgrade Date-of-Birth (and other
739 + // date) inputs to a picker with fast, typeable year navigation. The
740 + // single-trip page already ships flatpickr (see single-trip.php); the
741 + // dedicated booking page did not, so enqueue it here. booking.js
742 + // self-guards on `typeof flatpickr`, so this is safe either way.
743 + wp_enqueue_style(
744 + 'yatra-flatpickr',
745 + 'https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css',
746 + [],
747 + YATRA_VERSION
748 + );
749 + wp_enqueue_script(
750 + 'yatra-flatpickr',
751 + 'https://cdn.jsdelivr.net/npm/flatpickr',
752 + [],
753 + YATRA_VERSION,
754 + true
755 + );
756 +
577 757 // Enqueue booking-specific JavaScript
578 758 $bookingJs = YATRA_PLUGIN_PATH . 'assets/js/booking.js';
579 759 if (file_exists($bookingJs)) {
760 + // booking.js renders user-facing strings via wp.i18n.__() (the
761 + // "Processing..." button label and the per-gateway info messages
762 + // shown when a payment method is selected). It therefore needs
763 + // wp-i18n as a dependency AND wp_set_script_translations so its
764 + // Jed catalog loads — mirroring the trip-detail enqueue above.
765 + // Without these, those strings stay English on the standalone
766 + // booking page regardless of site locale.
580 767 wp_enqueue_script(
581 768 'yatra-booking',
582 769 YATRA_PLUGIN_URL . 'assets/js/booking.js',
583 - ['jquery'],
770 + ['jquery', 'yatra-flatpickr', 'wp-i18n'],
584 771 YATRA_VERSION . '.' . filemtime($bookingJs),
585 772 true
586 773 );
774 + if (function_exists('wp_set_script_translations')) {
775 + wp_set_script_translations(
776 + 'yatra-booking',
777 + 'yatra',
778 + YATRA_PLUGIN_PATH . 'i18n/languages'
779 + );
780 + }
587 781 }
588 -
782 +
783 + // International phone-number widget (country flag + dial code).
784 + $this->enqueuePhoneInputAssets();
785 + $this->enqueueCountrySelectAssets();
786 +
787 + // Load each available gateway's own client scripts on the checkout page
788 + // (e.g. Square Web Payments SDK + square.js, Authorize.Net Accept.js +
789 + // its handler, Razorpay SDK + its handler). Every gateway's
790 + // enqueueScripts() self-guards on isAvailable(), so only enabled +
791 + // configured gateways load anything. This call was previously missing,
792 + // so Pro gateways that render an inline card form shipped no JS to
793 + // checkout and clicking "Pay" just span the button forever. It is
794 + // additive and safe for the others: Stripe's enqueueScripts() is a
795 + // no-op (Stripe is loaded via enqueueCommonJs), and PayPal/Pay Later
796 + // have no client scripts.
797 + if (class_exists(\Yatra\PaymentGateways\PaymentGatewayRegistry::class)) {
798 + \Yatra\PaymentGateways\PaymentGatewayRegistry::getInstance()->enqueueScripts();
799 + }
800 +
589 801 // Localize booking data for booking.js
590 802 $permalink_structure = get_option('permalink_structure') ?: '';
591 803 $is_plain = empty($permalink_structure);
592 804
@@ -625,13 +837,13 @@
625 837 'bookingNonce' => wp_create_nonce('yatra_booking_action'),
626 838 'currency' => \Yatra\Services\SettingsService::getCurrency(),
627 839 'currencyPosition' => \Yatra\Services\SettingsService::getString('currency_position', 'left'),
628 840 'currency_position' => \Yatra\Services\SettingsService::getString('currency_position', 'left'),
629 - 'decimalPlaces' => (int) \Yatra\Services\SettingsService::getString('currency_decimals', '2'),
841 + 'decimalPlaces' => \Yatra\Services\SettingsService::getPriceDecimals(),
630 842 'thousandSeparator' => \Yatra\Services\SettingsService::getString('thousand_separator', ','),
631 843 'decimalSeparator' => \Yatra\Services\SettingsService::getString('decimal_separator', '.'),
632 844 // Payment gateways data
633 - 'paymentGateways' => apply_filters('yatra_payment_gateways', \Yatra\Services\SettingsService::get('payment_gateways', [])),
845 + 'paymentGateways' => $this->sanitizeGatewayConfigsForFrontend(apply_filters('yatra_payment_gateways', \Yatra\Services\SettingsService::get('payment_gateways', []))),
634 846 'paymentMethods' => \Yatra\Services\SettingsService::get('payment_methods', []),
635 847 'paymentTestMode' => \Yatra\Services\SettingsService::get('payment_test_mode', false),
636 848 'partialPayment' => \Yatra\Services\SettingsService::get('partial_payment', false),
637 849 'partialPaymentPercentage' => \Yatra\Services\SettingsService::get('partial_payment_percentage', 0),
@@ -643,10 +855,17 @@
643 855 'gatewayOrder' => \Yatra\Services\SettingsService::get('gateway_order', []),
644 856 'autoConfirmPayLater' => \Yatra\Services\SettingsService::get('auto_confirm_pay_later', true),
645 857 'allowWaitlist' => \Yatra\Services\SettingsService::isEnabled('allow_waitlist'),
646 858 'waitlistAutoConfirm' => \Yatra\Services\SettingsService::isEnabled('waitlist_auto_confirm'),
647 - 'gateways' => apply_filters('yatra_payment_gateways', \Yatra\Services\SettingsService::get('payment_gateways', [])),
648 - 'enabledGateways' => \Yatra\Services\SettingsService::get('payment_gateways', []),
859 + 'gateways' => $this->getGatewayFrontendConfigs(),
860 + 'enabledGateways' => $this->sanitizeGatewayConfigsForFrontend(\Yatra\Services\SettingsService::get('payment_gateways', [])),
861 + // Server-side translated UI strings for booking.js. PHP __() resolves via .mo
862 + // (reliable), so these stay translatable even when the JS-translation JSON
863 + // chain (wp_set_script_translations) doesn't load on a given setup.
864 + 'i18n' => [
865 + 'complete_booking' => __('Complete Booking', 'yatra'),
866 + 'pay_now' => __('Pay Now', 'yatra'),
867 + ],
649 868 ];
650 869
651 870 $bookingData = array_merge($bookingData, $this->getStripeFrontendBookingPayload());
652 871
@@ -709,12 +928,24 @@
709 928 'companyEmail' => \Yatra\Services\SettingsService::getString('company_email', ''),
710 929 'currency' => \Yatra\Services\SettingsService::getCurrency(),
711 930 'currencyPosition' => \Yatra\Services\SettingsService::getString('currency_position', 'left'),
712 931 'currency_position' => \Yatra\Services\SettingsService::getString('currency_position', 'left'),
713 - 'decimalPlaces' => (int) \Yatra\Services\SettingsService::getString('currency_decimals', '2'),
932 + 'decimalPlaces' => \Yatra\Services\SettingsService::getPriceDecimals(),
714 933 'thousandSeparator' => \Yatra\Services\SettingsService::getString('thousand_separator', ','),
715 934 'decimalSeparator' => \Yatra\Services\SettingsService::getString('decimal_separator', '.'),
716 935 'locale' => get_locale(),
936 + // Global date/time format so the customer account pages render dates
937 + // in the operator's configured format (Settings → General), not a
938 + // hardcoded browser style. Keys mirror what the admin app receives.
939 + 'date_format' => \Yatra\Services\SettingsService::getString('date_format', 'Y-m-d'),
940 + 'time_format' => \Yatra\Services\SettingsService::getString('time_format', 'H:i'),
941 + 'timezone' => \Yatra\Services\SettingsService::getString('timezone', 'UTC'),
942 + // Full ISO country map (code => name) so the account profile can show
943 + // full country names and render the country dropdown. Mirrors the
944 + // admin (`yatraAdmin.countries`); honours the `yatra_countries_list` filter.
945 + 'countries' => class_exists('\\Yatra\\Helpers\\FormatHelper')
946 + ? \Yatra\Helpers\FormatHelper::getCountries()
947 + : [],
717 948 'translations' => $this->getFrontendTranslations(),
718 949 'wishlistEnabled' => \Yatra\Services\SettingsService::wishlistEnabled(),
719 950 ]);
720 951
@@ -849,8 +1080,34 @@
849 1080 'Total Amount' => __('Total Amount', 'yatra'),
850 1081 'Payment Status' => __('Payment Status', 'yatra'),
851 1082 'View Details' => __('View Details', 'yatra'),
852 1083
1084 + // Traveler / contact / emergency field labels on the account page.
1085 + // Keep in sync with the `fieldLabel()` map in account/BookingDetails.tsx.
1086 + 'First Name' => __('First Name', 'yatra'),
1087 + 'Last Name' => __('Last Name', 'yatra'),
1088 + 'Full Name' => __('Full Name', 'yatra'),
1089 + 'Name' => __('Name', 'yatra'),
1090 + 'Email' => __('Email', 'yatra'),
1091 + 'Phone' => __('Phone', 'yatra'),
1092 + 'Mobile' => __('Mobile', 'yatra'),
1093 + 'Date of Birth' => __('Date of Birth', 'yatra'),
1094 + 'Gender' => __('Gender', 'yatra'),
1095 + 'Nationality' => __('Nationality', 'yatra'),
1096 + 'Country' => __('Country', 'yatra'),
1097 + 'Address' => __('Address', 'yatra'),
1098 + 'City' => __('City', 'yatra'),
1099 + 'State' => __('State', 'yatra'),
1100 + 'Postal Code' => __('Postal Code', 'yatra'),
1101 + 'Zip Code' => __('Zip Code', 'yatra'),
1102 + 'Passport' => __('Passport', 'yatra'),
1103 + 'Passport Number' => __('Passport Number', 'yatra'),
1104 + 'Passport Expiry' => __('Passport Expiry', 'yatra'),
1105 + 'Dietary Requirements' => __('Dietary Requirements', 'yatra'),
1106 + 'Special Requirements' => __('Special Requirements', 'yatra'),
1107 + 'Relationship' => __('Relationship', 'yatra'),
1108 + 'Company' => __('Company', 'yatra'),
1109 +
853 1110 // Common
854 1111 'Loading...' => __('Loading...', 'yatra'),
855 1112 'No data available' => __('No data available', 'yatra'),
856 1113 'Error loading data' => __('Error loading data', 'yatra'),
@@ -955,8 +1212,100 @@
955 1212 {
956 1213 $basePath = $type === 'css' ? 'assets/css/' : 'assets/js/';
957 1214 $fullPath = YATRA_PLUGIN_PATH . $basePath . $path;
958 1215 return file_exists($fullPath);
1216 + }
1217 +
1218 + /**
1219 + * Strip secret credentials from per-gateway config before it is localized
1220 + * into the page (yatraBookingData). The stored payment_gateways option
1221 + * holds private keys / access tokens that must NEVER reach the browser; the
1222 + * checkout scripts only ever read public values (publishable keys, Square
1223 + * application/location IDs, Authorize.Net public client key, the enabled
1224 + * flag, etc.). This removes the known secret keys while preserving the
1225 + * structure and every public field, so existing gateways/consumers are
1226 + * unaffected — only secrets are dropped.
1227 + *
1228 + * @param mixed $gateways
1229 + * @return array<string, mixed>
1230 + */
1231 + /**
1232 + * Per-gateway PUBLIC config for the booking page, keyed by gateway id
1233 + * (window.yatraBookingData.gateways.<id>). Checkout scripts read their public
1234 + * settings from here — e.g. square.js → gateways.square.application_id /
1235 + * location_id, authorizenet.js → gateways.authorize_net.public_client_key /
1236 + * api_login_id.
1237 + *
1238 + * Source of truth is each ENABLED gateway's own getFrontendData(), i.e. an
1239 + * allowlist the gateway itself declares. This is deliberately NOT a denylist
1240 + * over the raw stored config: a denylist would leak any secret whose key we
1241 + * forgot (e.g. Stripe live_secret_key / test_secret_key, Bank Transfer
1242 + * account_number / routing_code). Gateways without a getFrontendData()
1243 + * (Bank Transfer, PayPal, Pay Later, …) contribute nothing, so their stored
1244 + * details never reach the browser. Disabled gateways are excluded.
1245 + *
1246 + * @return array<string, array<string, mixed>>
1247 + */
1248 + private function getGatewayFrontendConfigs(): array
1249 + {
1250 + if (!class_exists(\Yatra\PaymentGateways\PaymentGatewayRegistry::class)) {
1251 + return [];
1252 + }
1253 +
1254 + $out = [];
1255 + try {
1256 + $registry = \Yatra\PaymentGateways\PaymentGatewayRegistry::getInstance();
1257 + foreach ($registry->getEnabledGateways() as $id => $gateway) {
1258 + if (!is_object($gateway) || !method_exists($gateway, 'getFrontendData')) {
1259 + continue;
1260 + }
1261 + $data = $gateway->getFrontendData();
1262 + if (is_array($data) && $data !== []) {
1263 + $data['enabled'] = true;
1264 + $out[(string) $id] = $data;
1265 + }
1266 + }
1267 + } catch (\Throwable $e) {
1268 + return [];
1269 + }
1270 +
1271 + return $out;
1272 + }
1273 +
1274 + private function sanitizeGatewayConfigsForFrontend($gateways): array
1275 + {
1276 + if (!is_array($gateways)) {
1277 + return [];
1278 + }
1279 +
1280 + // Credential fields that are private to the server.
1281 + $secretKeys = [
1282 + 'access_token',
1283 + 'api_key',
1284 + 'api_secret',
1285 + 'secret_key',
1286 + 'key_secret',
1287 + 'client_secret',
1288 + 'transaction_key',
1289 + 'webhook_secret',
1290 + 'webhook_signing_secret',
1291 + 'signing_secret',
1292 + 'private_key',
1293 + 'password',
1294 + 'secret',
1295 + ];
1296 +
1297 + $clean = [];
1298 + foreach ($gateways as $id => $config) {
1299 + if (is_array($config)) {
1300 + foreach ($secretKeys as $secret) {
1301 + unset($config[$secret]);
1302 + }
1303 + }
1304 + $clean[$id] = $config;
1305 + }
1306 +
1307 + return $clean;
959 1308 }
960 1309
961 1310 /**
962 1311 * Stripe Elements (assets/js/stripe.js) expects publishableKey under yatraBookingData.stripe.