Skip to content

Stripe SetupIntent — Complete Guide to Saving Payment Methods

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Stripe SetupIntent. We cover key concepts, practical examples, and best practices to help you master this topic.

Stripe SetupIntent collects payment method details for future use without creating a payment, enabling saved cards for subscriptions, wallets, and one-click checkout scenarios.

What You'll Learn

  • How SetupIntent differs from PaymentIntent
  • Creating and confirming a SetupIntent
  • Attaching payment methods to customers

Why It Matters

Without SetupIntent, you would need to charge a small amount to verify a card before saving it. SetupIntent validates the payment method zero-cost and stores it for future PaymentIntents.

Real-World Use

Durga Antivirus Pro subscription signup collects payment method via SetupIntent during free trial. At trial end, a PaymentIntent uses the saved method without asking the user to re-enter card details.

flowchart LR
    U["User Enters Card"] --> SI["SetupIntent"]
    SI --> V["Validate Card"]
    V --> PM["Save PaymentMethod"]
    PM --> C["Attach to Customer"]
    C --> PI["Future PaymentIntent"]
    style SI fill:#dbeafe,stroke:#2563eb

Code Examples

import stripe
stripe.api_key = 'sk_test_...'

# Create a SetupIntent on the server
setup_intent = stripe.SetupIntent.create(
    customer='cus_123',
    payment_method_types=['card'],
)
print(f"Client secret: {setup_intent.client_secret}")

# After confirmation, attach to customer
setup_intent = stripe.SetupIntent.retrieve('seti_123')
payment_method = setup_intent.payment_method
print(f"PaymentMethod: {payment_method}")

# Use for future payment
charge = stripe.PaymentIntent.create(
    amount=2000,
    currency='usd',
    customer='cus_123',
    payment_method=payment_method,
    off_session=True,
    confirm=True,
)

Expected output: SetupIntent returns client_secret for frontend confirmation; saved payment method used for future charges.

// Frontend SetupIntent confirmation with Stripe.js
const stripe = Stripe('pk_test_...');

async function savePaymentMethod() {
  const { setupIntent, error } = await stripe.confirmCardSetup(
    clientSecret,
    { payment_method: { card: elements.getElement('card') } }
  );

  if (error) {
    console.error('Setup failed:', error.message);
  } else {
    console.log('Payment method saved:', setupIntent.payment_method);
    // Now can charge later
  }
}

// One-click payment using saved method
async function chargeSaved() {
  const { error } = await stripe.confirmCardPayment(clientSecret);
  if (error) {
    console.error('Payment failed:', error.message);
  }
}

Expected output: Card saved without charging; later payment uses saved method with one click.

# SetupIntent with usage limits
import stripe
stripe.api_key = 'sk_test_...'

# Single-use setup intent
setup_intent = stripe.SetupIntent.create(
    customer='cus_123',
    payment_method_types=['card'],
    usage='off_session',
    metadata={'purpose': 'subscription_renewal'}
)

# Multiple payment methods
multi_setup = stripe.SetupIntent.create(
    customer='cus_456',
    payment_method_types=['card', 'ideal', 'sepa_debit'],
)

print(f"Multi-method setup: {multi_setup.id}")

Expected output: SetupIntent configured for off_session usage; multiple payment method types supported.

Common Mistakes

1. Using PaymentIntent Instead of SetupIntent

PaymentIntent charges the card immediately. Use SetupIntent when you only want to save the method for later use.

2. Not Attaching the PaymentMethod to a Customer

A SetupIntent creates a PaymentMethod but does not automatically attach it. Attach to customer for future use.

3. Ignoring Confirmation Errors

SetupIntent requires client-side confirmation. Handle card errors (expired, insufficient funds) during setup.

4. No Off-Session Flag for Future Charges

When charging saved cards later, set off_session=True or the payment may require 3D Secure authentication.

5. Overlooking 3D Secure Requirements

Some cards require 3D Secure even during setup. Handle authentication_required status in the frontend.

Practice Questions

  1. What is the difference between SetupIntent and PaymentIntent?
  2. Why must the PaymentMethod be attached to a Customer?
  3. What does off_session flag do when charging saved cards?
  4. How does 3D Secure affect SetupIntent?
  5. What is the client_secret used for?

Answers:

  1. SetupIntent saves a payment method without charging; PaymentIntent captures payment immediately.
  2. Attaching to Customer links the method to a user for retrieval and reuse in future payments.
  3. It indicates the payment is initiated by the merchant, not the customer, which affects 3D Secure rules.
  4. Some cards require 3D Secure authentication during setup; handle the authentication_required status.
  5. The client_secret initializes the frontend Stripe.js confirmation flow securely.

Challenge: Build a subscription signup flow: SetupIntent collects card during free trial, PaymentIntent charges saved card at trial end, handle 3D Secure authentication, and send email on payment failure.

FAQ

Does SetupIntent charge the customer?

: No, SetupIntent only validates the payment method. No charge is made.

Can SetupIntent be used with wallets like Apple Pay?

: Yes, SetupIntent supports card and wallet payment methods.

What happens if the card expires after setup?

: The PaymentMethod becomes invalid. Use Webhooks to detect failed payments and prompt for update.

How do you update a saved payment method?

: Create a new SetupIntent with the same customer. Attach the new PaymentMethod and set it as default.

Is SetupIntent PCI-compliant?

: Yes, card details are handled by Stripe Elements; your server never sees raw card numbers.

Mini Project

Build a payment method management UI: users add a card via SetupIntent, see saved methods, set a default, remove old cards, and view the last 4 digits and expiry dates. Handle 3D Secure during setup.

What's Next

Learn about Stripe PaymentMethod API for managing saved methods, or explore Stripe Subscriptions for recurring billing with saved payment methods.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro