Every developer integrating Stripe hits the same wall on day one: you need to test the checkout flow, but you can't run real card numbers without burning real money. Stripe ships a set of test card numbers that work only against test API keys — and there are dozens of them, each designed to trigger a specific outcome. This cheat sheet covers the ones you'll actually use.
If you'd rather generate valid test card numbers on demand, DevZone's Credit Card Test Numbers tool spits out Luhn-valid test PANs grouped by network and scenario.
How Stripe Test Cards Work
Test card numbers only succeed when your code is using a test mode API key (it starts with sk_test_ for secret keys and pk_test_ for publishable keys). Hit Stripe's live API with a test card and you'll get a card_declined error. Hit Stripe's test API with a real card and you'll see the same error in reverse.
For every test card, Stripe ignores the expiry date and CVC — you can use any future date and any 3-digit CVC (4 digits for Amex). The card number itself is what controls the outcome.
This is why the test cards are useful: you're not testing the card, you're testing how your code handles a specific response from Stripe's API.
Successful Payment Test Cards
These are the cards you'll use for the golden path — checkout succeeds, customer is charged, your webhook fires.
| Brand | Number | Notes |
|---|---|---|
| Visa | 4242 4242 4242 4242 |
The default. Use this everywhere. |
| Visa (debit) | 4000 0566 5566 5556 |
Acts as a debit card |
| Mastercard | 5555 5555 5555 4444 |
|
| Mastercard (debit) | 5200 8282 8282 8210 |
|
| Mastercard (prepaid) | 5105 1051 0510 5100 |
|
| Amex | 3782 822463 10005 |
4-digit CVC |
| Discover | 6011 1111 1111 1117 |
|
| Diners Club | 3056 9300 0902 0004 |
|
| JCB | 3566 0020 2036 0505 |
|
| UnionPay | 6200 0000 0000 0005 |
For most flows, 4242 4242 4242 4242 is all you need. Reach for the others only when you need to test brand-specific UI (showing different card-network logos) or want to confirm your code handles non-Visa BINs.
Decline Codes — Triggering Specific Failures
Stripe encodes decline reasons in dedicated test card numbers. Each one returns a different decline_code so you can test your error handling against real failure paths.
| Card number | Decline code | When you'd see this in production |
|---|---|---|
4000 0000 0000 0002 |
generic_decline |
Bank declined for unspecified reason |
4000 0000 0000 9995 |
insufficient_funds |
Customer doesn't have the money |
4000 0000 0000 9987 |
lost_card |
Card reported lost |
4000 0000 0000 9979 |
stolen_card |
Card reported stolen |
4000 0000 0000 0069 |
expired_card |
Card expiry has passed |
4000 0000 0000 0127 |
incorrect_cvc |
CVC doesn't match |
4000 0000 0000 0119 |
processing_error |
Issuer-side error, retry advised |
4242 4242 4242 4241 |
incorrect_number |
Luhn check fails |
The right behaviour for your app depends on the decline code. insufficient_funds is recoverable — the customer can try a different card. stolen_card should silently fail in your UI without telling the user why (telling them helps fraudsters). processing_error is a candidate for an automatic retry.
3D Secure (SCA) Test Cards
If you take payments from EU/UK/India customers, Strong Customer Authentication is non-negotiable. These cards trigger the 3DS challenge flow:
| Card number | Behaviour |
|---|---|
4000 0027 6000 3184 |
Always requires authentication; succeeds after challenge |
4000 0082 6000 3178 |
Always requires authentication; declines after challenge |
4000 0038 0000 0446 |
Authentication required only for off-session payments |
4000 0025 0000 3155 |
Frictionless 3DS — authenticated without a challenge UI |
Test these against your actual checkout — including the redirect-back flow if you're using Checkout Sessions or PaymentIntents with manual confirmation. A common bug: the challenge succeeds but your code doesn't poll for the final PaymentIntent status.
Fraud and Risk Test Cards
Stripe Radar runs against test transactions too. These let you exercise the risk paths:
| Card number | Risk outcome |
|---|---|
4000 0000 0000 0101 |
Charge will be blocked with card_declined and fraudulent reason |
4100 0000 0000 0019 |
Charge succeeds but Radar flags it as elevated risk |
4000 0000 0000 4954 |
Always blocked by Radar — card_declined with fraudulent |
If you display fraud warnings in your admin dashboard, this is how you populate them in test mode.
Regional and Special-Case Cards
| Card number | Behaviour |
|---|---|
4000 0000 0000 3220 |
Triggers the address-check pass for AVS |
4000 0000 0000 0010 |
Address line 1 fails AVS check |
4000 0000 0000 0028 |
ZIP code fails AVS check |
4000 0000 0000 0036 |
Address and ZIP both fail |
4000 0566 5566 5556 |
US debit card |
4000 0566 5566 5557 |
UK debit card |
4000 0826 0000 0000 |
India card requiring mandate for recurring payments |
If you're charging across borders, test with at least one card from each region you care about — currency conversion, regulatory flows (RBI mandate in India, SCA in EU), and decline rates all vary.
Testing the Full Lifecycle
Cheat sheets like this list the cards but skip the playbook. Here's the order I work through when integrating Stripe from scratch:
- Happy path —
4242 4242 4242 4242, confirm charge succeeds, webhook fires, your DB updates. - Generic decline —
4000 0000 0000 0002, confirm your error UI is friendly and the user can retry. - 3DS challenge —
4000 0027 6000 3184, confirm the challenge appears, succeeds, and your code polls for final status. - 3DS decline —
4000 0082 6000 3178, confirm a failed challenge doesn't leave the customer in a stuck state. - Insufficient funds —
4000 0000 0000 9995, confirm you offer a clear "try another card" path. - Stolen card —
4000 0000 0000 9987, confirm your UI doesn't leak the reason. - Webhook failure — disable your webhook endpoint, retry a charge, confirm Stripe's retry logic eventually delivers the event.
Run this checklist before going live and most production payment bugs disappear before they happen.
FAQ
Can I use these cards on Stripe's live API?
No. Test cards only work with test-mode API keys (sk_test_... and pk_test_...). On live mode, every test card returns card_declined. This is intentional — there's no overlap between test and live.
What expiry date and CVC should I use?
Any future date and any 3-digit CVC (4 digits for American Express). Stripe ignores both for test cards. Common conventions: 12/34 and 123.
How do I trigger a specific decline code that isn't in this cheat sheet?
For decline codes not covered by a dedicated test card, use 4000 0000 0000 0002 (generic decline) and pass the desired decline_code via Stripe's test helpers in the dashboard, or via the attempted parameter on test PaymentMethods.
Do these test cards work with Apple Pay and Google Pay?
In sandbox modes — yes. Apple Pay's test environment and Google Pay's test merchant configuration both accept Stripe test PANs. You'll need to add the card to a test wallet first.
Where can I get more test card numbers programmatically?
Use DevZone's Credit Card Test Numbers tool to generate Luhn-valid test PANs across all major brands. Stripe's official docs at stripe.com/docs/testing list every card by scenario, with the same numbers used in this cheat sheet.
Do test charges cost money?
No. Test mode is completely free. You can run unlimited charges, refunds, disputes, and webhook events without ever touching a real card or bank account. Switch to live mode only when you're ready to take real payments.