Collect payment details before creating an Intent
Build an integration where you can render the Payment Element prior to creating a PaymentIntent or SetupIntent.
A setup flow allows you to set up a payment method for future payments without charging your customer right away. In this integration, you’ll build a custom payment flow where you render the Payment Element, create the SetupIntent, and confirm the setup from the buyer’s browser.
Set up StripeServer-side
First, create a Stripe account or sign in.
Use our official libraries to access the Stripe API from your application:
Enable payment methods
Caution
This integration path doesn’t support BLIK or pre-authorized debits that use the Automated Clearing Settlement System (ACSS).
View your payment methods settings and enable the payment methods you want to support. You need at least one payment method enabled to create a SetupIntent.
By default, Stripe enables cards and other prevalent payment methods that can help you reach more customers, but we recommend turning on additional payment methods that are relevant for your business and customers. See Payment method support for product and payment method support, and our pricing page for fees.
Collect payment detailsClient-side
You’re ready to collect payment details on the client with the Payment Element. The Payment Element is a prebuilt UI component that simplifies collecting payment details for a variety of payment methods.
The Payment Element contains an iframe that securely sends payment information to Stripe over an HTTPS connection. Avoid placing the Payment Element within another iframe because some payment methods require redirecting to another page for payment confirmation.
The checkout page address must start with https://
rather than http://
for your integration to work. You can test your integration without using HTTPS, but remember to enable it when you’re ready to accept live payments.
The Payment Element renders a dynamic form that allows your customer to pick a payment method. The form automatically collects all necessary payments details for the payment method selected by the customer.
You can customize the Payment Element to match the design of your site by passing the appearance object into options
when creating the Elements
provider.
Collect addresses
By default, the Payment Element only collects the necessary billing address details. To collect a customer’s full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
Create a CustomerServer-side
To set up a payment method for future payments, you must attach it to a Customer. Create a Customer
object when your customer creates an account with your business. Customer
objects allow for reusing payment methods and tracking across multiple payments.
Create a SetupIntentServer-side
When the customer submits your payment form, create a SetupIntent on your server. With automatic_
enabled, the SetupIntent is created using the payment methods you configured in the Dashboard.
Included on a SetupIntent is a client secret. Return this value to your client for Stripe.js to use to securely complete the setup process.
Submit the setup to StripeClient-side
Use stripe.confirmSetup to complete the setup using details from the Payment Element.
Provide a return_url to this function to indicate where Stripe should redirect the user after they complete the setup. Your user might be initially redirected to an intermediate site, like a bank authorization page, before being redirected to the return_
. Card setups immediately redirect to the return_
when a setup is successful.
If you don’t want to redirect for card setups after setup completion, you can set redirect to if_
. This only redirects customers that check out with redirect-based payment methods.
Charge the saved payment method laterServer-side
Warning
bancontact
and ideal
are one-time payment methods by default. When set up for future usage, they generate a sepa_
reusable payment method type so you need to use sepa_
to query for saved payment methods.
Compliance
You’re responsible for your compliance with all applicable laws, regulations, and network rules when saving a customer’s payment details. When rendering past payment methods to your end customer for future purchases, make sure you’re listing payment methods where you’ve collected consent from the customer to save the payment method details for this specific future use. To differentiate between payment methods attached to customers that can and can’t be presented to your end customer as a saved payment method for future purchases, use the allow_redisplay parameter.
When you’re ready to charge your customer off-session, use the Customer and PaymentMethod IDs to create a PaymentIntent. To find a payment method to charge, list the payment methods associated with your customer. This example lists cards but you can list any supported type.
When you have the Customer and PaymentMethod IDs, create a PaymentIntent with the amount and currency of the payment. Set a few other parameters to make the off-session payment:
- Set off_session to
true
to indicate that the customer isn’t in your checkout flow during a payment attempt and can’t fulfill an authentication request made by a partner, such as a card issuer, bank, or other payment institution. If, during your checkout flow, a partner requests authentication, Stripe requests exemptions using customer information from a previous on-session transaction. If the conditions for exemption aren’t met, the PaymentIntent might throw an error. - Set the value of the PaymentIntent’s confirm property to
true
, which causes confirmation to occur immediately when the PaymentIntent is created. - Set payment_method to the ID of the PaymentMethod and customer to the ID of the Customer.
When a payment attempt fails, the request also fails with a 402 HTTP status code and the status of the PaymentIntent is requires_payment_method. You must notify your customer to return to your application to complete the payment (for example, by sending an email or in-app notification).
Check the code of the error raised by the Stripe API library. If the payment failed due to an authentication_required decline code, use the declined PaymentIntent’s client secret with confirmPayment to allow the customer to authenticate the payment.
const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const {error} = await stripe.confirmPayment({ // The client secret of the PaymentIntent clientSecret, confirmParams: { return_url: 'https://example.com/order/123/complete', }, }); if (error) { // This point will only be reached if there is an immediate error when // confirming the payment. Show error to your customer (for example, payment // details incomplete) const messageContainer = document.querySelector('#error-message'); messageContainer.textContent = error.message; } else { // Your customer will be redirected to your `return_url`. For some payment // methods like iDEAL, your customer will be redirected to an intermediate // site first to authorize the payment, then redirected to the `return_url`. } });
Note
stripe.
can take several seconds to complete. During that time, disable your form from being resubmitted and show a waiting indicator like a spinner. If you receive an error, show it to the customer, re-enable the form, and hide the waiting indicator. If the customer must perform additional steps to complete the payment, such as authentication, Stripe.js walks them through that process.
If the payment failed for other reasons, such as insufficient funds, send your customer to a payment page to enter a new payment method. You can reuse the existing PaymentIntent to attempt the payment again with the new payment details.