PageSourceSearch

https://kabulnow.com/wp-content/plugins/paid-member-subscriptions/…/assets/front-end-connect.js?ver=3.0.8

js kabulnow.com collected 2026-09-24 07:53:00 UTC 44,047 bytes, 1,148 lines download raw bytes

1/**
2 * Initialize Stripe Connect payment gateway
3 * @param {jQuery} $ - jQuery instance
4 */
5async function pms_stripe_maybe_load_gateway( $ ) {
6
7    if( !( $('#stripe-pk').length > 0 ) ){
8        return false
9    }
10
11    var stripe_pk = $( '#stripe-pk' ).val()
12
13    //compatibility with PB conditional logic. if there are multiple subscription plans fields and the first one is hidden then it won't have a value attribute because of conditional logic
14    if( typeof stripe_pk == 'undefined' || stripe_pk == '' )
15        stripe_pk = $('#stripe-pk').attr('conditional-value')
16
17    if( typeof stripe_pk == 'undefined' )
18        return false
19
20    if ( typeof pms.stripe_connected_account == 'undefined' || pms.stripe_connected_account == '' ){
21        console.log( 'Before you can accept payments, you need to connect your Stripe Account by going to Dashboard -> Paid Member Subscriptions -> Settings -> Payments.' )
22        return false
23    }
24
25    var elements                     = false
26    var elements_setup_intent        = false
27    var update_elements_setup_intent = false
28    var stripe                       = false
29
30    var $payment_element        = ''
31    var $elements_instance_slug = ''
32
33    var cardIsEmpty = true
34    var recreating_payment_element = false
35    var email_change_debounce_timer = null
36
37    var subscription_plan_selector = 'input[name=subscription_plans]'
38    var paygate_selector           = 'input.pms_pay_gate'
39
40    var stripe_appearance = {}
41
42    if( pms.pms_elements_appearance_api )
43        stripe_appearance = pms.pms_elements_appearance_api
44
45    var StripeData = {
46        stripeAccount: pms.stripe_connected_account
47    }
48
49    if( pms.stripe_locale )
50        StripeData.locale = pms.stripe_locale
51
52    stripe = Stripe( stripe_pk, StripeData )
53
54    var stripe_payment_intent_options = {
55        mode                 : 'payment',
56        currency             : pms.currency,
57        amount               : 1099,
58        paymentMethodCreation: 'manual',
59        appearance           : stripe_appearance,
60    }
61
62    var stripe_setup_intent_options = {
63        mode                 : 'setup',
64        currency             : pms.currency,
65        paymentMethodCreation: 'manual',
66        appearance           : stripe_appearance,
67    }
68
69    if( pms.off_session_payments && pms.off_session_payments == 1 ){
70        stripe_payment_intent_options.setupFutureUsage = 'off_session'
71        stripe_setup_intent_options.setupFutureUsage   = 'off_session'
72    }
73
74    if( pms.pms_customer_session ){
75        stripe_payment_intent_options.customerSessionClientSecret = pms.pms_customer_session
76        stripe_setup_intent_options.customerSessionClientSecret   = pms.pms_customer_session
77    }
78
79    elements              = stripe.elements( stripe_payment_intent_options )
80    elements_setup_intent = stripe.elements( stripe_setup_intent_options )
81
82    stripeConnectInit()
83
84    // Validate currency for currently selected subscription plan if MC add-on 
84is active
85    if ( pms.pms_mc_addon_active )
86        await pms_stripe_validate_sdk_checkout_currency( $( $pms_checked_subscription ) );
87
88    // Declare reCaptcha callback as already executed
89    if( typeof pms_initialize_recaptcha_v3 == 'function' ){
90        window.pmsRecaptchaCallbackExecuted = true
91        
92        jQuery('.pms-form').off('submit', pms_initialize_recaptcha_v3 );
93    }
94
95    if( typeof wppbInitializeRecaptchaV3 == 'function' ){
96        window.wppbRecaptchaCallbackExecuted = true
97    }
98
99    // Update Stripe Payment Intent on subscription plan change
100    $(document).on('click', subscription_plan_selector, async function ( event ) {
101
102        if ( pms.pms_mc_addon_active ){
103            await pms_stripe_validate_sdk_checkout_currency( $(this) );
104        }
105
106        stripeConnectInit()
107
108    })
109
110    /**
111     * Resolves the Stripe setup_future_usage for a plan input from its recurring config and the customer's renewal choice
112     *
113     * - 'off_session' when the plan recurs (always-recurring, opt-in with the auto-renew box ticked, or the site default forcing recurring)
114     * - null when it does not recur, undefined when the input carries no recurring config so callers leave the current value untouched
115     * - shared so the primary plan and add-on items (e.g. Order Bumps) derive setup_future_usage from one rule and stay in agreement with the server-side PaymentIntent
116     *
117     */
118    function pms_stripe_connect_setup_future_usage_for_input( $input ) {
119
120        let recurring = $input.data( 'recurring' )
121
122        if( recurring == 0 || recurring == 1 ){
123
124            let default_recurring = $('input[type="hidden"][name="pms_default_recurring"]').val()
125
126            if( default_recurring == 2 )
127                return 'off_session'
128            else if( default_recurring == 3 )
129                return null
130            else
131                return $('.pms-subscription-plan-auto-renew input[name="pms_recurring"]').prop('checked') ? 'off_session' : null
132
133        } else if( recurring == 2 ){
134            return 'off_session'
135        } else if( recurring == 3 ){
136            return null
137        }
138
139        return undefined
140
141    }
142
143    // expose the rule so add-ons resolve setup_future_usage with the same logic as the primary plan
144    $.pms_stripe_connect_setup_future_usage_for_input = pms_stripe_connect_setup_future_usage_for_input
145
146    // Re-run mode selection when an addon signals a checkout state change (e.g. Order Bumps toggling line items)
147    $(document).on( 'pms_recompute_payment_mode', function() {
148        stripeConnectInit()
149    })
150
151    $(document).on('click', '.pms-subscription-plan-auto-renew input[name="pms_recurring"]', function ( event ) {
152
153        if( $(this).prop('checked') ){
154            elements.update( { setupFutureUsage: 'off_session' } );
155        } else {
156            elements.update( { setupFutureUsage: null } );
157        }
158
159    })
160
161    // This was added for Link support.
162    // After the user email is entered, the payment element is destroyed and then recreated using the new parameters.
163    $(document).on('change', '.pms-form .pms-user-email-field input[name="user_email"], .wppb-register-user input[name="email"], .pms-form .pms-billing-details input[name="pms_billing_email"]', function ( event ) {
164
165        // Skip if already recreating
166        if( recreating_payment_element ){
167            return
168        }
169
170        if( $('input[type=hidden][name=pay_gate]').val() != 'stripe_connect' && $('input[type=radio][name=pay_gate]:checked').val() != 'stripe_connect' )
171            return
172
173        if( $('input[type=hidden][name=pay_gate]').is(':disabled') || $('input[type=radio][name=pay_gate]:checked').is(':disabled') )
174            return
175
176        let element = $(this)
177        let email = $(this).val()
178
179        // Clear any pending debounce timer
180        if( email_change_debounce_timer ){
181            clearTimeout( email_change_debounce_timer )
182        }
183
184        if( email.length > 0 ){
185            
186            // Disable the input to prevent multiple submissions
187            element.attr('disabled', true)
188            
189            pms_stripe_show_spinner()
190
191            email_change_debounce_timer = setTimeout( function(){
192                
193                recreating_payment_element = true
194
195                // Only destroy if element exists
196                if( $payment_element && $payment_element != '' ){
197                    $payment_element.destroy()
198                    $payment_element = ''
199                }
200
201                setTimeout( function(){
202                    stripeConnectInit()
203                    element.attr('disabled', false)
204                    recreating_payment_element = false
205                }, 300 )
206
207            }, 250 )
208        }
209
210    })
211
212    // Discount applied
213    $(document).on('pms_discount_success', stripeConnectInit )
214    $(document).on('pms_discount_error', stripeConnectInit )
215    
216    // Update elements price when taxes are applied or removed
217    $(document).on('pms_tax_applied', function ( event, data ) {
218
219        if( data.total > 0 ){
220            elements.update( { amount: pms_stripe_convert_amount_to_cents( data.total ) } );
221        }
222
223    })
224
225    $(document).on('pms_tax_removed', function ( event ) {
226
227        if( typeof $pms_checked_subscription != 'undefined' ){
228
229            let price = $pms_checked_subscription.data( 'price' )
230
231            if( price > 0 ){
232                elements.update( { amount: pms_stripe_convert_amount_to_cents( price ) } );
233            }
234        }
235
236    })
237
238    // Show credit card details on the update payment method form
239    if ( $( 'input[name="pms_update_payment_method"]' ).length > 0 && $( '.pms-paygate-extra-fields-stripe_connect' ).length > 0 ){
240        $('.pms-paygate-extra-fields-stripe_connect').show()
241    }
242
243    // Paid Member Subscription submit buttons
244    var payment_buttons  = 'input[name=pms_register], ';
245        payment_buttons += 'input[name=pms_new_subscription], ';
246        payment_buttons += 'input[name=pms_change_subscription], ';
247        payment_buttons += 'input[name=pms_upgrade_subscription], ';
248        payment_buttons += 'input[name=pms_renew_subscription], ';
249        payment_buttons += 'input[name=pms_confirm_retry_payment_subscription], ';
250
251    // Profile Builder submit buttons
252    payment_buttons += '.wppb-register-user input[name=register]';
253
254    // WPPB Recaptcha
255    $(document).on( 'wppb_invisible_recaptcha_success', stripeConnectPaymentGatewayHandler )
256
257    $(document).on('submit', '.pms-form', async function (e) {
258
259        if( e.target && ( jQuery( e.target ).attr('id') == 'pms_recover_password_form' || jQuery( e.target ).attr('id') == 'pms_new_password_form' || jQuery( e.target ).attr('id') == 'pms_login' ) )
260            return
261
262        var target_button = $('input[type="submit"], button[type="submit"]', $(this)).not('#pms-apply-discount').not('input[name="pms_redirect_back"]')
263
264        // Email Confirmation using PB form
265        var form = $(this).closest( 'form' )
266
267        if( typeof form != 'undefined' && form && form.length > 0 && form.hasClass( 'pms-ec-register-form' ) ){
268
269            stripeConnectPaymentGatewayHandler(e, target_button)
270
271        // Skip if the Go Back button was pressed
272        } else if ( !e.originalEvent || !e.originalEvent.submitter || $(e.originalEvent.submitter).attr('name') != 'pms_redirect_back' ) {
273
274            if ( $(e.originalEvent.submitter).attr('name') == 'pms_update_payment_method' )
275                stripeConnectUpdatePaymentMethod(e, target_button)
276            else
277                stripeConnectPaymentGatewayHandler(e, target_button)
278
279        }
280
281    })
282
283    $(document).on('submit', '.wppb-register-user', function (e) {
284
285        if ( ! ( $( '.wppb-recaptcha .wppb-recaptcha-element', $(e.currentTarget) ).hasClass( 'wppb-invisible-recaptcha' ) ) ) {
286
287            var target_button = $('input[type="submit"], button[type="submit"]', $(this)).not('#pms-apply-discount').not('input[name="pms_redirect_back"]')
288
289            stripeConnectPaymentGatewayHandler(e, target_button)
290
291        }
292
293    })
294
295    async function stripeConnectPaymentGatewayHandler( e, target_button = false ){
296
297        if( $('input[type=hidden][name=pay_gate]').val() != 'stripe_connect' && $('input[type=radio][name=pay_gate]:checked').val() != 'stripe_connect' )
298            return
299
300        if( $('input[type=hidden][name=pay_gate]').is(':disabled') || $('input[type=radio][name=pay_gate]:checked').is(':disabled') )
301            return
302
303        e.preventDefault()
304
305        $.pms_form_remove_errors()
306
307        var current_button = $(this)
308
309        // Current submit button can't be determined from `this` context in case of the Invisible reCaptcha handler
310        if( e.type == 'wppb_invisible_recaptcha_success' || e.type == 'wppb_v3_recaptcha_success' || e.type == 'pms_v3_recaptcha_success' ){
311
312            // target_button is supplied to the handler starting with version 3.5.0 of Profile Builder, we use this for backwards compatibility
313            current_button = target_button == false ? $( 'input[type="submit"]', $( '.wppb-recaptcha-element' ).closest( 'form' ) ) : $( target_button )
314
315        } else if ( e.type == 'submit' ){
316
317            if( target_button != false )
318                current_button = $( target_button )
319
320        }
321
322        // Disable the button
323        current_button.attr( 'disabled', true )
324
325        return pms_stripe_maybe_validate_recaptcha( current_button, e ).then( async function( recaptcha_response ){
326
327            let target_elements = elements
328
329            if( $.pms_checkout_is_setup_intents() )
330                target_elements = elements_setup_intent
331
332            // let add-ons escalate setup_future_usage to off_session before the ConfirmationToken is built (e.g. a recurring Order Bump under a non-recurring primary), so the token matches the server-side PaymentIntent
333            // - escalate-only: it never downgrades the value the primary plan already required, it only forces off_session when an add-on needs the payment method stored for future renewals
334            if( $(document).triggerHandler( 'pms_filter_stripe_connect_setup_future_usage', [ null, current_button.closest( 'form' ) ] ) === 'off_session' )
335                target_elements.update( { setupFutureUsage: 'off_session' } )
336
337            const {error: submitError} = await target_elements.submit()
338
339            if (submitError) {
340                let message = ''
341
342                if( submitError.message && submitError.message != '' ){
343                    message = submitError.message
344                } else {
345                    message = 'An error occurred while processing your payment. Please try again.'
346                }
347
348                $.pms_stripe_add_credit_card_error( message )
349                $.pms_form_scrollTo( '#pms-paygates-wrapper', current_button )
350                return false
351            }
352
353            // Create the ConfirmationToken using the details collected by the Payment Element
354            const {error, confirmationToken}
354 = await stripe.createConfirmationToken({
355                elements : target_elements,
356            });
357
358            if (error) {
359
360                let message = ''
361
362                if( error.message && error.message != '' ){
363                    message = error.message
364                } else {
365                    message = 'An error occurred while processing your payment. Please try again.'
366                }
367
368                $.pms_stripe_add_credit_card_error( message )
369                $.pms_form_scrollTo( '#pms-paygates-wrapper', current_button )
370                return false
371            }
372
373            return pms_stripe_process_checkout( current_button, confirmationToken.id ).then( async function( response ){
374
375                // Handle validation errors
376                if( response.success == false && ( typeof response.data != 'undefined' || typeof response.wppb_errors != 'undefined' || typeof response.pms_errors != 'undefined' ) ){
377                    pms_stripe_handle_validation_errors( response, current_button )
378
379                    return false
380                } else if( response.success == false && typeof response.type != 'undefined' && response.type == 'use_stripe_sdk' ){
381
382                    let intent 
383
384                    if( $.pms_checkout_is_setup_intents() ){
385                        var { error, setupIntent } = await stripe.handleNextAction({
386                            clientSecret: response.client_secret
387                        });
388
389                        intent = setupIntent
390
391                    } else {
392                        var { error, paymentIntent } = await stripe.handleNextAction({
393                            clientSecret: response.client_secret
394                        });
395
396                        intent = paymentIntent
397                    }
398
399                    if( error && error.payment_intent ){
400                        intent = error.payment_intent
401                    } else if ( error && error.setup_intent ){
402                        intent = error.setup_intent
403                    }
404
405                    // Process the payment on the server
406                    const server_response = await pms_stripe_process_payment( intent, response, current_button )
407
408                    if ( typeof server_response.redirect_url != 'undefined' && server_response.redirect_url ){
409                        window.location.replace( server_response.redirect_url )
410
411                        return true
412                    }
413
414                    return false
415
416                }
417
418
419                // Redirect to the URL if the response contains a redirect URL
420                if ( typeof response.redirect_url != 'undefined' && response.redirect_url ){
421                    window.location.replace( response.redirect_url )
422                    return true
423                }
424
425                console.log( '[PMS Stripe] Something unexpected happened. Response: ' + response )
426
427                return false;
428
429            }) 
430
431        })
432    }
433
434    async function pms_stripe_process_checkout( current_button, confirmationToken ){
435
436        // grab all data from the form
437        var data = await $.pms_form_get_data( current_button, true )
438
439        if( confirmationToken ){
440            data['stripe_confirmation_token'] = confirmationToken
441        }
442
443        if( data == false )
444            return
445
446        // expand array values into separate appends so multi-value fields reach the wire as repeated entries
447        // - FormData.append stringifies array values via comma-join, collapsing them into a single scalar
448        var form_data = new FormData()
449
450        for (var key in data) {
451            if ( Array.isArray( data[key] ) ) {
452                data[key].forEach( function ( value ) {
453                    form_data.append( key, value )
454                } )
455            } else {
456                form_data.append( key, data[key] )
457            }
458        }
459
460        return fetch( pms.ajax_url, {
461            method     : 'post',
462            credentials: 'same-origin',   // Required for WordPress cookie authentication
463            body       : form_data
464        }).then(function (res) {
465            return res.json()
466        }).catch(error => {
467            console.error('Something went wrong:', error)
468            throw error
469        })
470
471    }
472
473    async function pms_stripe_process_payment( payment_intent, user_data, target_button ){
474
475        // update nonce
476        nonce_data = {}
477        nonce_data.action = 'pms_update_nonce'
478
479        // Update nonce
480        const nonce = await fetch(pms.ajax_url, {
481            method: 'POST',
482            credentials: 'same-origin',
483            headers: {
484                'Content-Type': 'application/x-www-form-urlencoded',
485            },
486            body: new URLSearchParams({
487                action: 'pms_update_nonce'
488            })
489        }).then(function (res) {
490            return res.json()
491        }).catch(error => {
492            console.error('Something went wrong:', error)
493            throw error
494        })
495
496        // get form data
497        var form_data = await $.pms_form_get_data( target_button )
498
499        form_data.pmstkn_original = form_data.pmstkn
500        form_data.pmstkn          = ''
501
502        const data = {
503            ...form_data,
504            action              : 'pms_process_payment',
505            user_id             : user_data.user_id,
506            payment_id          : user_data.payment_id,
507            subscription_id     : user_data.subscription_id,
508            subscription_plan_id: user_data.subscription_plan_id,
509            payment_intent      : payment_intent.id,
510            current_page        : window.location.href,
511            pms_nonce           : nonce
512        };
513
514        // Add subscription price if plans exist
515        if ( data.subscription_plans ) {
516            const priceKey = `subscription_price_${data.subscription_plans}`;
517
518            if ( form_data[priceKey] ) {
519                data[priceKey] = form_data[priceKey];
520            }
521        }
522
523        // prepare data
524        var request_data = new FormData()
525
526        for (var key in data) {
527            request_data.append(key, data[key])
528        }
529
530        // Process payment
531        return await fetch(pms.ajax_url, {
532            method     : 'POST',
533            credentials: 'same-origin',
534            body       : request_data
535        }).then(function (res) {
536            return res.json()
537        }).catch(error => {
538            console.error('Something went wrong:', error)
539            throw error
540        })
541
542    }
543
544    // Update Payment Method
545    function stripeConnectInitUpdatePaymentMethod(){
546
547        var $client_secret_setup_intent = $('.pms-form input[name="pms_stripe_connect_setup_intent"]').val()
548
549        if( $client_secret_setup_intent && $client_secret_setup_intent.length > 0 ){
550
551            update_elements_setup_intent = stripe.elements({ clientSecret: $client_secret_setup_intent, appearance: stripe_appearance })
552
553            $update_element = update_elements_setup_intent.create( "payment" )
554            $update_element.mount("#pms-stripe-payment-elements")
555
556            // Show credit card form error messages to the user as they happpen
557            $update_element.addEventListener('change', creditCardErrorsHandler )
558
559            pms_stripe_hide_spinner()
560        }
561
562    }
563
564    function stripeConnectUpdatePaymentMethod( e, target_button = false ){
565
566        e.preventDefault()
567
568        $.pms_form_remove_errors()
569
570        var current_button = $(this)
571
572        if ( target_button != false )
573            current_button = $( target_button )
574
575        //Disable the button
576        current_button.attr('disabled', true)
577
578        // Add error if credit card was not completed
579        if (cardIsEmpty === true) {
580            $.pms_form_add_validation_errors([{ target: 'credit_card', message: pms.invalid_card_details_error }], current_button)
581            return
582        }
583
584        stripe.confirmSetup({
585            elements: update_elements_setup_intent,
586            confirmParams: {
587                return_url: pms.stripe_return_url,
588                payment_method_data: { billing_details: pms_stripe_get_billing_details() }
589            },
590            redirect: 'if_required',
591        }).then(function (result) {
592
593            let token
594
595            if (result.error && result.error.decline_code && result.error.decline_code == 'live_mode_test_card') {
596                let errors = [{ target: 'credit_card', message: result.error.message }]
597
598                $.pms_form_add_validation_errors(errors, current_button)
599            } else if (result.error && result.error.type && result.error.type == 'validation_error')
600                $.pms_form_reset_submit_button(current_button)
601            else {
602                if (result.error && result.error.setup_intent)
603                    token = { id: result.error.setup_intent.id }
604                else if (result.setupIntent)
605                    token = { id: result.setupIntent.payment_method }
606                else
607                    token = ''
608
609                stripeTokenHandler(token, $(current_button).closest('form'))
610            }
611
612        })
613
614    }
615
616    function stripeConnectInit(){
617
618        var target_elements_instance      = false
619        var target_elements_instance_slug = ''
620
621        // Update Payment Method SetupIntent
622        if ( $('#pms-update-payment-method-form #pms-stripe-payment-elements').length > 0 ){
623            stripeConnectInitUpdatePaymentMethod();
624            return false;
625        // SetupIntent
626        } else if ( $.pms_checkout_is_setup_intents() ) {
627            target_elements_instance      = elements_setup_intent
628            target_elements_instance_slug = 'setup_intents'
629        // PaymentIntents
630        } else {
631            target_elements_instance      = elements
632            target_elements_instance_slug = 'payment_intents'
633        }
634
635        let selected_subscription = jQuery( subscription_plan_selector + '[type=radio]' ).length > 0 ? jQuery( subscription_plan_selector + '[type=radio]:checked' ) : jQuery( subscription_plan_selector + '[type=hidden]' )
636
637        // Handle Setup Future Usage parameter
638        let primary_setup_future_usage = pms_stripe_connect_setup_future_usage_for_input( selected_subscription )
639
640        if( typeof primary_setup_future_usage !== 'undefined' )
641            elements.update( { setupFutureUsage: primary_setup_future_usage } );
642
643        if( target_elements_instance != false ){
644
645            if( $payment_element == '' ){
646
647                if( typeof selected_subscription != 'undefined' && target_elements_instance_slug == 'payment_intents' ){
648
649                    // Use default price if custom currency price is unavailable
650                    let price = (selected_subscription.data('mc_price') !== undefined && selected_subscription.data('mc_price') !== null) ? parseFloat( selected_subscription.data('mc_price') ) : parseFloat( selected_subscription.data('price') );
651
652                    // Take into account sign-up fees as well
653                    let sign_up_fee = parseFloat( selected_subscription.data('sign_up_fee') );
654
655                    if( !isNaN( sign_up_fee ) && sign_up_fee > 0 ){
656                        price = price + sign_up_fee;
657                    }
658
659                    if( price > 0 ){
660                        target_elements_instance.update( { amount: pms_stripe_convert_amount_to_cents( price ) } );
661                    }
662                }
663            
664                let default_values = pms_stripe_get_default_values()
665                
666                $payment_element = target_elements_instance.create( "payment", default_values )
667                $payment_element.mount("#pms-stripe-payment-elements")
668
669                // Show credit card form error messages to the user as they happpen
670                $payment_element.addEventListener('change', creditCardErrorsHandler )
671
672            } else {
673
674                // Update the amount of the payment element
675                if( typeof selected_subscription != 'undefined' && target_elements_instance_slug == 'payment_intents'  ){
676
677                    // Use default price if custom currency price is unavailable
678                    let price = (selected_subscription.data('mc_price') !== undefined && selected_subscription.data('mc_price') !== null) ? parseFloat( selected_subscription.data('mc_price') ) : parseFloat( selected_subscription.data('price') );
679
680                    // Take into account sign-up fees as well
681                    let sign_up_fee = parseFloat( selected_subscription.data('sign_up_fee') );
682
683                    if( !isNaN( sign_up_fee ) && sign_up_fee > 0 ){
684                        price = price + sign_up_fee;
685                    }
686
687                    if( price > 0 ){
688                        target_elements_instance.update( { amount: pms_stripe_convert_amount_to_cents( price ) } );
689                    }
690                }
691
692                let default_values = pms_stripe_get_default_values()
693
694                if( $elements_instance_slug != target_elements_instance_slug ){
695
696                    $payment_element.destroy()
697
698                    $payment_element = target_elements_instance.create( "payment", default_values )
699                    $payment_element.mount("#pms-stripe-payment-elements")
700
701                    // Show credit card form error messages to the user as they happpen
702                    $payment_element.addEventListener('change', creditCardErrorsHandler )
703
704                }
705
706            }
707
708            $elements_instance_slug = target_elements_instance_slug
709
710            pms_stripe_hide_spinner()
711
712            if( typeof paymentSidebarPosition == 'function' ){
713                setTimeout( paymentSidebarPosition, 300 )
714            }
715
716        }
717
718    }
719
720    async function stripeConnectUpdatePaymentIntent(){
721
722        if( !$client_secret || !( $client_secret.length > 0 ) )
723            return
724
725        // Don't make this call when a Free Trial subscription is selected since we use the prepared SetupIntent
726        if ( $.pms_checkout_is_setup_intents() || $( '#pms-update-payment-method-form' ).length > 0 )
727            return
728
729        if( updating_payment_intent )
730            return
731
732        updating_payment_intent = true
733
734        var submitButton = $('.pms-form .pms-form-submit, .pms-form input[type="submit"], .pms-form button[type="submit"], .wppb-register-user input[type="submit"], .wppb-register-user button[type="submit"]').not('#pms-apply-discount, .login-submit #wp-submit')
735
736        var data = $.pms_form_get_data( submitButton )
737
738        data.action             = 'pms_update_payment_intent_connect'
739        data.pms_nonce          = $('#pms-stripe-ajax-update-payment-intent-nonce').val()
740        data.intent_secret      = $client_secret
741
742        data.pmstkn_original = data.form_type == 'pms' ? $('.pms-form #pmstkn').val() : 'wppb_register'
743        data.pmstkn          = ''
744
745        return await $.post(pms.ajax_url, data, function (response) {
746
747            if( typeof response == 'undefined' || response == '' ){
748                updating_payment_intent = false
749                return false;
750            }
751
752            response = JSON.parse( response )
753
754            if ( response.status == 'requires_payment_method' ) {
755                updating_payment_intent = false
756
757                elements.fetchUpdates().then( function(elements_response){
758                    if( typeof paymentSidebarPosition == 'function' ){
759                        setTimeout( paymentSidebarPosition, 300 )
760                    }
761
762                    return true;
763                })
764            }
765
766            updating_payment_intent = false
767
768            return false;
769
770        })
771
772    }
773
774    function stripeConnectProcessPayment( result, user_data, form_data, target_button ){
775
776        // update nonce
777        nonce_data = {}
778        nonce_data.action = 'pms_update_nonce'
779
780        $.post(pms.ajax_url, nonce_data, function (response) {
781
782            response = JSON.parse(response)
783
784            data                          = {}
785            data.action                   = 'pms_process_payment'
786            data.user_id                  = user_data.user_id
787            data.payment_id               = user_data.payment_id
788            data.subscription_id          = user_data.subscription_id
789            data.subscription_plan_id     = user_data.subscription_plan_id
790            data.pms_current_subscription = form_data.pms_current_subscription
791            data.current_page             = window.location.href
792            data.pms_nonce                = response
793            data.form_type                = form_data.form_type ? form_data.form_type : ''
794            data.pmstkn_original          = form_data.pmstkn ? form_data.pmstkn : ''
795            data.setup_intent             = form_data.setup_intent ? form_data.setup_intent : ''
796            data.user_consent_logged_in   = form_data.user_consent_logged_in ? form_data.user_consent_logged_in : ''
797
798            if( data.setup_intent == '' )
799                data.payment_intent = $client_secret_id
800            else
801                data.payment_intent = $client_secret_setup_id
802
803            // to determine actual location for change subscription
804            data.form_action          = form_data.form_action ? form_data.form_action : ''
805
806            // for member data
807            data.pay_gate             = form_data.pay_gate ? form_data.pay_gate : ''
808            data.subscription_plans   = form_data.subscription_plans ? form_data.subscription_plans : ''
809
810            if( data.subscription_plans )
811                data['subscription_price_' + data.subscription_plans] = form_data['subscription_price_' + data.subscription_plans]
812
813            // custom profile builder form name
814            data.form_name            = form_data.form_name ? form_data.form_name : ''
815
816            if( form_data.pms_default_recurring )
817                data.pms_default_recurring = form_data.pms_default_recurring
818
819            if ( form_data.pms_recurring )
820                data.pms_recurring = form_data.pms_recurring
821
822            if ( form_data.discount_code )
823                data.discount_code = form_data.discount_code
824
825            if ( form_data.group_name )
826                data.group_name = form_data.group_name
827
828            if ( form_data.group_description )
829                data.group_description = form_data.group_description
830
831            // add billing details
832            if ( form_data.pms_billing_address )
833                data.pms_billing_address = form_data.pms_billing_address
834
835            if ( form_data.pms_billing_city )
836                data.pms_billing_city = form_data.pms_billing_city
837            
838            if ( form_data.pms_billing_country )
839                data.pms_billing_country = form_data.pms_billing_country
840
841            if ( form_data.pms_billing_state )
842                data.pms_billing_state = form_data.pms_billing_state
843
844            if ( form_data.pms_billing_zip )
845                data.pms_billing_zip = form_data.pms_billing_zip
846
847            if ( form_data.pms_vat_number )
848                data.pms_vat_number = form_data.pms_vat_number
849
850            if ( form_data.wppb_referer_url	 )
851                data.wppb_referer_url = form_data.wppb_referer_url
852
853            $.post(pms.ajax_url, data, function (response) {
854
855                response = JSON.parse(response)
856
857                if( typeof response.redirect_url != 'undefined' && response.redirect_url )
858                    window.location.replace( response.redirect_url )
859
860            })
861
862        })
863
864    }
865
866    /*
867     * Stripe response handler
868     *
869     */
870    function stripeTokenHandler( token, $form = null ) {
871
872        if( $form === null )
873            $form = $(payment_buttons).closest('form')
874
875        $form.append( $('<input type="hidden" name="stripe_token" />').val( token.id ) )
876
877        // We have to append a hidden input to the form to simulate that the submit
878        // button has been clicked to have it to the $_POST
879        var button_name = $form.find('input[type="submit"], button[type="submit"]').not('#pms-apply-discount').not('input[name="pms_redirect_back"]').attr('name')
880        var button_value = $form.find('input[type="submit"], button[type="submit"]').not('#pms-apply-discount').not('input[name="pms_redirect_back"]').val()
881
882        $form.append( $('<input type="hidden" />').val( button_value ).attr('name', button_name ) )
883
884        $form.get(0).submit()
885
886    }
887
888    function pms_stripe_get_billing_details() {
889
890        var data = {}
891
892        var email = $( '.pms-form input[name="user_email"], .wppb-user-forms input[name="email"]' ).val()
893
894        if( typeof email == 'undefined' || email == '' )
895            data.email = $( '.pms-form input[name="pms_billing_email"]' ).val()
896
897        if( typeof email != 'undefined' && email != '' )
898            data.email = email.replace(/\s+/g, '') // remove any whitespace that might be present in the email
899
900        var name = ''
901
902        if( $( '.pms-billing-details input[name="pms_billing_first_name"]' ).length > 0 )
903            name = name + $( '.pms-billing-details input[name="pms_billing_first_name"]' ).val() + ' '
904        else if( $( '.pms-form input[name="first_name"], .wppb-user-forms input[name="first_name"]' ).length > 0 )
905            name = name + $( '.pms-form input[name="first_name"], .wppb-user-forms input[name="first_name"]' ).val() + ' '
906
907        if( $( '.pms-billing-details input[name="pms_billing_last_name"]' ).length > 0 )
908            name = name + $( '.pms-billing-details input[name="pms_billing_last_name"]' ).val()
909        else if( $( '.pms-form input[name="last_name"], .wppb-user-forms input[name="last_name"]' ).length > 0 )
910            name = name + $( '.pms-form input[name="last_name"], .wppb-user-forms input[name="last_name"]' ).val()
911
912        if( name.length > 1 )
913            data.name = name
914
915        if( $( '.pms-billing-details ').length > 0 ){
916
917            data.address = {
918                city        : $( '.pms-billing-details input[name="pms_billing_city"]' ).val(),
919                country     : $( '.pms-billing-details input[name="pms_billing_country"]' ).val(),
920                line1       : $( '.pms-billing-details input[name="pms_billing_address"]' ).val(),
921                postal_code : $( '.pms-billing-details input[name="pms_billing_zip"]' ).val(),
922                state       : $( '.pms-billing-details input[name="pms_billing_state"]' ).val()
923            }
924
925        }
926
927        return data
928
929    }
930
931    function creditCardErrorsHandler( event ){
932
933        if( event.complete == true )
934            cardIsEmpty = false
935        else
936            cardIsEmpty = true
937
938        if( typeof paymentSidebarPosition == 'function' ){
939            setTimeout( paymentSidebarPosition, 300 )
940        }
941
942    }
943
944    function pms_stripe_handle_validation_errors( response, current_button ){
945
946        var form_type = $('.wppb-register-user .wppb-subscription-plans').length > 0 ? 'wppb' : $('.pms-ec-register-form').length > 0 ? 'pms_email_confirmation' : 'pms'
947
948        // Paid Member Subscription forms
949        if (response.data && ( form_type == 'pms' || form_type == 'pms_email_confirmation' ) ){
950            $.pms_form_add_validation_errors( response.data, current_button )
951        // Profile Builder form
952        } else {
953
954            // Add PMS related errors (Billing Fields)
955            // These are added first because the form will scroll to the error and these
956            // are always placed at the end of the WPPB form
957            if( response.pms_errors && response.pms_errors.length > 0 )
958                $.pms_form_add_validation_errors( response.pms_errors, current_button )
959
960            // Add WPPB related errors
961            if( typeof response.wppb_errors == 'object' )
962                $.pms_form_add_wppb_validation_errors( response.wppb_errors, current_button )
963
964        }
965
966        jQuery(document).trigger( 'pms_checkout_validation_error', response, current_button )
967
968    }
969
970    async function pms_stripe_maybe_validate_recaptcha( current_button, event = null ){
971
972        if( typeof pms_initialize_recaptcha_v3 == 'function' ){
973
974            let form = current_button.closest('form')
975
976            var recaptcha_field = jQuery('.pms-recaptcha', form )
977
978            if( recaptcha_field.length > 0 ){
979
980                return await pms_initialize_recaptcha_v3( event, form )
981    
982            }
983
984        }
985        
986        let wppb_form = current_button.closest('.wppb-register-user')
987
988        if( wppb_form.length > 0 && wppb_form[0].length > 0 && typeof wppbInitializeRecaptchaV3 == 'function' ){
989
990            let wppb_recaptcha_field = jQuery('.wppb-recaptcha .wppb-recaptcha-element', wppb_form )
991
992            if( wppb_recaptcha_field.length > 0 ){
993                return await wppbInitializeRecaptchaV3( event, wppb_form )
994            }
995            
996        }
997
998        return true
999
1000    }
1001
1002    function pms_stripe_convert_amount_to_cents( amount ){
1003
1004        let currency = pms.currency
1005
1006        // List of zero-decimal currencies
1007        const zero_decimal_currencies = [
1008            'BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 
1009            'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'
1010        ];
1011
1012        // If currency is not in zero-decimal list, multiply by 100
1013        if ( !zero_decimal_currencies.includes( currency.toUpperCase() ) ) {
1014            amount = amount * 100;
1015        }
1016
1017        // Round to ensure we have a whole number
1018        return Math.round( amount );
1019    }
1020
1021    /**
1022     * Validate custom currency
1023     *
1024     * @param subscriptionPlan
1025     * @returns {Promise<*>}
1026     */
1027    async function pms_stripe_validate_sdk_checkout_currency( subscriptionPlan ) {
1028
1029        pms_stripe_show_spinner()
1030
1031        return $.ajax({
1032            url: pms.ajax_url,
1033            type: 'POST',
1034            data: {
1035                action              : 'pms_validate_sdk_currency',
1036                pms_nonce           : pms.pms_validate_currency_nonce,
1037                subscription_plan_id: subscriptionPlan.val(),
1038                pms_mc_currency     : subscriptionPlan.data('mc_currency'),
1039                subscription_id     : subscriptionPlan.closest('form').find('input[name="pms_current_subscription"]').val(),
1040                pay_gate            : 'stripe_connect'
1041            },
1042            dataType: 'json',
1043        }).done( function ( response ) {
1044
1045            if ( response && response.success && response.currency )
1046                elements.update( { currency: response.currency.toLowerCase() } )
1047
1048            pms_stripe_hide_spinner()
1049
1050            return;
1051
1052        }).fail( function () {
1053
1054            pms_stripe_hide_spinner()
1055
1056        });
1057    }
1058
1059    function pms_stripe_hide_spinner(){
1060
1061        jQuery('#pms-stripe-payment-elements').show()
1062        jQuery( '#pms-stripe-connect .pms-spinner__holder' ).hide()
1063
1064    }
1065
1066    function pms_stripe_show_spinner(){
1067
1068        jQuery('#pms-stripe-payment-elements').hide()
1069        jQuery( '#pms-stripe-connect .pms-spinner__holder' ).show()
1070
1071    }
1072
1073    function pms_stripe_get_default_values(){
1074
1075        if( jQuery('body').hasClass( 'logged-in' ) && pms.pms_customer_email ){
1076            var user_email = pms.pms_customer_email
1077        } else {
1078            var user_email = $( '.pms-form input[name="user_email"], .wppb-register-user input[name="email"]' ).val()
1079        }
1080
1081        let name = ''
1082
1083        if( jQuery('body').hasClass( 'logged-in' ) && pms.pms_customer_name ){
1084            name = pms.pms_customer_name
1085        } else {
1086            if( $( '.pms-billing-details input[name="pms_billing_first_name"]' ).length > 0 )
1087                name = name + $( '.pms-billing-details input[name="pms_billing_first_name"]' ).val() + ' '
1088            else if( $( '.pms-form input[name="first_name"], .wppb-user-forms input[name="first_name"]' ).length > 0 )
1089                name = name + $( '.pms-form input[name="first_name"], .wppb-user-forms input[name="first_name"]' ).val() + ' '
1090    
1091            if( $( '.pms-billing-details input[name="pms_billing_last_name"]' ).length > 0 )
1092                name = name + $( '.pms-billing-details input[name="pms_billing_last_name"]' ).val()
1093            else if( $( '.pms-form input[name="last_name"], .wppb-user-forms input[name="last_name"]' ).length > 0 )
1094                name = name + $( '.pms-form input[name="last_name"], .wppb-user-forms input[name="last_name"]' ).val()
1095        }
1096
1097        if( typeof user_email != 'undefined' && user_email.length > 0 ){
1098            var default_values = {
1099                defaultValues: {
1100                    billingDetails: {
1101                        email: user_email,
1102                        name : name.length > 0 ? name : null
1103                    }
1104                }
1105            }
1106        } else {
1107            var default_values = {}
1108        }
1109
1110        return default_values
1111
1112    }
1113
1114}
1115
1116// Initialize Stripe Connect when document is ready
1117jQuery( function() {
1118    try {
1119        pms_stripe_maybe_load_gateway( jQuery );
1120    } catch ( err ) {
1121        console.error( '[PMS Stripe] Error during init:', err );
1122    }
1123});
1124
1125// Maybe initialize Stripe when Elementor popup is shown
1126jQuery(document).on('elementor/popup/show', function () {
1127    if ( jQuery('.pms-form #pms-stripe-connect', jQuery('.elementor-popup-modal') ).length > 0 ) {
1128        pms_stripe_maybe_load_gateway( jQuery )
1129
1130        // By default, the regular submit event of the form is not triggered when the button is clicked inside the popup.
1131        // We simulate a submit event to trigger the form submission on the click event.
1132        document.addEventListener('click', function (ev) {
1133            const btn = ev.target.closest('input[type="submit"], button[type="submit"]');
1134            if (!btn) return;
1135            const form = btn.form || btn.closest('form');
1136            if (!form) return;
1137            if (!form.classList.contains('pms-form')) return;
1138        
1139            ev.preventDefault();
1140            ev.stopImmediatePropagation();
1141        
1142            const submitEvent = new Event('submit', { bubbles: true, cancelable: true });
1143            form.dispatchEvent(submitEvent);
1144          }, true);
1145    }
1146});
1147
1148  

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.