Stripe Test Cards: Complete Guide for Testing Checkout Flows
A practical Stripe test cards reference for successful payments, declines, 3D Secure, CVC and expiry errors, subscriptions, and full checkout flow monitoring.
Stripe test cards let you simulate real payment outcomes without moving real money. They are useful for checking one card form, but they are even more useful when you treat them as part of a complete checkout QA plan: pricing page, checkout session, payment confirmation, webhook handling, subscription state, account access, and post-deploy monitoring.
This guide gives you a practical Stripe test cards reference for the scenarios most teams need before launching a checkout flow: successful payments, declined cards, Strong Customer Authentication (SCA), 3D Secure, CVC and expiry errors, saved cards, subscriptions, and production-like checkout flow checks.
For the full official list, use Stripe's testing documentation. The cards below are the ones most teams should include in a repeatable checkout test plan.
Quick Stripe Test Cards Reference
Use these values only with Stripe test API keys or a Stripe sandbox. Do not use real card details in test mode or test cards in live mode.
For interactive testing, Stripe generally accepts:
- Any future expiry date, such as
12/34 - Any three-digit CVC for most cards
- Any four-digit CVC for American Express
- Any name, ZIP, and address unless you are specifically testing address validation
| Scenario | Test card | Expected result |
|---|---:|---|
| Successful Visa payment | 4242 4242 4242 4242 | Payment succeeds |
| Successful Visa debit payment | 4000 0566 5566 5556 | Payment succeeds |
| Successful Mastercard payment | 5555 5555 5555 4444 | Payment succeeds |
| Successful American Express payment | 3782 822463 10005 | Payment succeeds with a four-digit CVC |
| Generic decline | 4000 0000 0000 0002 | Payment fails with card_declined |
| Insufficient funds | 4000 0000 0000 9995 | Payment fails with insufficient_funds |
| Expired card | 4000 0000 0000 0069 | Payment fails with expired_card |
| Incorrect CVC | 4000 0000 0000 0127 | Payment fails with incorrect_cvc |
| Incorrect number | 4242 4242 4242 4241 | Payment fails with incorrect_number |
| 3D Secure authentication required | 4000 0025 0000 3155 | Authentication is required for on-session payments |
| Always authenticate | 4000 0027 6000 3184 | Authentication is required on all transactions |
If you are writing automated tests against the Stripe API, prefer Stripe's test PaymentMethod values, such as pm_card_visa, instead of hardcoding card numbers in server-side test code. Card numbers are best for browser-based checkout testing and manual QA.
How to Use Stripe Test Cards Safely
Before testing any checkout flow, confirm that the whole stack is pointed at test mode:
- The frontend uses your Stripe test publishable key.
- The backend uses your Stripe test secret key.
- Webhook endpoints are configured for test events.
- Products, prices, coupons, tax settings, and customer records are test-mode objects.
- Your app clearly separates test orders from real orders.
The most common Stripe testing mistake is mixing environments. For example, a checkout page might use a test publishable key while the backend tries to look up a live price ID. That can produce confusing failures that look like payment bugs but are really configuration bugs.
Use test mode for the full flow, not just the card input.
Test a Successful Checkout Flow
Start with the basic successful card:
Card: 4242 4242 4242 4242
Expiry: 12/34
CVC: 123
ZIP: 10001
A successful checkout test should verify more than "Stripe accepted the card." At minimum, check that:
- The user can start checkout from the correct plan, product, or cart.
- The Stripe Checkout or payment form loads without console-visible errors.
- The payment succeeds and redirects to the expected success page.
- The success page shows the right product, plan, or order state.
- The backend records the payment, subscription, or entitlement.
- The user receives access to the paid feature.
- Your webhook handler processes the relevant Stripe event.
- The user does not remain stuck in a pending, trial, or unpaid state.
If you sell subscriptions, also confirm that the app grants access only after the correct subscription status is active. A checkout redirect alone is not enough, because the source of truth should be the webhook-confirmed Stripe state.
Test Declined Cards
Decline handling is where many checkout flows feel unfinished. The happy path works, but the error path leaves users confused, sends them to a blank page, or creates a pending order that support has to clean up.
Use these Stripe test cards for the core decline cases:
| Scenario | Test card | What to verify |
|---|---:|---|
| Generic decline | 4000 0000 0000 0002 | The user sees a clear payment failure message and can retry |
| Insufficient funds | 4000 0000 0000 9995 | The copy suggests another card or payment method |
| Lost card | 4000 0000 0000 9987 | The app does not expose sensitive issuer details |
| Stolen card | 4000 0000 0000 9979 | The app handles the decline without retry loops |
| Processing error | 4000 0000 0000 0119 | The user can retry later without duplicate orders |
For each declined payment, check the full user experience:
- Is the error message understandable?
- Can the user try another card without restarting from scratch?
- Does the app avoid granting paid access?
- Does the order or subscription stay in a clean state?
- Does your team get enough logging to diagnose the failure?
Do not show raw Stripe error codes as the only user-facing message. Codes like card_declined are useful for logs, but the user needs plain English.
Test Expiry, CVC, and Invalid Card Errors
Some payment failures are validation failures rather than issuer declines. They are still important because users often hit them when entering card details on mobile.
Use these test cards:
| Scenario | Test card | Expected error |
|---|---:|---|
| Expired card | 4000 0000 0000 0069 | expired_card |
| Incorrect CVC | 4000 0000 0000 0127 | incorrect_cvc |
| Incorrect number | 4242 4242 4242 4241 | incorrect_number |
For these tests, verify that the user can correct the issue in place. The best experience keeps them in the checkout context, highlights the field that needs attention, and preserves non-sensitive form input.
If your checkout flow uses Stripe Checkout, much of the field-level validation is handled by Stripe. You still need to test what your own app does after the failure: retry links, plan selection, success and cancel URLs, pending order records, analytics events, and support visibility.
Test 3D Secure and SCA
3D Secure and Strong Customer Authentication are easy to miss if you only test with 4242 4242 4242 4242. European cards, bank rules, saved payment methods, and off-session billing can all introduce authentication requirements.
Use these Stripe test cards:
| Scenario | Test card | What it tests |
|---|---:|---|
| Authenticate unless set up | 4000 0025 0000 3155 | On-session payments require authentication; off-session behavior depends on setup |
| Always authenticate | 4000 0027 6000 3184 | Authentication is required on every transaction |
| Already set up for off-session use | 4000 0038 0000 0446 | Useful for saved-card and future-payment flows |
| Authenticate, then decline | 4000 0082 6000 3178 | Authentication succeeds, but the payment still fails with insufficient funds |
A complete 3D Secure test should verify that:
- The authentication challenge appears when expected.
- The user returns to the right page after completing authentication.
- The app handles both success and failure after authentication.
- The loading state does not hang while waiting for Stripe.
- Webhooks update the user's account even if the browser redirect is interrupted.
- Off-session subscription renewals have a recovery path when authentication is required.
The last point matters for SaaS subscriptions. A first checkout can succeed while later invoices fail because the saved card requires customer action. Your dunning emails, billing portal links, and in-app billing state need to handle that.
Test Subscriptions and Saved Payment Methods
Subscriptions need more than one successful checkout test. You should test the lifecycle:
- New subscription checkout succeeds.
- The user's plan changes after webhook confirmation.
- The billing portal opens for the right customer.
- The user can update a saved card.
- A renewal failure removes or limits access according to your policy.
- Cancellation and resume flows update the app correctly.
- Trial endings and coupon expirations do not create surprise states.
For saved payment methods, use Stripe's test PaymentMethod values in API-level tests when possible. For browser-level tests, use cards that trigger authentication and decline scenarios so you can verify what the customer actually sees.
If your app creates internal teams, workspaces, seats, credits, or usage limits after payment, test those records too. Many checkout bugs happen after Stripe succeeds: the payment is complete, but the product state is wrong.
Test Webhooks, Not Just Redirects
Stripe redirects are part of the user experience. Webhooks are part of the system of record.
Your checkout flow should not rely only on the user reaching a success URL. Users close tabs, mobile browsers get interrupted, ad blockers interfere with scripts, and network requests fail. Stripe webhooks are the reliable path for confirming payment and subscription changes.
For every important checkout scenario, verify the matching webhook behavior:
checkout.session.completedpayment_intent.succeededpayment_intent.payment_failedinvoice.paidinvoice.payment_failedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deleted
You do not need every event for every integration, but you do need a clear map of which events your app trusts and what each one changes in your database.
Test Full Checkout Flows After Deployment
Most teams test Stripe once during implementation, then assume checkout keeps working. That is risky because checkout flows depend on many moving parts:
- Pricing page links
- Plan IDs and price IDs
- Environment variables
- Stripe Checkout configuration
- Redirect URLs
- Webhook secrets
- Database writes
- Authentication state
- Feature gating
- Email delivery
- Analytics and conversion events
A deploy can break checkout even when the Stripe integration itself is fine. For example, a refactor can change the logged-in user's team ID, a pricing page update can point to the wrong plan, or a webhook secret can be missing in a new environment.
Build a post-deploy checkout test that runs like a real user:
- Visit the pricing page.
- Select the intended plan.
- Start checkout.
- Enter a Stripe test card in a test or staging environment.
- Complete any required authentication.
- Confirm the success page.
- Confirm the account has the expected entitlement.
- Confirm webhook-processed state in your app.
- Confirm the user can access the paid feature.
This is where scheduled browser checks help. QABot can run critical checkout flow checks on a schedule or after deployment, using the same kind of user journey you would manually test: open the app, start checkout, verify the result, and alert when something breaks.
Recommended Stripe Checkout Test Plan
Use this as a minimum checklist before launching or changing checkout:
| Test | Card or method | Expected result |
|---|---|---|
| Happy path checkout | 4242 4242 4242 4242 | Payment succeeds and access is granted |
| Generic decline | 4000 0000 0000 0002 | Access is not granted and the user can retry |
| Insufficient funds | 4000 0000 0000 9995 | Clear failure message and clean order state |
| Expired card | 4000 0000 0000 0069 | User can correct payment details |
| Incorrect CVC | 4000 0000 0000 0127 | User sees a field-level payment error |
| 3D Secure required | 4000 0025 0000 3155 | Authentication challenge and return flow work |
| Authentication then decline | 4000 0082 6000 3178 | App handles post-auth payment failure |
| Webhook confirmation | Stripe CLI or test event | Database state updates from webhook |
| Cancel URL | User exits checkout | App returns to a useful page without granting access |
| Post-deploy scheduled check | Browser automation | Critical checkout path still works after release |
Keep this suite small enough that your team will actually run it. A focused checkout suite that runs on every release is better than a giant spreadsheet that no one updates.
Common Stripe Test Card Mistakes
Only testing the happy path. A successful Visa card proves the basic integration works. It does not prove your checkout flow handles real customer problems.
Testing Stripe but not the product. The goal is not just "payment succeeded." The goal is "the customer can buy, receive access, and continue using the product."
Ignoring webhooks. Redirect-based success can hide webhook failures. Always test the backend state that unlocks paid access.
Mixing live and test objects. Keep separate test products, prices, customers, API keys, and webhook secrets.
Skipping 3D Secure. SCA issues often appear late because teams use only the basic Visa test card.
Not testing after deploy. Checkout depends on configuration and app code. Treat it as a critical flow that needs continuous monitoring.
Final Takeaway
Stripe test cards are not just a list of fake numbers. They are a way to model the payment outcomes your users will hit in production: success, declines, authentication, invalid details, webhook delays, and interrupted sessions.
Start with the core cards above, wire them into a repeatable checkout QA checklist, and run that checklist after meaningful checkout changes. For critical flows like signup, login, and checkout, QABot can turn those checks into scheduled browser tests so you find broken payment paths before customers do.