Skip to content
Create account
or
Sign in
The Stripe Docs logo
/
Ask AI
Create account
Sign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
Overview
About Stripe payments
Upgrade your integration
Payments analytics
Online payments
OverviewFind your use caseManaged Payments
Use Payment Links
Build a checkout page
Build an advanced integration
    Overview
    Quickstart
    Design an advanced integration
    Customize look and feel
    Manage payment methods
    Collect additional information
    Collect taxes on your payments
    Save the payment method used for a payment
    Save a payment method without making a payment
    Send receipts and paid invoices
Build an in-app integration
Payment methods
Add payment methods
Manage payment methods
Faster checkout with Link
Payment interfaces
Payment Links
Checkout
Web Elements
In-app Elements
Payment scenarios
Handle multiple currencies
Custom payment flows
Flexible acquiring
Orchestration
In-person payments
Terminal
Beyond payments
Incorporate your company
Crypto
Financial Connections
Climate
Understand fraud
Radar fraud protection
Manage disputes
Verify identities
HomePaymentsBuild an advanced integration

Save a customer's payment method when they use it for a payment

Learn how to save the customer's payment method when you confirm a PaymentIntent.

Use the Payment Intents API to save payment details from a purchase. There are several use cases:

  • Charge a customer for an e-commerce order and store the details for future purchases.
  • Initiate the first payment of a series of recurring payments.
  • Charge a deposit and store the details to charge the full amount later.

Card-present transactions

Card-present transactions, such as payments 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.

Set up Stripe
Server-side

First, register for a Stripe account.

Use our official libraries to access the Stripe API from your application:

Command Line
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
# Available as a gem sudo gem install stripe
Gemfile
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
# If you use bundler, you can add this line to your Gemfile gem 'stripe'

Create a Customer
Server-side

To set a card up 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.

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/customers \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d name="Jenny Rosen" \ --data-urlencode email="jennyrosen@example.com"

Successful creation returns the Customer object. You can inspect the object for the customer id and store the value in your database for later retrieval.

You can find these customers in the Customers page in the Dashboard.

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 PaymentIntent.

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 payment
Server-side

Note

If you want to render the Payment Element without first creating a PaymentIntent, see Collect payment details before creating an Intent.

The PaymentIntent object represents your intent to collect payment from a customer and tracks charge attempts and state changes throughout the payment process.

Create the PaymentIntent

Create a PaymentIntent on your server. Specify an amount, currency, and customer. In the latest version of the API, specifying the automatic_payment_methods parameter is optional because Stripe enables its functionality by default. Enable setup_future_usage. The payment methods you configured in the Dashboard are automatically added to the Payment Intent.

If you don’t want to use the Dashboard or if you want to specify payment methods manually, you can list them using the payment_method_types attribute.

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/payment_intents \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d customer=
{{CUSTOMER_ID}}
\ -d amount=1099 \ -d currency=usd \ -d setup_future_usage=off_session \ -d "automatic_payment_methods[enabled]"=true

Note

Always decide how much to charge on the server side, a trusted environment, as opposed to the client. This prevents malicious customers from being able to choose their own prices.

Retrieve the client secret

The PaymentIntent 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.

Retrieve the client secret from an endpoint on your server, using the browser’s fetch function. This approach is best if your client side is a single-page application, particularly one built with a modern frontend framework like React. Create the server endpoint that serves the client secret:

main.rb
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
get '/secret' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end

And then fetch the client secret with JavaScript on the client side:

(async () => { const response = await fetch('/secret'); const {client_secret: clientSecret} = await response.json(); // Render the form using the clientSecret })();

Collect payment details
Client-side

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.

If you do choose to use an iframe and want to accept Apple Pay or Google Pay, the iframe must have the allow attribute set to equal "payment *".

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.

Set up Stripe.js

The Payment Element is automatically available as a feature of Stripe.js. Include the Stripe.js script on your checkout page by adding it to the head of your HTML file. Always load Stripe.js directly from js.stripe.com to remain PCI compliant. Don’t include the script in a bundle or host a copy of it yourself.

checkout.html
<head> <title>Checkout</title> <script src="https://js.stripe.com/basil/stripe.js"></script> </head>

Create an instance of Stripe with the following JavaScript on your checkout page:

checkout.js
// Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe(
'pk_test_TYooMQauvdEDq54NiTphI7jx'
);

Add the Payment Element to your payment page

The Payment Element needs a place to live on your payment page. Create an empty DOM node (container) with a unique ID in your payment form:

checkout.html
<form id="payment-form"> <div id="payment-element"> <!-- Elements will create form elements here --> </div> <button id="submit">Submit</button> <div id="error-message"> <!-- Display error message to your customers here --> </div> </form>

When the previous form loads, create an instance of the Payment Element and mount it to the container DOM node. Pass the client secret from the previous step into options when you create the Elements instance:

Handle the client secret carefully because it can complete the charge. Don’t log it, embed it in URLs, or expose it to anyone but the customer.

checkout.js
const options = { clientSecret: '{{CLIENT_SECRET}}', // Fully customizable with appearance API. appearance: {/*...*/}, }; // Set up Stripe.js and Elements to use in checkout form, passing the client secret obtained in a previous step const elements = stripe.elements(options); // Create and mount the Payment Element const paymentElementOptions = { layout: 'accordion'}; const paymentElement = elements.create('payment', paymentElementOptions); paymentElement.mount('#payment-element');

Browse Stripe Elements

Stripe Elements is a collection of drop-in UI components. To further customize your form or collect different customer information, browse the Elements docs.

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.

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.

Request Apple Pay merchant token

If you’ve configured your integration to 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.

OptionalLink in your checkout page
Client-side

Let your customer check out faster by using Link in the Payment Element. You can autofill information for any logged-in customer already using Link, regardless of whether they initially saved their information in Link with another business. The default Payment Element integration includes a Link prompt in the card form. To manage Link in the Payment Element, go to your payment method settings.

Authenticate or enroll with Link directly in the Payment Element during checkout

Collect a customer email address for Link authentication or enrollment

Integration options

There are two ways you can integrate Link with the Payment Element. Of these, Stripe recommends passing a customer email address to the Payment Element if available. Remember to consider how your checkout flow works when deciding between these options:

Integration optionCheckout flowDescription
Pass a customer email address to the Payment Element Recommended
  • Your customer enters their email address before landing on the checkout page (in a previous account creation step, for example).
  • You prefer to use your own email input field.
Programmatically pass a customer email address to the Payment Element. In this scenario, a customer authenticates to Link directly in the payment form instead of a separate UI component.
Collect a customer email address in the Payment ElementYour customers enter their email and authenticate or enroll with Link directly in the Payment Element during checkout.If a customer hasn’t enrolled with Link and they choose a supported payment method in the Payment Element, they’re prompted to save their details using Link. For those who have already enrolled, Link automatically populates their payment information.

OptionalSave and retrieve customer payment methods

You can configure the Payment Element to save your customer’s payment methods for future use. This section shows you how to integrate the saved payment methods feature, which enables the Payment Element to:

  • Prompt buyers for consent to save a payment method
  • Save payment methods when buyers provide consent
  • Display saved payment methods to buyers for future purchases
  • Automatically update lost or expired cards when buyers replace them
The Payment Element and a saved payment method checkbox

Save payment methods.

The Payment Element with a Saved payment method selected

Reuse a previously saved payment method.

Enable saving the payment method in the Payment Element

When creating a PaymentIntent on your server, also create a CustomerSession providing the Customer ID and enabling the payment_element component for your session. Configure which saved payment method features you want to enable. For instance, enabling payment_method_save displays a checkbox offering customers to save their payment details for future use.

You can specify setup_future_usage on a PaymentIntent or Checkout Session to override the default behavior for saving payment methods. This ensures that you automatically save the payment method for future use, even if the customer doesn’t explicitly choose to save it.

Caution

Allowing buyers to remove their saved payment methods by enabling payment_method_remove impacts subscriptions that depend on that payment method. Removing the payment method detaches the PaymentMethod from that Customer.

server.rb
Ruby
Python
PHP
Node.js
Java
Go
.NET
No results
# Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key =
'sk_test_BQokikJOvBiI2HlWgH4olfQ2'
post '/create-intent-and-customer-session' do intent = Stripe::PaymentIntent.create({ amount: 1099, currency: 'usd', # In the latest version of the API, specifying the `automatic_payment_methods` parameter # is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true}, customer:
{{CUSTOMER_ID}}
, }) customer_session = Stripe::CustomerSession.create({ customer:
{{CUSTOMER_ID}}
, components: { payment_element: { enabled: true, features: { payment_method_redisplay: 'enabled', payment_method_save: 'enabled', payment_method_save_usage: 'off_session', payment_method_remove: 'enabled', }, }, }, }) { client_secret: intent.client_secret, customer_session_client_secret: customer_session.client_secret }.to_json end

Your Elements instance uses the CustomerSession’s client secret to access that customer’s saved payment methods. Handle errors properly when you create the CustomerSession. If an error occurs, you don’t need to provide the CustomerSession client secret to the Elements instance, as it’s optional.

Create the Elements instance using the client secrets for both the PaymentIntent and the CustomerSession. Then, use this Elements instance to create a Payment Element.

checkout.js
// Create the CustomerSession and obtain its clientSecret const res = await fetch("/create-intent-and-customer-session", { method: "POST" }); const { customer_session_client_secret: customerSessionClientSecret } = await res.json(); const elementsOptions = { clientSecret: '{{CLIENT_SECRET}}', customerSessionClientSecret, // Fully customizable with appearance API. appearance: {/*...*/}, }; // Set up Stripe.js and Elements to use in checkout form, passing the client secret // and CustomerSession's client secret obtained in a previous step const elements = stripe.elements(elementsOptions); // Create and mount the Payment Element const paymentElementOptions = { layout: 'accordion'}; const paymentElement = elements.create('payment', paymentElementOptions); paymentElement.mount('#payment-element');

When confirming the PaymentIntent, Stripe.js automatically controls setting setup_future_usage on the PaymentIntent and allow_redisplay on the PaymentMethod, depending on whether the customer checked the box to save their payment details.

Enforce CVC recollection

Optionally, specify require_cvc_recollection when creating the PaymentIntent to enforce CVC recollection when a customer is paying with a card.

Detect the selection of a saved payment method

To control dynamic content when a saved payment method is selected, listen to the Payment Element change event, which is populated with the selected payment method.

checkout.js
paymentElement.on('change', function(event) { if (event.value.payment_method) { // Control dynamic content if a saved payment method is selected } })

OptionalCollect address details
Client-side

The Address Element lets you collect shipping or billing addresses. Create an empty DOM node for the Address Element. Display it after the Link Authentication Element:

checkout.html
<form id="payment-form"> <h3>Contact info</h3> <div id="link-authentication-element"></div> <h3>Shipping</h3> <div id="address-element"></div> <h3>Payment</h3> <div id="payment-element"></div> <button type="submit">Submit</button> </form>

Then, create an instance of the Address Element, and mount it to the DOM node:

checkout.js
// Customize the appearance of Elements using the Appearance API. const appearance = { /* ... */ }; // Enable the skeleton loader UI for the optimal loading experience. const loader = 'auto'; const stripe = Stripe(
'pk_test_TYooMQauvdEDq54NiTphI7jx'
); // Create an elements group from the Stripe instance passing in the clientSecret and, optionally, appearance. const elements = stripe.elements({clientSecret, appearance, loader}); // Create Element instances const linkAuthenticationElement = elements.create("linkAuthentication"); const addressElement = elements.create("address", { mode: 'shipping', allowedCountries: ['US'] }); const paymentElement = elements.create("payment"); // Mount the Elements to their corresponding DOM node linkAuthenticationElement.mount("#link-authentication-element"); addressElement.mount("#address-element"); paymentElement.mount("#payment-element");

Display the Address Element before the Payment Element. The Payment Element dynamically detects address data collected by the Address Element, hiding unnecessary fields and collecting additional billing address details as necessary.

Retrieve address information

The Address Element automatically passes the shipping address when a customer submits payment, but you can also retrieve the address details on the frontend using the change event. The change event sends whenever the user updates any field in the Address Element, or after selecting saved addresses:

addressElement.on('change', (event: AddressChangeEvent) => { const address = event.value; })

Prefill a shipping address

Use defaultValues to prefill address information, speeding checkout for your customers.

// Create addressElement with the defaultValues option const addressElement = elements.create("address", { mode: 'shipping', defaultValues: { name: 'Jane Doe', address: { line1: '354 Oyster Point Blvd', line2: '', city: 'South San Francisco', state: 'CA', postal_code: '94080', country: 'US', } } }); // Mount the Element to its corresponding DOM node addressElement.mount("#address-element");

OptionalCustomize the layout
Client-side

You can customize the Payment Element’s layout (accordion or tabs) to fit your checkout interface. For more information about each of the properties, see elements.create.

You can start using the layout features by passing a layout type and other optional properties when creating the Payment Element:

const paymentElement = elements.create('payment', { layout: { type: 'accordion', defaultCollapsed: false, radios: true, spacedAccordionItems: false } });

The following image is the same Payment Element rendered using different layout configurations:

Three checkout form experiences

Payment Element layouts

OptionalCustomize the appearance
Client-side

Now that you’ve added the Payment Element to your page, you can customize its appearance to make it fit your design. To learn more about customizing the Payment Element, see Elements Appearance API.

Customize the Payment Element

Customize the Payment Element

OptionalFetch updates from the server
Client-side

You might want to update attributes on the PaymentIntent after the Payment Element renders, such as the amount (for example, discount codes or shipping costs). You can update the PaymentIntent on your server, then call elements.fetchUpdates to see the new amount reflected in the Payment Element. This example shows you how to create the server endpoint that updates the amount on the PaymentIntent:

main.rb
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
get '/update' do intent = Stripe::PaymentIntent.update( '{{PAYMENT_INTENT_ID}}', {amount: 1499}, ) {status: intent.status}.to_json end

This example demonstrates how to update the UI to reflect these changes on the client side:

(async () => { const response = await fetch('/update'); if (response.status === 'requires_payment_method') { const {error} = await elements.fetchUpdates(); } })();

Submit the payment to Stripe
Client-side

Use stripe.confirmPayment to complete the payment 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 payment. Your user may be first redirected to an intermediate site, like a bank authorization page, before being redirected to the return_url. Card payments immediately redirect to the return_url when a payment is successful.

If you don’t want to redirect for card payments after payment completion, you can set redirect to if_required. This only redirects customers that check out with redirect-based payment methods.

checkout.js
const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const {error} = await stripe.confirmPayment({ //`Elements` instance that was used to create the Payment Element elements, 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.confirmPayment may 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 succeeded, the card is saved to the Customer object. This is reflected on the PaymentMethod’s customer field. At this point, associate the ID of the Customer object with your own internal representation of a customer, if you have one. Now you can use the stored PaymentMethod object to collect payments from your customer in the future without prompting them for their payment details again.

Make sure the return_url corresponds to a page on your website that provides the status of the payment. When Stripe redirects the customer to the return_url, we provide the following URL query parameters:

ParameterDescription
payment_intentThe unique identifier for the PaymentIntent.
payment_intent_client_secretThe client secret of the PaymentIntent object.

Caution

If you have tooling that tracks the customer’s browser session, you might need to add the stripe.com domain to the referrer exclude list. Redirects cause some tools to create new sessions, which prevents you from tracking the complete session.

Use one of the query parameters to retrieve the PaymentIntent. Inspect the status of the PaymentIntent to decide what to show your customers. You can also append your own query parameters when providing the return_url, which persist through the redirect process.

status.js
// Initialize Stripe.js using your publishable key const stripe = Stripe(
'pk_test_TYooMQauvdEDq54NiTphI7jx'
); // Retrieve the "payment_intent_client_secret" query parameter appended to // your return_url by Stripe.js const clientSecret = new URLSearchParams(window.location.search).get( 'payment_intent_client_secret' ); // Retrieve the PaymentIntent stripe.retrievePaymentIntent(clientSecret).then(({paymentIntent}) => { const message = document.querySelector('#message') // Inspect the PaymentIntent `status` to indicate the status of the payment // to your customer. // // Some payment methods will [immediately succeed or fail][0] upon // confirmation, while others will first enter a `processing` state. // // [0]: https://stripe.com/docs/payments/payment-methods#payment-notification switch (paymentIntent.status) { case 'succeeded': message.innerText = 'Success! Payment received.'; break; case 'processing': message.innerText = "Payment processing. We'll update you when payment is received."; break; case 'requires_payment_method': message.innerText = 'Payment failed. Please try another payment method.'; // Redirect your user back to your payment page to attempt collecting // payment again break; default: message.innerText = 'Something went wrong.'; break; } });

Charge the saved payment method later
Server-side

Warning

bancontact, ideal, and sofort are one-time payment methods by default. When set up for future usage, they generate a sepa_debit reusable payment method type so you need to use sepa_debit 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.

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl -G https://api.stripe.com/v1/payment_methods \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d customer=
{{CUSTOMER_ID}}
\ -d type=card

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.
Command Line
curl
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/payment_intents \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -d amount=1099 \ -d currency=usd \ # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. -d "automatic_payment_methods[enabled]"=true \ -d customer="{{CUSTOMER_ID}}" \ -d payment_method="{{PAYMENT_METHOD_ID}}" \ -d return_url="https://example.com/order/123/complete" \ -d off_session=true \ -d confirm=true

OptionalSave payment details for future use
Server-side

As described in the Create a PaymentIntent step, you can save payment details to a customer by passing the setup_future_usage argument. While you can make a subset of payment methods reusable in this way, you can’t make all payment methods reusable. A single payment intent can handle both reusable and non-reusable payment methods. See the Payment method support page to learn more about which payment methods are compatible with setup_future_usage.

For example, you can accept card payments and Giropay (which you can’t reuse). When customers select the card payment method, you can save the payment method to the customer for future usage by configuring setup_future_usage=off_session on the payment_method_options[card] object.

If the customer declines to have their payment details saved, disable setup_future_usage in the PaymentIntent on the server-side. We don’t support making this adjustment on the client-side.

You can manage payment methods from the Dashboard. Stripe handles the return of eligible payment methods based on factors such as the transaction’s amount, currency, and payment flow.

Command Line
curl
Ruby
Python
PHP
Node.js
Stripe CLI
No results
curl https://api.stripe.com/v1/payment_intents \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -d "amount"=1099 \ -d "currency"="usd" \ -d "automatic_payment_methods[enabled]"="true" \ -d "payment_method_options[card][setup_future_usage]"="off_session"

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.

Payment methodScenarioHow to test
Credit cardThe card setup succeeds and doesn’t require authentication.Fill out the credit card form using the credit card number 4242 4242 4242 4242 with any expiration, CVC, and postal code.
Credit cardThe card requires authentication for the initial setup, then succeeds for subsequent payments.Fill out the credit card form using the credit card number 4000 0025 0000 3155 with any expiration, CVC, and postal code.
Credit cardThe card requires authentication for the initial setup and also requires authentication for subsequent payments.Fill out the credit card form using the credit card number 4000 0027 6000 3184 with any expiration, CVC, and postal code.
Credit cardThe card is declined during setup.Fill out the credit card form using the credit card number 4000 0000 0000 9995 with any expiration, CVC, and postal code.

Test charging a saved SEPA Debit PaymentMethod

Confirming the PaymentIntent 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_payment_method state.

Set payment_method.billing_details.email to one of the following values to test the PaymentIntent status transitions. You can include your own custom text at the beginning of the email address followed by an underscore. For example, test_1_generatedSepaDebitIntentsFail@example.com results in a SEPA Direct Debit PaymentMethod that always fails when used with a PaymentIntent.

Email AddressDescription
generatedSepaDebitIntentsSucceed@example.comThe PaymentIntent status transitions from processing to succeeded.
generatedSepaDebitIntentsSucceedDelayed@example.comThe PaymentIntent status transitions from processing to succeeded after at least three minutes.
generatedSepaDebitIntentsFail@example.comThe PaymentIntent status transitions from processing to requires_payment_method.
generatedSepaDebitIntentsFailDelayed@example.comThe PaymentIntent status transitions from processing to requires_payment_method after at least three minutes.
generatedSepaDebitIntentsSucceedDisputed@example.comThe PaymentIntent status transitions from processing to succeeded, but a dispute is created immediately.

OptionalApple Pay and Google Pay
Client-side

When you enable card payments, we display Apple Pay and Google Pay for customers whose environment meets the wallet display conditions. To accept payments from these wallets, you must also:

  • Enable them in your payment methods settings. Apple Pay is enabled by default.
  • Register your domain.

Regional Testing
India

Stripe Elements doesn’t support Google Pay or Apple Pay for Stripe accounts and customers in India. Therefore, you can’t test your Google Pay or Apple Pay integration if the tester’s IP address is in India, even if the Stripe account is based outside India.

See also

  • Save payment details during in-app payments
  • Save payment details in a Checkout session
  • Accept a payment
  • Set up future payments
  • Handle post-payment events
Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Join our early access program.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc