Why is the Elements UI dependent on a PaymentIntent?

240 views
Skip to first unread message

EML

unread,
Jan 25, 2023, 11:22:45 AM1/25/23
to Stripe API Discussion
I'm just getting my head around a custom payment integration. One issue is that, when using the example code, I can create a PaymentIntent only after I get a price from the client. The flow is therefore:

  1. Client chooses product, gets a price, talks to server
  2. Server requests a PI from Stripe, waits, then returns the client_secret to the client
  3. client_secret is used to generate the payment form on the client
End result: the client has to wait to see the card payment form. This is noticeable (about a second) and looks really bad.

Is there some way I can pre-generate a payment form *without* a PaymentIntent? Just a simple one - cards only, single country, etc. I'm pretty sure, after several hours searching, that the answer to this question is 'No'. Alternatively, can I maybe pre-generate a PaymentIntent with a cost of zero, and update it later? How do other people handle this?



Remi J.

unread,
Jan 25, 2023, 11:42:46 AM1/25/23
to api-d...@lists.stripe.com
Hello,

Elements is a library of UI components [1] to help collect payment method details and other information client-side. We have multiple flavours of elements in there from the PaymentElement [2] (likely what you use) to our PaymentRequestButton [3] for displaying a branded button for wallets payments like Apple Pay and Google Pay through our newer AddressElement [4] to collect address details.

When we designed PaymentElement, the intent was to make it easy to collect any and all payment method information client-side without having to change your code. Each payment methods can have their own specificities though from a specific minimum or maximum amount, to which currencies are supported or in which country. Others require an email to be collected or a billing address. And others require certain additional options such as mandate details or not supporting separate authorization and capture.

Because of those additional restrictions, we needed a simple and reliable way to know what you planned to use to ensure that we showed only viable and compatible information to the end customer. That's what the PaymentIntent or SetupIntent APIs were designed for. They represent the lifecycle of attempting to collect payment details and are modeled as a state machine reflecting what has happened to it. For that reason, PaymentElement was built to rely on simply the `client_secret` associated with your PaymentIntent or SetupIntent to configure it easily and seamlessly client-side. Over time, as you change the amount or currency associated with the object, for example when the customer changes what's in their cart, the PaymentElement UI can dynamically render updated information.

This flexibility has also allowed us to release support for the "automatic payment methods" feature last year. You can now enable or disable new payment methods in the Dashboard with a simple click and your integration can now accept those easily without having to change your client-side integration (or often the server-side part).

Now, while this has served us and developers extremely well, it still can appear too restrictive and it has some downsides such as having a lot of "abandoned" objects that are never completed. While this integration path still offers numerous upsides, we have been working on an alternative one for a while. We now have a public beta that covers this where you can defer the creation of the PaymentIntent to later and render a PaymentElement with all the options you'd expect client-side only. We have a public doc for this here [5] which goes over the flow of that integration. You can request access to the beta directly at the top of that page too.

Alternatively, if you only use card payments, you can use the CardElement integration which lets you collect card details first and then confirm separately. This is documented here [6].

Hope this helps!
Remi


--
To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss...@lists.stripe.com.

EML

unread,
Jan 25, 2023, 1:03:10 PM1/25/23
to Stripe API Discussion, re...@stripe.com
Hi Remi - that's very comprehensive; thanks. I'll look into the 'defer-payment-intent' beta.

I looked at one work-around, which was to create a zero-cost PaymentIntent and to update the cost later. However, this doesn't work - Stripe complains that " This value must be greater than or equal to 1."

Remi J.

unread,
Jan 25, 2023, 1:17:26 PM1/25/23
to EML, Stripe API Discussion
That's correct, the PaymentIntent API is used to accept a real payment via Stripe so you can't have a $0 one. We have a similar/parallel API called the SetupIntent API for that which allows you to collect payment method details upfront without taking a real payment. This is covered in detail here [1].

You wouldn't want to use this flow to collect card details now and then immediately after that accept a real payment though as this can cause issues (declines, 3DS twice, etc.). The beta I mentioned is likely a better fit for you!

Reply all
Reply to author
Forward
0 new messages