PageSourceSearch

https://www.thewirechina.com/wp-content/plugins/leaky-paywall/js/stripe-registration.js?ver=5.1.9

js thewirechina.com collected 2026-10-02 03:21:10 UTC 18,180 bytes, 427 lines download raw bytes

1( function( $ )  {
2
3	$(document).ready( function() {
4
5        if ( ! leaky_paywall_stripe_registration_ajax.stripe_pk ) {
6            return;
7        }
8
9        // Bail cleanly if Stripe.js was blocked. This happens when a consent
10        // management platform (Cookiebot, OneTrust, Iubenda, etc.) auto-blocks
11        // https://js.stripe.com/v3/ because the visitor didn't consent to the
12        // category the CMP classified Stripe under. Without this guard the
13        // form throws "Stripe is not defined" and the Subscribe button appears
14        // broken — user has no idea their consent choices are the reason.
15        //
16        // Publisher-side fix: mark Stripe as "Necessary" in the consent tool
17        // (Stripe processes the transaction the visitor is trying to make,
18        // which fits the Necessary category under GDPR). We surface an
19        // in-form message here so the visitor knows what to do.
20        if ( typeof Stripe === 'undefined' ) {
21            var $errors = $('#leaky-paywall-registration-errors');
22            if ( $errors.length ) {
23                $errors.html(
24                    '<div class="leaky_paywall_message error">' +
25                    'Payment processing is currently blocked by your cookie settings. ' +
26                    'To subscribe, please reopen the cookie banner and allow the payment / necessary category, then reload this page.' +
27                    '</div>'
28                );
29            }
30            // Also disable the submit buttons so the user doesn't repeatedly
31            // click a form that can't submit.
32            $('#checkout, #leaky-paywall-registration-next').prop('disabled', true);
33            return;
34        }
35
36        let stripe = Stripe(leaky_paywall_stripe_registration_ajax.stripe_pk);
37
38        if ( leaky_paywall_stripe_registration_ajax.client_id ) {
39            stripe = Stripe(leaky_paywall_stripe_registration_ajax.stripe_pk, { stripeAccount: leaky_paywall_stripe_registration_ajax.client_id});
40        }
41
42        let elements;
43        let billingAddress = null;
44        let isSubmitting = false;
45
46        // Stripe Checkout
47        $('#checkout').click(function(e) {
48            e.preventDefault();
49            $(this).text(leaky_paywall_stripe_registration_ajax.continue_text);
50            $("#leaky-paywall-registration-errors").html("");
51            validateUserData();
52        });
53
54        // one time and recurring
55        $("#leaky-paywall-registration-next").click(function () {
56            $(this).text(leaky_paywall_stripe_registration_ajax.continue_text).prop('disabled', true);
57            $("#leaky-paywall-registration-errors").html("");
58            validateUserData();
59        });
60
61        // Intercept Enter key during step 1 (account setup) — prevents native form submission
62        // which would bypass AJAX validation and fail server-side with no payment intent.
63        document.querySelector("#leaky-paywall-payment-form") && document.querySelector("#leaky-paywall-payment-form").addEventListener("submit", function(e) {
64            if ($(".leaky-paywall-form-account-setup-step").hasClass("active")) {
65                e.preventDefault();
66                $("#leaky-paywall-registration-next").text(leaky_paywall_stripe_registration_ajax.continue_text);
67                $("#leaky-paywall-registration-errors").html("");
68                validateUserData();
69            }
70        });
71
72
73        function validateUserData() {
74
75            $("#leaky-paywall-registration-errors").html("");
76
77            const form_data = $("#leaky-paywall-payment-form").serialize();
78
79            const data = {
80                action: "leaky_paywall_process_user_registration_validation",
81                form_data: form_data,
82                nonce: leaky_paywall_stripe_registration_ajax.register_nonce
83            };
84
85            $.post(leaky_paywall_stripe_registration_ajax.ajaxurl, data, function (resp) {
86
87                if (resp.errors) {
88                    $.each(resp.errors, function (i, value) {
89                        $("#leaky-paywall-registration-errors").append(
90                        "<p class='leaky-paywall-registration-error'>" +
91                            value.message +
92                            "</p>"
93                        );
94                        $("#leaky-paywall-registration-next").text( leaky_paywall_stripe_registration_ajax.next_text ).prop('disabled', false);
95                        $("#leaky-paywall-registration-errors").show();
96
97                        $("html, body").animate(
98                        {
99                            scrollTop: $(".leaky-paywall-registration-error").offset().top,
100                        },
101                        1000
102                        );
103                    });
104
105                } else {
106
107                    if ( resp.subscription_updated ) {
108                        // Existing subscription was updated to new plan, submit form directly
109                        let form$ = jQuery('#leaky-paywall-payment-form');
110                        form$.get(0).submit();
111                    } else if ( resp.session_id ) {
112                        // stripe checkout
113                        stripe.redirectToCheckout({
114                            sessionId: resp.session_id
115                        });
116                    } else if (resp.pi_client) {
117                        // one time payment
118                        $("#payment-intent-client").val(resp.pi_client);
119                        $("#payment-intent-id").val(resp.pi_id);
120
121                        buildPaymentForm(resp.pi_client);
122                        showPaymentForm();
123
124                          // Handle form submission.
125                        document.querySelector("#leaky-paywall-payment-form").addEventListener("submit", handleSubmit);
126
127                    } else if (resp.deferred_tax) {
128                        // subscription with automatic tax — defer subscription creation until address is entered
129                        $("#stripe-customer-id").val(resp.customer_id);
130                        buildAddressOnly();
131                        showPaymentForm();
132
133                    } else if (resp.customer_id) {
134                        // subscription
135                        $("#stripe-customer-id").val(resp.customer_id);
136
137                        buildPaymentForm(resp.client_secret);
138                        showPaymentForm();
139
140                          // Handle form submission.
141                        document.querySelector("#leaky-paywall-payment-form").addEventListener("submit", handleSubmit);
142
143                    }
144
145                }
146
147            });
148
149        }; // end validate user data
150
151        let addressElementMounted = false;
152
153        function mountAddressElement( elementsInstance ) {
154            const addressElement = elementsInstance.create("address", {
155                mode: "billing",
156            });
157
158            addressElement.mount("#address-element");
159            addressElementMounted = true;
160
161            addressElement.on('change', (event) => {
162                if (event.complete) {
163                    billingAddress = event.value;
164                    $('input[name="lp_billing_name"]').val(billingAddress.name || '');
165                    $('input[name="lp_billing_line1"]').val(billingAddress.address.line1 || '');
166                    $('input[name="lp_billing_line2"]').val(billingAddress.address.line2 || '');
167                    $('input[name="lp_billing_city"]').val(billingAddress.address.city || '');
168                    $('input[name="lp_billing_state"]').val(billingAddress.address.state || '');
169                    $('input[name="lp_billing_postal_code"]').val(billingAddress.address.postal_code || '');
170                    $('input[name="lp_billing_country"]').val(billingAddress.address.country || '');
171
172                    if ( 'on' === leaky_paywall_stripe_registration_ajax.automatic_tax_enabled ) {
173                        fetchTaxPreview(billingAddress.address);
174                    }
175                }
176            });
177        }
178
179        function buildAddressOnly() {
180            // For deferred tax flow: mount only the address element first, without a clientSecret.
181            var standaloneElements = stripe.elements();
182            mountAddressElement( standaloneElements );
183        }
184
185        function buildPaymentForm( clientSecret ) {
186
187            elements = stripe.elements({ clientSecret });
188
189            const paymentElementOptions = {
190                layout: "tabs",
191            };
192
193            const paymentElement = elements.create("payment", paymentElementOptions);
194
195            // Temporarily lock scroll position while Stripe Element mounts to prevent layout shift.
196            var scrollPos = $(window).scrollTop();
197            paymentElement.mount("#payment-element");
198            $(window).scrollTop(scrollPos);
199
200            if ( 'on' == leaky_paywall_stripe_registration_ajax.billing_address && !addressElementMounted ) {
201                mountAddressElement( elements );
202            }
203
204        }
205
206        function showPaymentForm() {
207
208            setTimeout(() => {
209                $("#leaky-paywall-registration-errors").hide();
210                $("#leaky-paywall-registration-next").remove();
211                $(".leaky-paywall-registration-user-container").hide();
212                $(".leaky-paywall-form-payment-setup-step").addClass("active");
213                $(".leaky-paywall-form-account-setup-step").removeClass("active");
214
215                $(".leaky-paywall-registration-payment-container").slideDown();
216
217                if ( 'on' === leaky_paywall_stripe_registration_ajax.automatic_tax_enabled ) {
218                    showInitialOrderSummary();
219                }
220
221                $("html, body").animate(
222                    {
223                    scrollTop: $(".leaky-paywall-form-steps").offset().top,
224                    },
225                    1000
226                );
227            }, 500);
228
229        }
230
231        function showInitialOrderSummary() {
232            var price = $('input[name="level_price"]').val();
233            var currency = $('input[name="currency"]').val() || 'USD';
234            var formatter = formatCurrency(currency);
235            var subtotal = Math.round(parseFloat(price) * 100);
236
237            $('#lp-order-subtotal-amount').text(formatter(subtotal));
238            $('#lp-order-tax-amount').text('—').addClass('lp-order-pending');
239            $('#lp-order-total-amount').text('—');
240            $('#lp-order-summary').slideDown();
241        }
242
243        var taxPreviewRequest = null;
244
245        function fetchTaxPreview(address) {
246            var levelId = $('input[name="level_id"]').val();
247            var customerId = $('#stripe-customer-id').val() || '';
248
249            // Abort any in-flight request.
250            if ( taxPreviewRequest ) {
251                taxPreviewRequest.abort();
252            }
253
254            $('#lp-order-tax-amount').text('Calculating...').addClass('lp-order-pending');
255            $('#leaky-paywall-submit').prop('disabled', true);
256
257            taxPreviewRequest = $.ajax({
258                url: leaky_paywall_stripe_registration_ajax.ajaxurl,
259                type: 'POST',
260                dataType: 'json',
261                data: {
262                    action: 'leaky_paywall_stripe_tax_preview',
263                    nonce: leaky_paywall_stripe_registration_ajax.tax_preview_nonce,
264                    level_id: levelId,
265                    customer_id: customerId,
266                    line1: address.line1 || '',
267                    city: address.city || '',
268                    state: address.state || '',
269                    postal_code: address.postal_code || '',
270                    country: address.country || ''
271                },
272                success: function(response) {
273                    jQuery('#leaky-paywall-submit').prop('disabled', false);
274                    if (response.success) {
275                        var data = response.data;
276                        var formatter = formatCurrency(data.currency);
277                        jQuery('#lp-order-subtotal-amount').text(formatter(data.subtotal));
278                        jQuery('#lp-order-tax-amount').text(formatter(data.tax)).removeClass('lp-order-pending');
279                        jQuery('#lp-order-total-amount').text(formatter(data.total));
280
281                        // Build payment form now that subscription is created with tax.
282                        if (data.client_secret && !jQuery('#payment-element .StripeElement, #payment-element iframe').length) {
283                            buildPaymentForm(data.client_secret);
284                            document.querySelector("#leaky-paywall-payment-form").addEventListener("submit", handleSubmit);
285                        }
286                    } else {
287                        jQuery('#lp-order-tax-amount').text('$0.00').removeClass('lp-order-pending');
288                    }
289                },
290                error: function(xhr, status, err) {
291                    jQuery('#leaky-paywall-submit').prop('disabled', false);
292                    jQuery('#lp-order-tax-amount').text('$0.00').removeClass('lp-order-pending');
293                }
294            });
295        }
296
297        function formatCurrency(currency) {
298            return function(amountInCents) {
299                return new Intl.NumberFormat(undefined, {
300                    style: 'currency',
301                    currency: currency
302                }).format(amountInCents / 100);
303            };
304        }
305
306
307        async function handleSubmit(e) {
308            e.preventDefault();
309
310            // Re-entry guard: if a submission is already in flight, ignore further submits
311            // (handles rapid double-click / Enter-spam where the disabled attribute isn't
312            // applied between events).
313            if ( isSubmitting ) {
314                return;
315            }
316            isSubmitting = true;
317
318            let subButton = document.getElementById('leaky-paywall-submit');
319            if ( subButton ) {
320                subButton.disabled = true;
321                subButton.innerHTML = leaky_paywall_stripe_registration_ajax.continue_text;
322            }
323
324            let emailAddress = $('input[name="email_address"]').val();
325            let isTrial = $('input[name="is_trial"]').val();
326            let paymentMethod = $('input[name="payment_method"]:checked').val();
327
328            if ( paymentMethod != 'stripe' ) {
329                let form$ = jQuery('#leaky-paywall-payment-form');
330                form$.get(0).submit();
331                return;
332            }
333
334            if ( isTrial ) {
335                const { error }
335 = await stripe.confirmSetup({
336                    elements,
337                    confirmParams: {
338                        return_url: leaky_paywall_stripe_registration_ajax.redirect_url,
339                    },
340                    redirect: 'if_required'
341                });
342
343                 if ( error ) {
344                    if (error.type === "card_error" || error.type === "validation_error") {
345                        showMessage(error.message);
346                    } else {
347                        showMessage("An unexpected error occurred.");
348                    }
349                    resetSubButton();
350                } else {
351                    let form$ = jQuery('#leaky-paywall-payment-form');
352                    form$.get(0).submit();
353                }
354
355            } else {
356                const { error, paymentIntent } = await stripe.confirmPayment({
357                    elements,
358                    confirmParams: {
359                        // Make sure to change this to your payment completion page
360                        return_url: leaky_paywall_stripe_registration_ajax.redirect_url,
361                        receipt_email: emailAddress,
362                    },
363                    redirect: 'if_required'
364                });
365
366                if (paymentIntent && paymentIntent.id) {
367
368                    // 'processing' is the success state for ACH (us_bank_account) — the bank
369                    // transfer is in flight but won't settle for 3-5 business days. Treat it
370                    // as a success so the subscriber lands on the post-signup page (where the
371                    // ACH-pending modal can fire) instead of being silently dropped here.
372                    if ( paymentIntent.status === 'succeeded' || paymentIntent.status === 'processing' ) {
373                        let form$ = jQuery('#leaky-paywall-payment-form');
374                        form$.get(0).submit();
375                    } else {
376                        resetSubButton();
377                    }
378
379                }
380
381                 if ( error ) {
382                    if (error.type === "card_error" || error.type === "validation_error") {
383                        showMessage(error.message);
384                    } else {
385                        showMessage("An unexpected error occurred.");
386                    }
387                    resetSubButton();
388                }
389            }
390
391            // This point will only be reached if there is an immediate error when
392            // confirming the payment. Otherwise, your customer will be redirected to
393            // your `return_url`. For some payment methods like iDEAL, your customer will
394            // be redirected to an intermediate site first to authorize the payment, then
395            // redirected to the `return_url`.
396
397
398
399
400          //  setLoading(false);
401        }
402
403        function showMessage(messageText) {
404            const messageContainer = document.querySelector("#payment-message");
405
406            messageContainer.classList.remove("hidden");
407            messageContainer.textContent = messageText;
408
409            setTimeout(function () {
410                messageContainer.classList.add("hidden");
411                messageContainer.textContent = "";
412            }, 7000);
413        }
414
415        function resetSubButton() {
416            isSubmitting = false;
417            let subButton = document.getElementById('leaky-paywall-submit');
418            if ( subButton ) {
419                subButton.disabled = false;
420                subButton.innerHTML = 'Subscribe';
421            }
422        }
423
424
425	}); // doc ready
426
427})( 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.