简体   繁体   中英

Stripe Payment Element and one page checkout - what is the correct payment flow?

I want to upgrade my simple Stripe one-page checkout to use the new Payment Element that unifies a lot of different payment methods under one component. By simple I mean, the customer chooses between a few variants of one product, provides needed info and submits the order. Collect money, send emails, fulfil the order etc. Just vanilla HTML/CSS/JS and a bit of PHP . Using Payment Intents API to process the payments, was on Charges API before.

I love the premise of this unified element so I decided to give it a go. It turns out I have trouble understanding what to do with both stripe.confirmPayment method and return_url parameter.

I guess the return_url should be my checkout page? Also, is there a way to redirect without hard refresh? Ideally, I would be able to do some server-side stuff before redirect happens, but it seems that stripe.confirmPayment automatically redirects if resolved successfully.

Here is my code. I am a designer btw, so guess I am missing something obvious as always.

        // init Stripe elements
        fetch('/config.php', {
        method: 'get',
        headers: {
            'Content-Type': 'application/json'
        }
    })
    .then((response) => {
        return response.json();
    })
    .then((response) => {
        return setupElements(response.publishableKey)
    })

var setupElements = function (publishableKey) {
    stripe = Stripe(publishableKey);
    // create payment intent to setup payment element
    fetch('/setup-elements.php', {
            method: 'POST',
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(order)
        })
        .then(function (response) {
            return response.json()
        })
        .then(function (data) {
            const appearance = {
            theme: 'none',
            labels: 'floating',
            // etc.....
            };
            elements = stripe.elements({
                clientSecret: data.clientSecret,
                fonts: [{
                    cssSrc: 'https://use.typekit.net/hly2qug.css'
                }, ],
                appearance
            });
            const paymentElement = elements.create("payment", {
                fields: {
                    billingDetails: {
                        email: 'never',
                        address: {
                            line1: 'never',
                            city: 'never',
                            state: 'never',
                            country: 'never',
                            postalCode: 'never'
                        }
                    }
                }
            });
            paymentElement.mount("#payment-element");
          
        })
}

form.addEventListener('submit', function (e) {
    e.preventDefault();
    var isFormValid = validate.validateAll(form);
    if (isFormValid.length < 1) {
        loading(true);
        collectFormInfo();
        confirmPayment();
    }
})

var confirmPayment = function () {
    stripe.confirmPayment({
            elements,
            confirmParams: {
                return_url: 'checkout-page?',
                payment_method_data: {
                    billing_details: {
                        email: order.customer.email,
                        address: {
                            line1: order.delivery.address,
                            city: order.delivery.city,
                            state: order.delivery.state,
                            country: order.delivery.country,
                            postal_code: order.delivery.postcode
                        }
                    }
                }
            }
        })
        .then(function (result) {
            // This is where I get stuck. How to do stuff after 
            // payment is confirmed
            // and not get redirected immediately? If 
            //redirected, where to and is it 
            // possible to do so asynchronously?    
            if (result.error.type === "card_error" || result.error.type === "validation_error") {
                showMessage(result.error.message);
            } else {
                // get client secret
                const clientSecret = new URLSearchParams(window.location.search).get(
                    "payment_intent_client_secret"
                );
                // bail if no client secret
                if (!clientSecret) {
                    return;
                } else {
                    stripe.retrievePaymentIntent(clientSecret).then(function (response) {
                        switch (response.paymentIntent.status) {
                            case "succeeded":
                                showMessage("Payment succeeded!");
                                break;
                            case "processing":
                                showMessage("Your payment is processing.");
                                break;
                            case "requires_payment_method":
                                showMessage("Payment failed. Please try another payment method.");
                                break;
                            default:
                                showMessage("Something went wrong.");
                                break;
                        }
                    });
                }
            }

        })
}

Nudge in the right direction is all I need, at least I hope so

Yes the return_url should be your own page that Stripe will automatically redirect after your customer completed the Payment: Stripe Doc . 'checkout-page?' doesn't look like a valid URL. Normally you would want something like 'http://localhost:4242/success'

This action is done automatically on client and you can't intercept it. Any action you want to perform on server should be handled via webhook, at Step 6 "Handle post-payment events" at the same article above.

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