euphbasio
euphbasio

Reputation: 1

Vary Customer Details with Stripe Payment Element on Single Page Checkout

I'm migrating an application from Stripe's 'card' element to the newer 'payment' element.

If I understand correctly, the client secret from the PaymentIntent is now required to create and mount the payment element. In order to create the PaymentIntent, we need the customer to have been created and the amount.

From the docs:

Previously:

const stripe = Stripe('pk_test_qblFNYngBkEdjEZ16jxxoWSM');
const elements = stripe.elements();

Now:

const stripe = Stripe('pk_test_qblFNYngBkEdjEZ16jxxoWSM');
const options = {
  clientSecret: '{{CLIENT_SECRET}}',
};
const elements = stripe.elements(options);

My question - the application is a single page on which customers enter details, select quantities (tickets) and enter card details. I'm assuming that this is not feasible with the new payment element, since the customer would not be able to modify their details or change quantity after the payment element has been created.

Am I wrong?

Thank you so much.

Image of existing form for context:

Image of existing form for context

Upvotes: 0

Views: 762

Answers (2)

fluxus
fluxus

Reputation: 559

Just wondering if you ever found a solution? I am in the same boat, and this thread is the only thing I found on google for this scenario.

Is it maybe possible to fake a paymentIntent on page load and then create new one/update with info from the form?

Edit:

Bad wording above. Nothing fake about this. Just create initial paymentIntent on page-load. Use the returned clientSecret when initialising elements and paymentElement.

// setup 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);
   //  endpoint to create PI and return client secret
   fetch('/setup-elements.php', {
    method: 'POST',
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify(order)
})
.then(function (response) {
    return response.json()
})
.then(function (data) {
    elements = stripe.elements({clientSecret:data.clientSecret});
    const paymentElement = elements.create("payment");
    paymentElement.mount("#payment-element");
 })
} 

Payment element should be displayed now. Update/etc the paymentIntent as needed.

Upvotes: 0

koopajah
koopajah

Reputation: 25552

Correct, in this flow you should collect the card details last once the customer is ready to finalize their payment. This would be the recommended approach where you don't let them change the quantity at that point and charge their card as you collect the card details

Otherwise, the best option is to stay on the Card Element so that you collect their card details upfront and only confirm at the next step once they are ready to finalize.

Upvotes: 1

Related Questions