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 | assets/js/stripe.js +35 -1 3.0.5 → 3.0.16 View file →
@@ -235,9 +235,16 @@
235 235 const stripePreselected = !!stripeOption.checked;
236 236 container.style.display = stripePreselected ? 'block' : 'none';
237 237
238 238 this.methodSwitcher = this.createMethodSwitcher();
239 - container.appendChild(this.methodSwitcher);
239 + // Show the "Payment methods" chooser only when there's an actual choice
240 + // (Card + Apple/Google Pay). With Card as the only enabled method the
241 + // chooser is redundant chrome, so present the card field directly.
242 + if (this.hasMultipleMethods) {
243 + container.appendChild(this.methodSwitcher);
244 + } else {
245 + container.classList.add('yatra-stripe-container--single-method');
246 + }
240 247
241 248 if (this.supportsPaymentRequest) {
242 249 const requestWrapper = document.createElement('div');
243 250 requestWrapper.className = 'yatra-stripe-payment-request-wrapper';
@@ -637,8 +644,13 @@
637 644 icon: this.getMethodIconMarkup('apple_pay')
638 645 });
639 646 }
640 647
648 + // Only a real choice (Card + a wallet) warrants the chooser. With Card
649 + // as the only enabled method, the render step drops this switcher and
650 + // shows the card field on its own (no redundant "Payment methods" row).
651 + this.hasMultipleMethods = availableButtons.length > 1;
652 +
641 653 const buttons = document.createElement('div');
642 654 buttons.className = 'yatra-method-switcher__buttons';
643 655
644 656 availableButtons.forEach((method) => {
@@ -907,8 +919,30 @@
907 919 || (typeof document !== 'undefined'
908 920 ? (document.querySelector('input[name="yatra_booking_nonce"]') || {}).value
909 921 : '')
910 922 || '';
923 +
924 +
925 + // reCAPTCHA v3: this gateway posts to /booking/create itself, so it must
926 + // attach its own token — the shared submit path in booking.js never runs
927 + // for an intercepted gateway submit. Without this the server receives an
928 + // empty token and rejects the booking with "reCAPTCHA verification
929 + // failed", which no score threshold can get past.
930 + //
931 + // A fresh token every attempt: v3 tokens are single-use and expire after
932 + // ~2 minutes, so a retry after a declined card must not reuse the old one.
933 + try {
934 + const yatraRc = (typeof window !== 'undefined') ? window.yatraRecaptcha : null;
935 + if (yatraRc && typeof yatraRc.protects === 'function' && yatraRc.protects('booking')
936 + && typeof yatraRc.execute === 'function') {
937 + const recaptchaToken = await yatraRc.execute('booking');
938 + if (recaptchaToken) {
939 + bookingData.recaptcha_token = recaptchaToken;
940 + }
941 + }
942 + } catch (e) {
943 + // Never block checkout on the helper itself; the server still decides.
944 + }
911 945
912 946 // Always call the same endpoint - server decides based on session type
913 947 const bookingResponse = await fetch(`${this.apiUrl}/booking/create`, {
914 948 method: 'POST',