Set up future payments
Learn how to save payment details and charge your customers later.
The Setup Intents API lets you save a customer’s payment details without an initial payment. This is helpful if you want to onboard customers now, set them up for payments, and charge them in the future—when they’re offline.
Use this integration to set up recurring payments or to create one-time payments with a final amount determined later, often after the customer receives your service.
Card-present transactions
Card-present transactions, such as collecting card details through Stripe Terminal, use a different process for saving the payment method. For details, see the Terminal documentation.
Compliance
You’re responsible for your compliance with all applicable laws, regulations, and network rules when saving a customer’s payment details. These requirements generally apply if you want to save your customer’s payment method for future use, such as displaying a customer’s payment method to them in the checkout flow for a future purchase or charging them when they’re not actively using your website or app. Add terms to your website or app that state how you plan to save payment method details and allow customers to opt in.
When you save a payment method, you can only use it for the specific usage you have included in your terms. To charge a payment method when a customer is offline and save it as an option for future purchases, make sure that you explicitly collect consent from the customer for this specific use. For example, include a “Save my payment method for future use” checkbox to collect consent.
To charge them when they’re offline, make sure your terms include the following:
- The customer’s agreement to your initiating a payment or a series of payments on their behalf for specified transactions.
- The anticipated timing and frequency of payments (for example, if the charges are for scheduled installments, subscription payments, or unscheduled top-ups).
- How you determine the payment amount.
- Your cancellation policy, if the payment method is for a subscription service.
Make sure you keep a record of your customer’s written agreement to these terms.
Note
If you need to use manual server-side confirmation or your integration requires presenting payment methods separately, see our alternative guide.
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
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.
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
Note
If you want to render the Payment Element without first creating a SetupIntent, see Collect payment details before creating an Intent.
A SetupIntent is an object that represents your intent to set up a customer’s payment method for future payments. The payment methods shown to customers during the checkout process are also included on the SetupIntent. You can let Stripe automatically pull payment methods from your Dashboard settings or you can list them manually.
Unless your integration requires a code-based option for offering payment methods, Stripe recommends the automated option. This is because Stripe evaluates the currency, payment method restrictions, and other parameters to determine the list of supported payment methods. Payment methods that increase conversion and that are most relevant to the currency and customer’s location are prioritized. Lower priority payment methods are hidden beneath an overflow menu.
Retrieve the client secret
The SetupIntent includes a client secret that the client side uses to securely complete the payment process. You can use different approaches to pass the client secret to the client side.
Using Radar
When saving a customer’s payment method without an initial payment, Radar doesn’t act on the SetupIntent by default. If you want to activate this as the default, go to the Radar settings and enable Use Radar on payment methods saved for future use.
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. The checkout page address must start with https://
rather than http://
for your integration to work. You can test your integration without doing so, but remember to enable HTTPS when you’re ready to accept live payments.
The Payment Element renders a dynamic form that allows your customer to pick a payment method. For each payment method, the form automatically asks the customer to fill in all necessary payment details.
Customize appearance
Customize the Payment Element to match the design of your site by passing the appearance object into options
when creating the Elements
provider.
Request Apple Pay merchant token
If you accept Apple Pay payments, we recommend configuring the Apple Pay interface to return a merchant token to enable merchant initiated transactions (MIT). Request the relevant merchant token type in the Payment Element. The following example shows a request for the deferred payments merchant token.
const paymentElement = elements.create('payment', { applePay: { deferredPaymentRequest: { paymentDescription: 'My deferred payment', managementURL: 'https://example.com/billing', deferredBilling: { amount: 2500, label: 'Deferred Fee', deferredPaymentDate: new Date('2024-01-05') }, } }, // Other options });
Configure currency
When using SetupIntents with automatic_payment_methods, passing currency into options
when creating the Elements
provider, influences which payment methods are rendered by the Payment Element. Payment Element renders the payment methods enabled in the Stripe Dashboard that support the provided currency. See Payment method integration options for more details about what’s supported.
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.
Submit the payment details to StripeClient-side
Use stripe.confirmSetup to complete the setup using details collected by the Payment Element. Provide a return_url to this function so that Stripe can redirect the user after they complete setup. We may first redirect them to an intermediate site, like a bank authorization page, before redirecting them to the return_
.
If your customer saves their card details, we immediately redirect them to the return_
when setup is successful. If you don’t want to redirect for card payments, you can set redirect to if_
. This only redirects customers that check out with redirect-based payment methods.
Make sure the return_
corresponds to a page on your website that provides the status of the SetupIntent
. Stripe provides the following URL query parameters to verify the status when we redirect the customer to the return_
. You can also append your own query parameters when providing the return_
, and they persist through the redirect process.
Parameter | Description |
---|---|
setup_ | The unique identifier for the SetupIntent . |
setup_ | The client secret of the SetupIntent object. |
You can use stripe.retrieveSetupIntent to retrieve the SetupIntent using the setup_
query parameter. Successful confirmation of the SetupIntent saves the resulting PaymentMethod
ID (in result.
) to the provided Customer
.
Mise en garde
If you have tooling that tracks the customer’s browser session, you might need to add the stripe.
domain to the referrer exclude list. Redirects cause some tools to create new sessions which prevents you from tracking the complete session.
Charge the saved payment method laterServer-side
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.
Test the integration
Use test payment details and the test redirect page to verify your integration. Click the tabs below to view details for each payment method.
Test charging a saved SEPA Debit PaymentMethod
Confirming the SetupIntent using iDEAL, Bancontact, or Sofort, generates a SEPA Direct Debit PaymentMethod. SEPA Direct Debit is a delayed notification payment method that transitions to an intermediate processing
state before transitioning several days later to a succeeded
or requires_
state.
Disclose Stripe to your customers
Stripe collects information on customer interactions with Elements to provide services to you, prevent fraud, and improve its services. This includes using cookies and IP addresses to identify which Elements a customer saw during a single checkout session. You’re responsible for disclosing and obtaining all rights and consents necessary for Stripe to use data in these ways. For more information, visit our privacy center.