Save Payment Methods Fresh
Store customer payment methods for reuse — charging customers later when they're offline, or pre-filling payment info at future checkouts.
Two approaches
1. Save without an initial payment (Setup mode)
Use a Checkout Session in setup mode to collect payment details without charging:
javascript
const session = await stripe.checkout.sessions.create({
mode: 'setup',
customer: customer.id,
success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
cancel_url: 'https://example.com/cancel',
});2. Save during a payment
Set payment_intent_data.setup_future_usage when creating a Checkout Session for a one-time payment:
javascript
const session = await stripe.checkout.sessions.create({
line_items: [{ price: 'price_1234', quantity: 1 }],
mode: 'payment',
payment_intent_data: {
setup_future_usage: 'off_session',
},
success_url: 'https://example.com/success',
cancel_url: 'https://example.com/cancel',
});Create a customer first
Always attach saved payment methods to a Customer object:
bash
curl https://api.stripe.com/v1/customers \
-u "sk_test_YOUR_KEY:" \
-d email="customer@example.com"javascript
const customer = await stripe.customers.create({
email: 'customer@example.com',
name: 'Jane Doe',
});Retrieve saved payment methods
After setup, list the customer's saved payment methods:
bash
curl "https://api.stripe.com/v1/customers/cus_123/payment_methods?type=card" \
-u "sk_test_YOUR_KEY:"javascript
const paymentMethods = await stripe.customers.listPaymentMethods('cus_123', {
type: 'card',
});Charge a saved payment method
javascript
// Off-session (customer not present)
const paymentIntent = await stripe.paymentIntents.create({
amount: 2000,
currency: 'usd',
customer: 'cus_123',
payment_method: 'pm_abc123',
off_session: true,
confirm: true,
});Handle the case where authentication is required:
javascript
try {
const paymentIntent = await stripe.paymentIntents.create({
amount: 2000,
currency: 'usd',
customer: 'cus_123',
payment_method: 'pm_abc123',
off_session: true,
confirm: true,
});
} catch (err) {
if (err.code === 'authentication_required') {
// Bring customer back on-session to authenticate
// Send them an email with a link to complete payment
}
}Display saved methods at checkout
Show saved payment methods to returning customers:
javascript
const session = await stripe.checkout.sessions.create({
customer: 'cus_123', // Stripe shows their saved methods
line_items: [{ price: 'price_1234', quantity: 1 }],
mode: 'payment',
success_url: 'https://example.com/success',
cancel_url: 'https://example.com/cancel',
});Compliance
Before saving payment details, ensure your terms cover:
- Customer's permission for you to initiate payments
- Anticipated frequency and timing of charges
- How payment amounts are determined
- Cancellation policy (for subscriptions)
Always collect explicit consent. For on-session reuse: include a "Save card for future" checkbox. For off-session charging: display and collect agreement to mandate text.
allow_redisplay parameter
Control whether a saved payment method can be shown to the customer at future checkouts:
| Value | Meaning |
|---|---|
always | Show to customer in future checkouts |
limited | Only use for off-session payments |
unspecified | Default — Stripe decides |
javascript
// When confirming setup:
const { setupIntent } = await stripe.confirmSetup({
elements,
confirmParams: {
payment_method_data: {
allow_redisplay: 'always',
},
return_url: 'https://example.com/return',
},
});