PageSourceSearch

https://fastpassportsandvisas.com/wp-content/plugins/visa-acceptan…ateway-unified-checkout-public.js?ver=2.2.2

js fastpassportsandvisas.com collected 2026-10-08 07:10:55 UTC 52,510 bytes, 1,038 lines download raw bytes

1(function($) {
2    'use strict';
3
4    var firstLoadFlag = false;
5    var isEventTriggered = false;
6    var add_payment_method_token;
7    var disableLoader = false;
8    var isExpressPaySubmission = false;
9
10    // Flex microform variables for saved card CVV.
11    var flexInstances = {};
12    var flexFieldsValid = {};
13    // Collect and send browser data for 3DS device information.
14    function collectBrowserData() {
15        if (typeof visa_acceptance_ajaxUCObj === 'undefined') {
16            return;
17        }
18        
19        var browserData = {
20            action: 'store_browser_data',
21            nonce: visa_acceptance_ajaxUCObj.store_browser_data_nonce || '',
22            gateway_id: visa_acceptance_ajaxUCObj.gateway_id || '',
23            screen_height: window.screen.height,
24            screen_width: window.screen.width,
25            color_depth: window.screen.colorDepth,
26            tz_offset: new Date().getTimezoneOffset(),
27            java_enabled: navigator.javaEnabled ? navigator.javaEnabled() : false,
28            js_enabled: true
29        };
30        
31        $.ajax({
32            url: visa_acceptance_ajaxUCObj.ajax_url,
33            type: 'POST',
34            data: browserData,
35            async: false
36        });
37    }
38    
39    // Collect browser data on page load.
40    $(document).ready(function() {
41        collectBrowserData();
42    });
43    
44    jQuery(document).on('wc_checkout_form_error', function() {
45        window.flexSubmissionInProgress = false;
46        jQuery('form.checkout').off('submit', handleFormSubmission).on('submit', handleFormSubmission);
47        // Show payment form back when there's a validation error after express pay click.
48        hideExpressPayLoader();
49        jQuery('.woocommerce-checkout-payment').show();
50    });
51
52    jQuery(document.body).on('checkout_error', function() {
53        var isNewCard = (
54            jQuery("input[name$='payment_method'][value$='" + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id'] + "']").is(':checked') &&
55            (
56                jQuery('#wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] + '-use-new-payment-method').is(':checked') ||
57                jQuery('#wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] + '-use-new-payment-method').length === 0
58            )
59        );
60        if (isNewCard) {
61            location.reload();
62        }
63    });
64
65    setInterval(checkDisableLoader, 1000);
66
67    function checkDisableLoader() {
68        if (disableLoader) {
69            jQuery('.blockUI.blockOverlay').hide();
70            disableLoader = false;
71            location.reload();
72        }
73    }
74
75    //Building Error Message.
76    const errorMessagePara = document.createElement("p");
77    errorMessagePara.setAttribute('style','color:red')
78    const errorMessageText = document.createTextNode(visa_acceptance_ajaxUCObj['form_load_error']);
79    errorMessagePara.appendChild(errorMessageText);
80
81    var paymentMethodRow = $('tr.payment-method');
82    var defaultPaymentMethodRow = $('tr.default-payment-method');
83    var paymentMethodRowText = paymentMethodRow.find('td.woocommerce-PaymentMethod.woocommerce-PaymentMethod--default.payment-method-default').text();
84    var defaultPaymentMethodRowText = defaultPaymentMethodRow.find('td.woocommerce-PaymentMethod.woocommerce-PaymentMethod--default.payment-method-default').text();
85
86    jQuery('.woocommerce-MyAccount-paymentMethods').on('click', '.woocommerce-PaymentMethod--actions .button.delete', function(e) {
87        if (!confirm(visa_acceptance_ajaxUCObj['delete_card_text'])) {
88            e.preventDefault();
89            location.reload();
90        }
91        if (!navigator.onLine) {
92            alert(visa_acceptance_ajaxUCObj['offline_text']);
93            e.preventDefault();
94        }
95    });
96
97    // Named function for form submission handling.
98    async function handleFormSubmission(e) {
99        // Express pay bypasses all form validation (terms, CVV, etc.).
100        if (isExpressPaySubmission) {
101            isExpressPaySubmission = false;
102            return true;
103        }
104        if ($("input[name$='payment_method'][value$='" + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id'] +"']").is(':checked')) {
105            var valueForTkn = jQuery('input[name=wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] + '-payment-token]:checked').val();
106            
107            // If no token is selected, allow normal processing (new card).
108            if (!valueForTkn) {
109                document.getElementById("errorMessage").value = "no";
110                return true; // Allow form submission.
111            }
112            
113            // Check if token is eCheck - skip CVV validation for eCheck.
114            var isEcheck = visa_acceptance_ajaxUCObj['token_type'] && visa_acceptance_ajaxUCObj['token_type'][valueForTkn] === 'eCheck';
115            
116            if (!visa_acceptance_ajaxUCObj['saved_card_cvv'] || isEcheck) {
117                document.getElementById("errorMessage").value = "no";
118                return true;
119            }
120            
121            // CVV is required - check if Flex is being used for this token.
122            if (valueForTkn && flexInstances[valueForTkn]) {
123                if (!flexFieldsValid[valueForTkn]) {
124                    // Show error if Flex CVV field is not valid.
125                    jQuery('#error-' + encodeURI(valueForTkn)).show();
126                    document.getElementById("errorMessage").value = "yes";
127                    e.preventDefault();
128                    e.stopImmediatePropagation();
129                    return false;
130                }
131                try {
132                    e.preventDefault();
133                    e.stopImmediatePropagation();
134                    
135                    var flexTokenResponse = await flexInstances[valueForTkn].createToken();
136                    
137                    if (flexTokenResponse && flexTokenResponse.token) {
138                        // Add the flex token to a hidden field.
139                        var flexTokenField = jQuery('input[name="flex_cvv_token"]');
140                        if (flexTokenField.length === 0) {
141                            jQuery('form.checkout').append('<input type="hidden" name="flex_cvv_token" value="' + flexTokenResponse.token + '">');
142                        } else {
143                            flexTokenField.val(flexTokenResponse.token);
144                        }
145                        document.getElementById("errorMessage").value = "no";
146
147                        if (!window.flexSubmissionInProgress) {
148                            window.flexSubmissionInProgress = true;
149                            var form = jQuery('form.checkout');
150                            form.off('submit', handleFormSubmission);
151                            form.removeClass('processing');
152                            form.submit();
153                        }
154                        return false;
155                    } else {
156                        jQuery('#error-' + encodeURI(valueForTkn)).show();
157                        document.getElementById("errorMessage").value = "yes";
158                        return false;
159                    }
160                } catch (error) {
161                    jQuery('#error-' + encodeURI(valueForTkn)).show();
162                    document.getElementById("errorMessage").value = "yes";
163                    e.preventDefault();
164                    e.stopImmediatePropagation();
165                    return false;
166                }
167            } else {
168                // Flex is NOT being used - validate regular input field.
169                let security_code = jQuery('input[name=csc-saved-card-' + encodeURI(valueForTkn) + ']').val();
170                if (security_code && (security_code.length < 3 || security_code.length > 4)) {
171                    jQuery('#error-' + encodeURI(valueForTkn)).show();
172                    document.getElementById("errorMessage").value = "yes";
173                    //To stop loading checkout page after entering invaid CVV.
174                    e.preventDefault();
175                    e.stopImmediatePropagation();
176                    return false;
177                }
178                document.getElementById("errorMessage").value = "no";
179            }
180        }
181    }
182
183    // Attach the named function to the form submit event.
184    jQuery('form.checkout').on("submit", handleFormSubmission);
185
186    if (paymentMethodRow.length && defaultPaymentMethodRow.length && paymentMethodRowText != defaultPaymentMethodRowText) {
187        defaultPaymentMethodRow.find('.woocommerce-PaymentMethod--actions .delete').hide();
188    }
189
190    function createButton(id, text) {
191        return $('<button>', {
192            type: 'button',
193            id: id,
194            class: 'btn btn-lg btn-block btn-primary',
195            disabled: 'disabled',
196            text: text,
197            style: 'display: none;'
198        });
199    }
200
201    function addLoader() {
202        var loaderHtml = '<div id="loader" style="display:none;">' +
203            '</div>';
204        jQuery('body').append(loaderHtml);
205    }
206
207    function showExpressPayLoader() {
208        addLoader();
209        const blockUIElement = document.querySelector('.blockUI.blockOverlay');
210        if (blockUIElement) {
211            var computedStyle = getComputedStyle(blockUIElement);
212            var display = computedStyle.getPropertyValue('display');
213            var visibility = computedStyle.getPropertyValue('visibility')
214            if (display == 'none' || visibility == 'hidden') {
215                var loader = document.getElementById("loader");
216                loader.style.display = "block";
217                const topWindow = window.top;
218                topWindow.document.body.appendChild(loader);
219            }
220        } else {
221
222            var loader = document.getElementById("loader");
223            loader.style.display = "block";
224            const topWindow = window.top;
225            topWindow.document.body.appendChild(loader);
226        }
227    }
228
229    function hideExpressPayLoader() {
230        document.getElementById("loader").style.display = "none";
231    }
232
233    function populateCheckoutFieldsFromTransientToken(transientToken, isExpressPay) {
234        return new Promise((resolve) => {
235            var expressOnly = !!isExpressPay;
236            var isLoggedIn = (typeof visa_acceptance_ajaxUCObj !== 'undefined' && visa_acceptance_ajaxUCObj.is_user_logged_in);
237
238            if (!expressOnly || isLoggedIn) {
239                resolve();
240                return;
241            }
242
243            if (!transientToken) {
244                resolve();
245                return;
246            }
247
248            jQuery.ajax({
249                type: "POST",
250                url: visa_acceptance_ajaxUCObj["ajax_url"],
251                data: {
252                    action: 'get_addresses_from_transient_token',
253                    transientToken: transientToken
254                },
255                success: function (response) {
256                    if (response && response.success && response.data) {
257                        const billing = response.data.billing || {};
258                        const shipping = response.data.shipping || {};
259
260                        const billingMap = {
261                            first_name: 'billing_first_name',
262                            last_name: 'billing_last_name',
263                            company: 'billing_company',
264                            address_1: 'billing_address_1',
265                            address_2: 'billing_address_2',
266                            city: 'billing_city',
267                            state: 'billing_state',
268                            postcode: 'billing_postcode',
269                            country: 'billing_country',
270                            email: 'billing_email',
271                            phone: 'billing_phone'
272                        };
273
274                        Object.keys(billingMap).forEach(function (key) {
275                            if (billing[key] !== undefined && billing[key] !== null) {
276                                const fieldName = billingMap[key];
277                                const $field = jQuery('[name="' + fieldName + '"]');
278                                if ($field.length) {
279                                    $field.val(billing[key]).trigger('change');
280                                }
281                            }
282                        });
283
284                        const shipDiffCheckbox = jQuery('#ship-to-different-address-checkbox');
285                        const shouldSetShipping = shipDiffCheckbox.length ? shipDiffCheckbox.is(':checked') : true;
286
287                        if (shouldSetShipping) {
288                            const shippingMap = {
289                                first_name: 'shipping_first_name',
290                                last_name: 'shipping_last_name',
291                                company: 'shipping_company',
292                                address_1: 'shipping_address_1',
293                                address_2: 'shipping_address_2',
294                                city: 'shipping_city',
295                                state: 'shipping_state',
296                                postcode: 'shipping_postcode',
297                                country: 'shipping_country',
298                                phone: 'shipping_phone'
299                            };
300
301                            Object.keys(shippingMap).forEach(function (key) {
302                                if (shipping[key] !== undefined && shipping[key] !== null) {
303                                    const fieldName = shippingMap[key];
304                                    const $field = jQuery('[name="' + fieldName + '"]');
305                                    if ($field.length) {
306                                        $field.val(shipping[key]).trigger('change');
307                                    }
308                                }
309                            });
310                        }
311
312                        jQuery(document.body).trigger('update_checkout');
313                    }
314                    resolve();
315                },
316                error: function () {
317                    resolve();
318                }
319            });
320        });
321    }
322
323    // Initialize Flex microform for saved card CVV validation.
324    function initFlexForToken(tokenId) {
325
326        // Check if Flex is available and we have required settings.
327        var flexCaptureContext = document.getElementById("flex_cvv_token_data").value;
328        if (typeof Flex !== 'undefined' && tokenId && visa_acceptance_ajaxUCObj['saved_card_cvv'] && flexCaptureContext) {
329            
330            
331            if (flexCaptureContext && typeof flexCaptureContext === 'string') {
332                var jwtParts = flexCaptureContext.split('.');
333                if (jwtParts.length === 3) {
334                    
335                    try {
336                        var flex = new Flex(flexCaptureContext);
337                        
338                        var microform = flex.microform('card', { 
339                            styles: {
340                                'input': {
341                                    'font-size': '14px',
342                                    'font-family': 'inherit',
343                                    'color': '#333',
344                                    'padding': '8px'
345                                }
346                            },
347                        });
348                        
349                        var cardType = '';
350                        if (visa_acceptance_ajaxUCObj['token_type'] && tokenId) {
351                            cardType = visa_acceptance_ajaxUCObj['token_type'][tokenId] || '';
352                        }
353                        var max_length = ('AMEX' == cardType) ? 4 : 3;
354                        var securityCode = microform.createField('securityCode', { 
355                            placeholder: '•••',
356                            maxLength: max_length
357                        });                
358                        
359                        // Wait for DOM to be ready and load CVV field.
360                        setTimeout(() => {
361                            var containerElement = document.getElementById('flex-cvv-' + encodeURI(tokenId));
362                            
363                            if (!containerElement) {
364                                return;
365                            }
366                            
367                            try {
368                                securityCode.load(containerElement);
369                                flexInstances[tokenId] = {
370                                    microform: microform,
371                                    securityCode: securityCode,
372                                    tokenId: tokenId,
373
374                                    createToken: function() {
375                                        return new Promise((resolve, reject) => {
376                                            try {
377                                                const options = {};
378                                                
379                                                microform.createToken(options, (err, flexjwtToken) => {
380                                                    if (err) {
381                                                        console.error('An error occurred while generating the Microform token:', err);
382                                                        reject(err);
383                                                    } else {
384                                                        resolve({ token: flexjwtToken });
385                                                    }
386                                                });
387                                            } catch (error) {
388                                                console.error('An unexpected error occurred during Microform token creation:', error);
389                                                reject(error);
390                                            }
391                                        });
392                                    }
393                                };
394                                
395                                flexFieldsValid[tokenId] = false;
396                                
397                                // Handle CVV field events.
398                                securityCode.on('change', function(data) {
399                                    flexFieldsValid[tokenId] = data.valid;
400                                    if (data.valid) {
401                                        jQuery('#error-' + encodeURI(tokenId)).hide();
402                                    }
403                                });
404                                
405                                // Hide the regular input field.
406                                jQuery('input[name="csc-saved-card-' + encodeURI(tokenId) + '"]').hide();
407                                
408                                // Show the parent container and Flex container only on success.
409                                jQuery('#token-' + encodeURI(tokenId)).show();
410                                jQuery('#flex-cvv-' + encodeURI(tokenId)).show();
411                                
412                            } catch (fieldError) {
413                                jQuery('#token-' + encodeURI(tokenId)).hide();
414                            }
415                        }, 100);
416                        
417                    } catch (error) {
418                        jQuery('#token-' + encodeURI(tokenId)).hide();
419                    }
420                } else {
421                    jQuery('#token-' + encodeURI(tokenId)).hide();
422                }
423            } else {
424                jQuery('#token-' + encodeURI(tokenId)).hide();
425            }
426        } else {
427            if (tokenId) {
428                jQuery('#token-' + encodeURI(tokenId)).hide();
429            }
430        }
431    }
432
433    function initExpressCheckout() {
434
435        var transientToken = document.getElementById("transientToken");
436        var captureContext = document.getElementById("ep_jwt_updated") ? (document.getElementById("ep_jwt_updated")?.value || null) : (document.getElementById("ep_jwt")?.value || null);
437
438        var showArgs = {
439            containers: {
440                paymentSelection: "#expressPaymentListContainer"
441            }
442        };
443
444        if (typeof Accept !== 'undefined' && captureContext) {
445            jQuery('#wc-error-failure').hide();
446
447            Accept(captureContext)
448                .then(function(accept) {
449                    return accept.unifiedPayments();
450                })
451                .then(function(up) {
452                    return up.show(showArgs);
453                })
454                .then(function(tt) {
455                    
456                    // Force Visa Unified Checkout as active method after checkout updates.
457                    const paymentMethodRadioId = "input[name='payment_method'][value='" + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id'] + "']";
458                    if( ! jQuery(paymentMethodRadioId).is(':checked') ) {
459                        jQuery(paymentMethodRadioId).prop('checked', true).trigger('click');
460                    }
461                    const gatewayRadioId = '#wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-use-new-payment-method';
462                    jQuery(gatewayRadioId).prop('checked', true).trigger('click');
463                                        
464                    // hide default payment method box.
465                    jQuery('.woocommerce-checkout-payment').hide();
466
467                    // show loader while processing.
468                    showExpressPayLoader();
469
470                    transientToken.value = tt;
471                    populateCheckoutFieldsFromTransientToken(tt, true).then(function () {
472                        if (jQuery('form#order_review').length > 0) {
473                            jQuery('form#order_review').submit();
474                        } 
475                        else {
476                            // Auto-accept terms & conditions for express pay so that
477                            // WooCommerce's terms checkbox validation does not block
478                            // the express pay flow (registered/admin users included).
479                            var $termsCheckbox = jQuery('input[name="terms"]');
480                            if ($termsCheckbox.length && !$termsCheckbox.is(':checked')) {
481                                $termsCheckbox.prop('checked', true);
482                            }
483                            isExpressPaySubmission = true;
484                            setTimeout(() => {
485                                jQuery('form.checkout').removeClass('processing');
486                                jQuery('form.checkout').submit();
487                            }, 200);
488                            hideExpressPayLoader();
489                        }
490                    });
491                })
492            .catch(function(error) {
493                jQuery('#wc-error-failure').show();
494                jQuery('#expressPaymentListContainer').hide();
495                // Show payment form back if express pay fails.
496                hideExpressPayLoader();
497                jQuery('.woocommerce-checkout-payment').show();
498            });
499        } else if (!captureContext) {
500            jQuery('#express_payment_form_load_error').show();
501        } else {
502            jQuery('#wc-error-failure').show();
503        }
504
505        if( jQuery("#wc-express-checkout-section").is(':hidden') ) {
506            jQuery('.checkout #wc-error-failure #wc-failure-error').hide();
507        }
508    }
509    // Listen for checkout validation errors and show payment form back.
510    jQuery(document.body).on('checkout_error', function() {
511        hideExpressPayLoader();
512        jQuery('.woocommerce-checkout-payment').show();
513    });
514    // Run on checkout load.
515    if(visa_acceptance_ajaxUCObj['enabled_payment_methods'].length !== 0){
516        jQuery(document.body).on('updated_checkout', initExpressCheckout);
517    }
518    // Run Express Checkout initialization only on Pay for Order page.
519    if ((window.location.href.indexOf('order-pay=') !== -1 || window.location.pathname.indexOf('/order-pay/') !== -1) && visa_acceptance_ajaxUCObj['enabled_payment_methods'].length !== 0 ) {
520        initExpressCheckout();
521    }
522
523    function handlePaymentSelection(event) {
524        // Remove the tag when calling the handle function.
525        jQuery('#buttonPaymentListContainer').remove();
526        var buttonPaymentListContainer = $('<div>', {
527            id: 'buttonPaymentListContainer'
528        });
529        var checkoutEmbeddedButton = createButton('checkoutEmbedded', 'Loading...');
530        var checkoutSidebarButton = createButton('checkoutSidebar', 'Loading...');
531
532        buttonPaymentListContainer.append(checkoutEmbeddedButton, checkoutSidebarButton);
533
534        async function deriveAESKeyFromString(stringVal) {
535            const encoder = new TextEncoder();
536            const valIdData = encoder.encode(stringVal);
537        
538            // Hash the valId using SHA-256 and take the initial 32 bytes for AES-256.
539            const hashBuffer = await crypto.subtle.digest('SHA-256', valIdData);
540            return new Uint8Array(hashBuffer).slice(0, 32);
541        }
542        
543        async function encryptData(data, stringVal) {
544            const extId = crypto.getRandomValues(new Uint8Array(12));//iv:extId
545            const encoder = new TextEncoder();
546            const encodedData = encoder.encode(data);
547        
548            try {
549                const valId = await deriveAESKeyFromString(stringVal);//key:valId
550                const cryptoKey = await crypto.subtle.importKey(
551                    'raw',
552                    valId,
553                    { name: 'AES-GCM' },
554                    false,
555                    [visa_acceptance_ajaxUCObj['encrypt_const']]
556                );
557        
558                const encryptedBuffer = await crypto.subtle.encrypt(
559                    { name: 'AES-GCM', iv: extId },
560                    cryptoKey,
561                    encodedData
562                );
563        
564                const encryptedArray = new Uint8Array(encryptedBuffer);
565                const refIdLength = 16;
566                const ciphertext = encryptedArray.slice(0, encryptedArray.length - refIdLength);
567                const refId = encryptedArray.slice(encryptedArray.length - refIdLength);//tag:refId
568        
569                // Return base64 encoded values.
570                return {
571                    encrypted: btoa(String.fromCharCode(...ciphertext)),
572                    extId: btoa(String.fromCharCode(...extId)),
573                    refId: btoa(String.fromCharCode(...refId))
574                };
575            } catch (error) {
576                return null;
577            }
578        }
579
580        var tokencnt = visa_acceptance_ajaxUCObj['token_cnt'];
581        if ( visa_acceptance_ajaxUCObj['tokenization'] === 'no' ) {
582            // Force "use new card" option to be selected by default.
583            jQuery('#wc-credit-card-use-new-payment-method-div').show();
584            if (jQuery('#wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-use-new-payment-method').length > 0) {
585                jQuery('#wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-use-new-payment-method').prop('checked', true);
586            }
587            jQuery('#buttonPaymentListContainer').show();
588            jQuery('#place_order').hide();
589        } else {
590            if (tokencnt != "0") {
591                if (jQuery('#wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-use-new-payment-method').is(':checked')) {
592                    jQuery('#buttonPaymentListContainer').show();
593                    jQuery('#place_order').hide();
594                } else {
595                    jQuery('#buttonPaymentListContainer').hide();
596                    jQuery('.wc-payment-gateway-payment-form-manage-payment-methods').show();
597                    jQuery('#wc-credit-card-use-new-payment-method-div').show();
598                    jQuery('#place_order').show();
599                    jQuery('#wc-unified-checkout-normal-save-token-div').hide();
600                };
601            }
602        }
603        var tknval = jQuery('input[name=wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-payment-token]:checked').val();
604        
605        // Hide CVV containers for ALL eCheck tokens on page load.
606        if (visa_acceptance_ajaxUCObj['token_type']) {
607            jQuery.each(visa_acceptance_ajaxUCObj['token_type'], function(tokenId, tokenType) {
608                if (tokenType === 'eCheck') {
609                    jQuery('#token-' + tokenId).hide();
610                }
611            });
612        }
613        
614        // Check if currently selected token is eCheck - don't initialize CVV for eCheck tokens.
615        var isEcheck = visa_acceptance_ajaxUCObj['token_type'] && visa_acceptance_ajaxUCObj['token_type'][tknval] === 'eCheck';
616        
617        if (tknval && visa_acceptance_ajaxUCObj['saved_card_cvv'] && !isEcheck) {
618            setTimeout(() => {
619                initFlexForToken(tknval);
620            }, 100);
621        }
622        jQuery(`input[name="csc-saved-card-${encodeURI(tknval)}"]`).on('input', async function () {
623            let rawValue = jQuery(this).val().replace(/\D/g, '');
624            let valId = visa_acceptance_ajaxUCObj['token_key'];
625            jQuery(this).val(rawValue);
626            
627            if ((rawValue.length === 3 || rawValue.length === 4)) {
628                const encryptedData = await encryptData(rawValue, valId);
629                  
630                if (encryptedData) {
631        
632                    // Ensure hidden fields for extId, and refId are created if needed.
633                    if ($(`input[name="extId-${encodeURI(tknval)}"]`).length === 0) {
634                        jQuery(this).after(`
635                            <input type="hidden" name="csc-saved-card-${encodeURI(tknval)}" value="${encryptedData.encrypted}">
636                            <input type="hidden" name="extId-${encodeURI(tknval)}" value="${encryptedData.extId}">
637                            <input type="hidden" name="refId-${encodeURI(tknval)}" value="${encryptedData.refId}">
638                        `);
639                    } else {
640                        $(`input[name="csc-saved-card-${encodeURI(tknval)}"]`).val(encryptedData.encrypted);
641                        $(`input[name="extId-${encodeURI(tknval)}"]`).val(encryptedData.extId);
642                        $(`input[name="refId-${encodeURI(tknval)}"]`).val(encryptedData.refId);
643                    }
644                    jQuery(this).val(rawValue);
645                }
646            }
647        });
648        //Fetch token selected
649        var tknval = jQuery('input[name=wc-' + visa_acceptance_aja
649xUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-payment-token]:checked').val();
650        jQuery('input[name=wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-payment-token]').click(function() {
651            jQuery('#wc-unified-checkout-tokenize-payment-method').prop('checked', false);
652            jQuery('.cvv-div').hide();
653            jQuery('.wc-unified-checkout-saved-card #wc-unified-checkout-saved-card-cvn').val('');
654            
655            //Fetch token selected.
656            var tknval = jQuery(this).val();
657            
658            jQuery('[id^="flex-cvv-"]').hide();
659            jQuery('input[name^="csc-saved-card-"]').hide();
660            jQuery('[id^="token-"]').hide();
661            
662            // Initialize Flex for the newly selected token (it will show the div if successful).
663            // Check if token is eCheck - don't initialize CVV for eCheck tokens.
664            var isEcheckToken = visa_acceptance_ajaxUCObj['token_type'] && visa_acceptance_ajaxUCObj['token_type'][tknval] === 'eCheck';
665            if (tknval && visa_acceptance_ajaxUCObj['saved_card_cvv'] && !isEcheckToken) {
666                setTimeout(() => {
667                    initFlexForToken(tknval);
668                }, 100);
669            }
670            jQuery(`input[name="csc-saved-card-${encodeURI(tknval)}"]`).on('input', async function () {
671            let rawValue = jQuery(this).val().replace(/\D/g, '');
672            let valId = visa_acceptance_ajaxUCObj['token_key'];
673            jQuery(this).val(rawValue);
674            
675            if ((rawValue.length === 3 || rawValue.length === 4)) {
676                const encryptedData = await encryptData(rawValue, valId);
677                  
678                if (encryptedData) {
679        
680                    // Ensure hidden fields for extId, and refId are created if needed.
681                    if ($(`input[name="extId-${encodeURI(tknval)}"]`).length === 0) {
682                        jQuery(this).after(`
683                            <input type="hidden" name="csc-saved-card-${encodeURI(tknval)}" value="${encryptedData.encrypted}">
684                            <input type="hidden" name="extId-${encodeURI(tknval)}" value="${encryptedData.extId}">
685                            <input type="hidden" name="refId-${encodeURI(tknval)}" value="${encryptedData.refId}">
686                        `);
687                    } else {
688                        $(`input[name="csc-saved-card-${encodeURI(tknval)}"]`).val(encryptedData.encrypted);
689                        $(`input[name="extId-${encodeURI(tknval)}"]`).val(encryptedData.extId);
690                        $(`input[name="refId-${encodeURI(tknval)}"]`).val(encryptedData.refId);
691                    }
692                    jQuery(this).val(rawValue);
693                }
694            }
695        });
696            jQuery('input[name=wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-payment-token]').not(':checked').each(function() {
697                var tknval = jQuery(this).val();
698                jQuery("#token-" + encodeURI(tknval)).hide();
699            });
700            if (jQuery('#wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-use-new-payment-method').is(':checked')) {
701                //Add at Checkout page below Use a new card.
702                if(!jQuery('#buttonPaymentListContainer').length){
703                    $('#wc-credit-card-use-new-payment-method-div').append(buttonPaymentListContainer);
704                }
705                var transientToken = document.getElementById("transientToken");
706                var captureContext = document.getElementById("jwt_updated")? document.getElementById("jwt_updated").value : (document.getElementById("jwt") ? document.getElementById("jwt").value : null);
707                var showArgs = {
708                    containers: {
709                        //checkout with card Payment box.
710                        paymentSelection: "#buttonPaymentListContainer"
711                    }
712                };
713
714                if (typeof Accept !== 'undefined') {
715                    jQuery('#wc-error-failure').hide();
716                    Accept(captureContext)
717                        .then(function(accept) {
718                            return accept.unifiedPayments();
719                        })
720                        .then(function(up) {
721                            return up.show(showArgs);
722                        })
723                        .then(function(tt) {
724                            transientToken.value = tt;
725                            jQuery("body").css({"overflow": "auto"});
726                            populateCheckoutFieldsFromTransientToken(tt, false).then(function () {
727                                if (jQuery('form#order_review').length > 0) {
728                                    jQuery('form#order_review').submit();
729                                } else if (jQuery('form#add_payment_method').length > 0) {
730                                    add_payment_method_token = tt;
731                                    jQuery("form#add_payment_method").submit();
732                                } else {
733                                    $('form.checkout').removeClass('processing');
734                                    $('form.checkout').submit();
735                                }
736                            });
737
738                        }).catch(function(error) {
739                            jQuery('#wc-error-failure').show();
740                            jQuery('#buttonPaymentListContainer').hide();
741                        });
742                } else {
743                    buttonPaymentListContainer.append(errorMessagePara);
744                }
745
746                jQuery('#buttonPaymentListContainer').show();
747                jQuery('#place_order').hide();
748                jQuery('#wc-unified-checkout-normal-save-token-div').show();
749            } else {
750                jQuery('#place_order').show();
751                jQuery('#buttonPaymentListContainer').hide();
752                jQuery('#wc-unified-checkout-normal-save-token-div').hide();
753            };
754        });
755       
756        if ($("input[name$='payment_method'][value$='" + visa_acceptance_aja
756xUCObj['visa_acceptance_solutions_uc_id'] +"']").is(':checked')) {
757            if (jQuery('#wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-use-new-payment-method').length == 0 ||  jQuery('#wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-use-new-payment-method').is(':checked')) {
758                $("#place_order").hide();                  
759                if (event.type == 'init_add_payment_method') {
760                    // At My account -> Add Payment page.
761                    if(!jQuery('#buttonPaymentListContainer').length){
762                        jQuery('.woocommerce-PaymentBox.woocommerce-PaymentBox--' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id'] + '.payment_box.payment_method_' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id']).append(buttonPaymentListContainer);
763                    }
764                }
765                    //checkout page - no saved payment method.
766                var save_token_checkbox_div = $('#wc-unified-checkout-normal-save-token-div');
767                if(save_token_checkbox_div.length){
768                    //save card enabled, insert before checkbox div
769                    buttonPaymentListContainer.insertBefore(save_token_checkbox_div);
770                }else{
771                    //If save card option not enabled, append directly to parent div
772                    if(!jQuery('#buttonPaymentListContainer').length){
773                        $('.payment_box.payment_method_' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id']).append(buttonPaymentListContainer);
774                    }
775                }
776                var transientToken = document.getElementById("transientToken");
777                var captureContext = document.getElementById("jwt_updated")? document.getElementById("jwt_updated").value : (document.getElementById("jwt") ? document.getElementById("jwt").value : null);
778                var showArgs = {
779                    containers: {
780                        paymentSelection: "#buttonPaymentListContainer"
781                    }
782                };
783                if (typeof Accept !== 'undefined') {
784                    jQuery('#wc-error-failure').hide();
785                    Accept(captureContext)
786                        .then(function(accept) {
787                            return accept.unifiedPayments();
788                        })
789                        .then(function(up) {
790                            return up.show(showArgs);
791                        })
792                        .then(function(tt) {
793                            transientToken.value = tt;
794                            // Adding to make the overflow auto.
795                            jQuery("body").css({"overflow": "auto"});
796                            populateCheckoutFieldsFromTransientToken(tt, false).then(function () {
797                                if (jQuery('form#order_review').length > 0) {
798                                    jQuery('form#order_review').submit();
799                                } else if (jQuery('form#add_payment_method').length > 0) {
800                                    add_payment_method_token = tt;
801                                    jQuery("form#add_payment_method").submit();
802                                } else {
803                                    $('form.checkout').removeClass('processing');
804                                    $('form.checkout').submit();
805                                }
806                            });
807
808                        }).catch(function(error) {
809                            jQuery('#wc-error-failure').show();
810                            jQuery('#buttonPaymentListContainer').hide();
811                        });
812                } else {
813                    buttonPaymentListContainer.append(errorMessagePara);
814                }
815
816            } else {
817                buttonPaymentListContainer.append(errorMessagePara);
818            }
819
820        } else {
821            $("#place_order").show();
822            $('.wc_payment_method.payment_method_' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id']).find('#buttonPaymentListContainer').empty();
823        } 
824        if (event.type == 'init_add_payment_method') {
825            firstLoadFlag = true;
826
827            function checkAndTrigger() {
828                if ($("input[name$='payment_method'][value$='"+ visa_acceptance_aja
828xUCObj['visa_acceptance_solutions_uc_id'] +"']").is(':checked') && !isEventTriggered) {
829                    $(document.body).trigger('init_add_payment_method');
830                    isEventTriggered = true; // Set the flag to true once the event is triggered.
831                } else if (!$("input[name$='payment_method'][value$='"+ visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id']+"']").is(':checked')) {
832                    isEventTriggered = false; // Reset the flag if the checkbox is unchecked.
833                }
834            }
835
836            function checkAndRemove() {
837                if (!$("input[name$='payment_method'][value$='"+ visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id']+"']").is(':checked')) {
838                    $("#place_order").show();
839                    $('li.payment_method_' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id']).find('#buttonPaymentListContainer').empty();
840                }
841            }
842
843            setInterval(checkAndTrigger, 1000);
844            setInterval(checkAndRemove, 1000);
845        }
846    }
847
848    $('body').on('payment_method_selected', handlePaymentSelection);
849    // Whenever there is an error it will call the function.
850    $('body').on('updated_checkout', handlePaymentSelection);
851    $('body').on('init_add_payment_method', function(event) {
852        handlePaymentSelection(event);
853    });
854
855
856    //Code for Special case of pay-order page
857    //This extracts order_id to pass it to custom getOrderIDPayPage
858    var hrefUrl = window.location.href;
859    var url = new URL(hrefUrl);
860    var orderPayValue = url.searchParams.get("order-pay");
861    var startIndex = hrefUrl.indexOf("/order-pay/") + "/order-pay/".length;
862    var endIndex = hrefUrl.indexOf("/", startIndex);
863    var extractedNumber;
864    if (startIndex !== -1 && endIndex !== -1 && hrefUrl.indexOf("/order-pay/") !== -1) {
865        extractedNumber = hrefUrl.substring(startIndex, endIndex);
866    } else if (orderPayValue !== null) {
867        extractedNumber = orderPayValue;
868    }
869
870    var repeatFlag = false;
871
872    jQuery('form#order_review').on('submit', async function(e) {
873        if ($("input[name$='payment_method'][value$='" + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id'] +"']").is(':checked')) {
874            var valTkn = jQuery('input[name=wc-' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id_hyphen'] +'-payment-token]:checked').val();
875            var trans_token = document.getElementById("transientToken").value;
876            var solution_id = '';
877            if (trans_token) {
878                const parts = trans_token.split('.');
879                const decodedPayload = atob(parts[1]);
880
881                const payload = JSON.parse(decodedPayload);
882
883                if (payload?.content?.processingInformation?.paymentSolution?.value !== undefined) {
884                    solution_id = payload.content.processingInformation.paymentSolution.value;
885                }
886
887
888            }
889            
890            // Check if token is eCheck - skip CVV validation for eCheck.
891            var isEcheckPayOrder = visa_acceptance_ajaxUCObj['token_type'] && visa_acceptance_ajaxUCObj['token_type'][valTkn] === 'eCheck';
892            
893            // Check if using saved card with CVV required.
894            if (valTkn && visa_acceptance_ajaxUCObj['saved_card_cvv'] && !isEcheckPayOrder) {
895                // Check if Flex is being used for this token
896                if (flexInstances[valTkn]) {
897                    if (!flexFieldsValid[valTkn]) {
898                        jQuery('#error-' + encodeURI(valTkn)).show();
899                        e.preventDefault();
900                        e.stopImmediatePropagation();
901                        return false;
902                    }
903
904                    try {
905                        e.preventDefault();
906                        e.stopImmediatePropagation();
907                        
908                        var flexTokenResponse = await flexInstances[valTkn].createToken();
909                        
910                        if (flexTokenResponse && flexTokenResponse.token) {
911                            // Add the flex token to a hidden field
912                            var flexTokenField = jQuery('input[name="flex_cvv_token"]');
913                            if (flexTokenField.length === 0) {
914                                jQuery('form#order_review').append('<input type="hidden" name="flex_cvv_token" value="' + flexTokenResponse.token + '">');
915                            } else {
916                                flexTokenField.val(flexTokenResponse.token);
917                            }
918                            if (!window.orderReviewFlexSubmission) {
919                                window.orderReviewFlexSubmission = true;
920                                // Check if payer authentication flow should handle submission
921                                var isPayerAuthFlow = typeof visa_acceptance_uc_payer_auth_param !== 'undefined' 
922                                    && visa_acceptance_uc_payer_auth_param['payment_method'] == 'unified_checkout' 
923                                    && solution_id != '001' 
924                                    && solution_id != '027';
925                                if (!isPayerAuthFlow) {
926                                    var form = jQuery('form#order_review');
927                                    form.off('submit');
928                                    form.submit();
929                                    return false;
930                                }
931                            }
932                        } else {
933                            jQuery('#error-' + encodeURI(valTkn)).show();
934                            return false;
935                        }
936                    } catch (error) {
937                        jQuery('#error-' + encodeURI(valTkn)).show();
938                        return false;
939                    }
940                } else {
941                    var security_code = jQuery('input[name=csc-saved-card-' + encodeURI(valTkn) + ']').val();
942                    if (( !(typeof security_code == 'undefined') && (security_code == '' || security_code.length > 4 || security_code.length < 3))) {
943                        jQuery('#error-' + encodeURI(valTkn)).show();
944                        e.preventDefault();
945                        e.stopImmediatePropagation();
946                        return false;
947                    }
948                }
949            }
950
951            if (typeof visa_acceptance_uc_payer_auth_param !== 'undefined' && solution_id != '001' && solution_id != '027') {
952                e.preventDefault();
953            }
954            if (typeof payer_auth_param == 'undefined') {
955                if (!repeatFlag) {
956                    repeatFlag = true;
957
958                    if ((jQuery('#payment_method_' + visa_acceptance_ajaxUCObj['visa_acceptance_solutions_uc_id']).is(':checked'))) {
959                        if (typeof visa_acceptance_uc_payer_auth_param !== 'undefined' && visa_acceptance_uc_payer_auth_param['payment_method'] == 'unified_checkout' && solution_id != '001' && solution_id != '027') {
960                            addLoader();
961                            showLoader();
962                            getOrderIDPayPage(extractedNumber);
963                        } else {
964                            return true;
965                        }
966
967                    }
968                }
969            }
970        }
971    });
972
973    
974    // Function to move Visa Acceptance payment method after terms and conditions
975    function movePaymentMethodAfterTerms() {
976        var $termsWrapper = $('.woocommerce-terms-and-conditions-wrapper');
977        var $visaPaymentMethod = $('.payment_box.payment_method_visa_acceptance_solutions_unified_checkout');
978        var $paymentMethods = $('.wc_payment_methods.payment_methods.methods');
979        
980        // Check if both elements exist
981        if ($termsWrapper.length && $visaPaymentMethod.length) {
982            // Check if it's not already moved
983            if (!$visaPaymentMethod.hasClass('moved-after-terms') && $paymentMethods.length) {
984                // Add a class to track that it's been moved
985                $visaPaymentMethod.addClass('moved-after-terms');
986                
987                // Move the actual payment method element after terms and conditions
988                $visaPaymentMethod.detach().insertAfter($termsWrapper);
989                var $form = $('form.checkout');
990                $visaPaymentMethod.find(
991                    '#transientToken, #errorMessage, #jwt, #jwt_updated, #ep_jwt, #ep_jwt_updated, #payer_auth_enabled, #flex_cvv_token_data'
992                ).each(function() {
993                    $form.append($(this).detach());
994                });
995                
996                // Setup radio button synchronization
997                setupPaymentMethodRadioSync();
998            }
999        }
1000    }
1001    
1002    // Function to ensure only one payment method radio is selected at a time
1003    function setupPaymentMethodRadioSync() {
1004        // Handle clicks on the moved Visa Acceptance radio button
1005        $(document).on('change', '.payment_box.payment_method_visa_acceptance_solutions_unified_checkout.moved-after-terms > input[type="radio"][name="payment_method"]', function() {
1006            if ($(this).is(':checked')) {
1007                // Uncheck all other payment method radios in the original list
1008                $('.wc_payment_methods.payment_methods.methods input[type="radio"][name="payment_method"]').prop('checked', false);
1009                
1010                // Show the payment box
1011                $('.payment_box.payment_method_visa_acceptance_solutions_unified_checkout.moved-after-terms .payment_box').slideDown();
1012                
1013                // Trigger WooCommerce payment method selected event
1014                $(document.body).trigger('payment_method_selected');
1015            }
1016        });
1017        
1018        // Handle clicks on other payment method radios in the main payment methods list
1019        $(document).on('change', '.wc_payment_methods.payment_methods.methods input[type="radio"][name="payment_method"]', function() {
1020            if ($(this).is(':checked')) {
1021                // Uncheck the moved Visa Acceptance main radio button
1022                $('.payment_box.payment_method_visa_acceptance_solutions_unified_checkout.moved-after-terms > input[type="radio"][name="payment_method"]').prop('checked', false);
1023                
1024                // Uncheck all nested token selection radios (saved cards and "use new card")
1025                $('.payment_box.payment_method_visa_acceptance_solutions_unified_checkout.moved-after-terms input[type="radio"]').not('[name="payment_method"]').prop('checked', false);
1026                
1027                // Hide the payment box
1028                $('.payment_box.payment_method_visa_acceptance_solutions_unified_checkout.moved-after-terms .payment_box').slide
1028Up();
1029            }
1030        });
1031    }
1032    
1033    // Run after WooCommerce updates checkout
1034    $(document.body).on('updated_checkout', function() {
1035        movePaymentMethodAfterTerms();
1036    });
1037
1038 })(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.