Skip to content
Create account or Sign in
The Stripe Docs logo
/
Ask AI
Create accountSign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
APIs & SDKsHelp
Overview
About Stripe payments
Upgrade your integration
Payments analytics
Online payments
OverviewFind your use caseUse Managed Payments
Use Payment Links
Use a pre-built checkout page
Build a custom integration with Elements
Build an in-app integration
In-person payments
Terminal
Payment Methods
Add payment methods
Manage payment methods
Faster checkout with Link
Payment scenarios
Handle multiple currencies
Custom payment flows
    Overview
    Payments for existing customers
    Authorise and capture a payment separately
    Build a two-step checkout flow
    Collect payment details before creating an Intent
    Finalise payments on the server
    Take mail orders and telephone orders (MOTO)
    US and Canadian cards
    Forward card details to third-party API endpoints
    Payments line items
Flexible acquiring
Orchestration
Beyond payments
Incorporate your company
Crypto
Agentic commerce
Financial Connections
Climate
Understand fraud
Radar fraud protection
Manage disputes
Verify identities
United States
English (United Kingdom)
HomePaymentsCustom payment flows

Payments for existing customers

Learn how to charge an existing payment method while a customer is on-session.

A Checkout Session allows buyers to enter their payment details. If the buyer is an existing customer, you can configure the Checkout Session to prefill the details with one of the customer’s saved cards. The Checkout Session displays up to 50 saved cards that a customer can choose to pay with.

Payment Element with one saved card

Create a Checkout Session
Client-side
Server-side

Checkout Sessions supports reusing existing Customer objects with the customer parameter. When reusing existing Customers, all objects created by Checkout, such as PaymentIntents and Subscriptions, are associated with that Customer object.

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/checkout/sessions \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d mode=payment \ -d ui_mode=custom \ -d "line_items[0][price]"=
"{{PRICE_ID}}"
\ -d "line_items[0][quantity]"=1 \ -d customer=
"{{CUSTOMER_ID}}"
\ --data-urlencode return_url="https://example.com/return?session_id={CHECKOUT_SESSION_ID}"

OptionalDisplay additional saved payment methods
Server-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 a customer for future purchases, make sure you’ve collected consent to save the payment method details for this specific future use.

By default, we only show payment methods set to always allow redisplay.

You can’t reuse Apple Pay and Google Pay during a Checkout Session, so these payment methods don’t appear in the list of saved options. You must display the Google Pay and Apple Pay UI, and the payment request button UI, each time the Checkout Session is active.

You can display other previously saved payment methods by including other redisplay values in the Checkout Session, or by updating a payment method’s allow_redisplay setting to always.

  • Use the allow_redisplay_filters parameter to specify which saved payment methods to show in Checkout. You can set any of the valid values: limited, unspecified and always.

    If you specify redisplay filtering in your Checkout Session, it overrides the default behaviour, so you must include the always value to see those saved payment methods.

    Command Line
    cURL
    Stripe CLI
    Ruby
    Python
    PHP
    Java
    Node.js
    Go
    .NET
    No results
    curl https://api.stripe.com/v1/checkout/sessions \ -u "
    sk_test_BQokikJOvBiI2HlWgH4olfQ2
    :"
    \ -d mode=payment \ -d ui_mode=custom \ -d "line_items[0][price]"=
    "{{PRICE_ID}}"
    \ -d "line_items[0][quantity]"=1 \ -d customer=
    "{{CUSTOMER_ID}}"
    \ --data-urlencode return_url="https://example.com/return?session_id={CHECKOUT_SESSION_ID}" \ -d "saved_payment_method_options[allow_redisplay_filters][0]"=always \ -d "saved_payment_method_options[allow_redisplay_filters][1]"=limited \ -d "saved_payment_method_options[allow_redisplay_filters][2]"=unspecified
  • Update the Payment Method to set the allow_redisplay value on individual payment methods.
    Command Line
    cURL
    Stripe CLI
    Ruby
    Python
    PHP
    Java
    Node.js
    Go
    .NET
    No results
    curl https://api.stripe.com/v1/payment_methods/
    {{PAYMENT_METHOD_ID}}
    \ -u "
    sk_test_BQokikJOvBiI2HlWgH4olfQ2
    :"
    \ -d allow_redisplay=always

Display the Payment Element
Client-side

Set up 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/clover/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"> <!-- Checkout will create form elements here --> </div> <button id="submit">Submit</button> <div id="error-message"> <!-- Display error message to your customers here --> </div> </form>

Fetch the Checkout Session client_secret from the previous step to initialise the Checkout object. Then create and mount the Payment Element.

checkout.js
const promise = fetch("/create-checkout-session", { method: "POST", headers: { "Content-Type": "application/json" }, }) .then((r) => r.json()) .then((r) => r.clientSecret); // Initialize Checkout const checkout = stripe.initCheckout({ clientSecret: promise, }); // Create and mount the Payment Element const paymentElement = checkout.createPaymentElement(); paymentElement.mount('#payment-element');

Prefill fields on payment page

If all the following conditions are true, the Session object contains the email, name, card, and billing address using details from the Customer’s saved card for you to display on your payment page, and the Payment Element to display the saved card:

  • Checkout is in payment or subscription mode; setup mode doesn’t support pre-filling fields.
  • The customer has a saved card. Checkout only supports pre-filling card payment methods.
  • The saved card has allow_redisplay set to always or you adjusted the default display setting.
  • The payment method includes billing_details required by the Checkout Session’s billing_address_collection value:
    • auto requires values for email, name, and address[country]. US, CA, and GB billing addresses also require address[postal_code].
    • required requires values for email, name, and all address fields.

If your Customer has multiple saved cards, the Payment Element displays the saved card matching the following prioritisation:

  • In payment mode, Stripe prefills the fields using the Customer’s newest saved card.
  • In subscription mode, Stripe prefills the Customer’s default payment method if it’s a card. Otherwise, Stripe prefills the newest saved card.

When collecting a shipping address, the Session object contains the shipping address fields if the Customer’s shipping.address meets the Checkout Session’s supported countries.

To let your customers remove saved cards during a Checkout Session, set save_payment_method_options[payment_method_remove] to enabled.

Pre-fill timeout

The pre-filled payment method displays for 30 minutes following Checkout Session creation. After it expires, loading the same Checkout Session doesn’t pre-fill the payment method any more for security reasons.

Submit the payment to Stripe
Client-side

Render a Pay button that calls confirm from the checkout instance to submit the payment.

index.html
<button id="pay-button">Pay</button> <div id="confirm-errors"></div>
checkout.js
const checkout = stripe.initCheckout({clientSecret}); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const {actions} = loadActionsResult; const button = document.getElementById('pay-button'); const errors = document.getElementById('confirm-errors'); button.addEventListener('click', () => { // Clear any validation errors errors.textContent = ''; actions.confirm().then((result) => { if (result.type === 'error') { errors.textContent = result.error.message; } }); }); }

Handle post-payment events
Server-side

Stripe sends a checkout.session.completed event when a customer completes a Checkout Session payment. Use the Dashboard webhook tool or follow the webhook guide to receive and handle these events, which might trigger you to:

  • Send an order confirmation email to your customer.
  • Log the sale in a database.
  • Start a shipping workflow.

Listen for these events rather than waiting for your customer to be redirected back to your website. Triggering fulfilment only from your Checkout landing page is unreliable. Setting up your integration to listen for asynchronous events allows you to accept different types of payment methods with a single integration.

Learn more in our fulfilment guide for Checkout.

Handle the following events when collecting payments with the Checkout:

EventDescriptionAction
checkout.session.completedSent when a customer successfully completes a Checkout Session.Send the customer an order confirmation and fulfill their order.
checkout.session.async_payment_succeededSent when a payment made with a delayed payment method, such as ACH direct debt, succeeds.Send the customer an order confirmation and fulfill their order.
checkout.session.async_payment_failedSent when a payment made with a delayed payment method, such as ACH direct debt, fails.Notify the customer of the failure and bring them back on-session to attempt payment again.
Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc