简体   繁体   中英

Page not redirecting to stripe checkout after it passed form validation

I am using HTML 5 required attribute for form validation. Now what I want is that if the form has passed the HTML 5 validation, it should take the user to the stripe checkout (I deliberately xxx out info in the code below for SO question).

Now if the form has not passed validation, the submit doesn't process, which is good. But after I complete the form and submit the form, it does not take me to the stripe checkout page, it just refreshes the page. What am I doing wrong?

<form id="tcform">

<p><b>Quantity:</b> 1</p>
<b class="price">Price:</b> <s>£xx</s> <span style="color: red;">£xx</span>
<button class="btn btn-default buynow" id="checkout-button-sku_xxx" role="link">
     Buy Now
    </button>
    <p>
    <i style="font-size:small">Limited time offer</i>
    </p>

  <p class="tcparagraph">
  <input id="field_terms" type="checkbox" required name="terms"> I accept the <u><a href="Terms" id="tclink">Terms and Conditions</a></u></p>

  <div id="error-message"></div>
  </form>

<script>
    (function() {

        var stripe = Stripe('pk_test_xxx');

        var checkoutButton = document.getElementById('checkout-button-sku_xxx');

        checkoutButton.addEventListener('click', function() {
            // When the customer clicks on the button, redirect
            // them to Checkout.

            const isFormValid = checkoutButton.form.checkValidity();

            if(isFormValid==true) {

            stripe.redirectToCheckout({
                    items: [{
                        sku: 'sku_xxx',
                        quantity: 1
                    }],

                    // Do not rely on the redirect to the successUrl for fulfilling
                    // purchases, customers may not always reach the success_url after
                    // a successful payment.
                    // Instead use one of the strategies described in
                    // https://stripe.com/docs/payments/checkout/fulfillment
                    successUrl: window.location.protocol + '//metis-online.com/courses/course-BRFAITC009-order-confirmation',
                    cancelUrl: window.location.protocol + '//metis-online.com/order-cancelled',
                })
                .then(function(result) {
                    if (result.error) {
                        // If `redirectToCheckout` fails due to a browser or network
                        // error, display the localized error message to your customer.
                        var displayError = document.getElementById('error-message');
                        displayError.textContent = result.error.message;
                    }
                });
            }

        });
    })();
</script>

You want to prevent the default behaviour of submiting the form. So do:

checkoutButton.addEventListener('click', function(event) {

...

if(isFormValid==true) {
    event.preventDefault();

References

Right now your code is only attaching the click listener if the form is valid at page load. In the absence of other form behavior, clicking a button in a form submits it back to the page it came from, which is why it looks like a page refresh.

You need to move the form check inside the button click event handler like so:

<script>
    (function() {
        var stripe = Stripe('pk_test_xxx');
        var checkoutButton = document.getElementById('checkout-button-sku_xxx');

        checkoutButton.addEventListener('click', function() {
            if($('#tcform')[0].checkValidity()){

                // When the customer clicks on the button, redirect
                // them to Checkout.
                stripe.redirectToCheckout({
                    items: [{
                        sku: 'sku_xxx',
                        quantity: 1
                    }],

                    // Do not rely on the redirect to the successUrl for fulfilling
                    // purchases, customers may not always reach the success_url after
                    // a successful payment.
                    // Instead use one of the strategies described in
                    // https://stripe.com/docs/payments/checkout/fulfillment
                    successUrl: window.location.protocol + '//www.xxx.com',
                    cancelUrl: window.location.protocol + '//www.xxx.com',
                })
                .then(function(result) {
                    if (result.error) {
                        // If `redirectToCheckout` fails due to a browser or network
                        // error, display the localized error message to your customer.
                        var displayError = document.getElementById('error-message');
                        displayError.textContent = result.error.message;
                    }
                });
            }
        });
  })();

But it might be even better to listen to the form's submit event ( https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit_event ):

$('#tcform').on('submit', function() {
     stripe.redirectToCheckout({ 
         ...
     });
});

The submit event is only emitted after the form is validated.

It happened to us as well.

We've added the novalidate attribute (removes the HTML5 validation) to the form and validate it by javascript only.

    <form id="tcform" novalidate>
    ...
    </form>

As Jannes Botis said , you can use preventDefault . You can also just return false on the eventHandler from an submit event, that will also cancel the form submission. For reference see: https://www.geeksforgeeks.org/when-to-use-preventdefault-vs-return-false-in-javascript/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM