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
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 Payments
Payment scenarios
Handle multiple currencies
Custom payment flows
    Overview
    Payments for existing customers
    Authorize and capture a payment separately
    Build a two-step checkout flow
    Collect payment details before creating an Intent
    Finalize 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
In-person payments
Terminal
Beyond payments
Incorporate your company
Crypto
Financial Connections
Climate
Understand fraud
Radar fraud protection
Manage disputes
Verify identities
HomePaymentsCustom payment flows

Payments for existing customers

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

To completely control how you display existing Payment Methods, use the Direct API implementation.

Display Payment Methods
Client-side
Server-side

Call the list Payment Method endpoint with the allow_redisplay parameter to retrieve a customer’s reusable payment methods.

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

Use the API response data to display the Payment Methods in your own UI and let the customer select one.

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 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 parameter to specify which saved payment methods to show the customer. You can set any of the valid values: limited, unspecified and always.
    Command Line
    cURL
    Stripe CLI
    Ruby
    Python
    PHP
    Java
    Node.js
    Go
    .NET
    No results
    curl -G https://api.stripe.com/v1/customers/
    {{CUSTOMER_ID}}
    /payment_methods
    \ -u "
    sk_test_BQokikJOvBiI2HlWgH4olfQ2
    :"
    \ -d allow_redisplay=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

Create PaymentIntent
Server-side

Create a PaymentIntent to try to charge the customer with the payment method they selected.

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 \ -d customer={{CUSTOMER_ID}} \ -d payment_method={{PAYMENT_METHOD_ID}} \ -d confirm=true \ --data-urlencode return_url="https://example.com/order/123/complete"

If the API call fails with a 402 response, it means the payment was declined. Ask the customer to try again or use a different payment method.

Check PaymentIntent status
Client-side
Server-side

Assuming the PaymentIntent is successfully created, check its status:

  • succeeded indicates the customer was charged as expected. Display a success message to your customer.
  • requires_action indicates you must prompt additional action, such as authenticating with 3D Secure. Call handleNextAction on the frontend to trigger the action the customer needs to perform.
checkout.js
const { error, paymentIntent } = await stripe.handleNextAction({ clientSecret: "{{CLIENT_SECRET}}" }); if (error) { // Show error from Stripe.js } else { // Actions handled, show success message }

Handle post-payment events
Server-side

Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard webhook tool or follow the webhook guide to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.

Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.

In addition to handling the payment_intent.succeeded event, we recommend handling these other events when collecting payments with the Payment Element:

EventDescriptionAction
payment_intent.succeededSent when a customer successfully completes a payment.Send the customer an order confirmation and fulfill their order.
payment_intent.processingSent when a customer successfully initiates a payment, but the payment has yet to complete. This event is most commonly sent when the customer initiates a bank debit. It’s followed by either a payment_intent.succeeded or payment_intent.payment_failed event in the future.Send the customer an order confirmation that indicates their payment is pending. For digital goods, you might want to fulfill the order before waiting for payment to complete.
payment_intent.payment_failedSent when a customer attempts a payment, but the payment fails.If a payment transitions from processing to payment_failed, offer the customer another attempt to pay.
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