Stripe test cards for every decline scenario | RecoverFlow

Guide

Stripe test cards for every failed payment scenario

Last updated 28 July 2026 · written by Bruce McGinley, who builds RecoverFlow

Short answer

Stripe publishes a test card for each decline reason. 4000000000000002 gives a generic decline, 4000000000009995 gives insufficient_funds, 4000000000009987 gives lost_card and 4000000000009979 gives stolen_card.

The most useful one is 4000000000000341, which attaches to a customer successfully and only fails when you try to charge it. That is the one that exercises your recovery code rather than your signup form.

The decline cards

Card numberScenarioWhat you get back
4000000000000002Generic declineerror code card_declined, decline code generic_decline
4000000000009995Insufficient fundserror code card_declined, decline code insufficient_funds
4000000000009987Lost carderror code card_declined, decline code lost_card
4000000000009979Stolen carderror code card_declined, decline code stolen_card
4000000000000069Expired carderror code expired_card
4000000000000127Incorrect CVCerror code incorrect_cvc
4000000000000119Processing errorerror code processing_error
4242424242424241Incorrect numbererror code incorrect_number
4000000000000341Attaches fine, fails on chargeerror code card_declined

Note that the last four in that list return an error code without a separate decline code. expired_card, incorrect_cvc, processing_error and incorrect_number are the error code. If your handler only reads decline_code and ignores code, it will see nothing for these and fall through to a generic branch.

Why 4000000000000341 is the one you want

Most test cards fail immediately at the point of entry, which tests your checkout form. Card 4000000000000341 succeeds when attached to a Customer object and fails when you attempt to charge it.

That is the shape of a real recovery scenario. The customer signed up months ago, the card worked then, and it is failing now on a renewal with nobody watching. If you want to test a dunning sequence, a retry schedule, or a webhook handler end to end, this is the card that gets you there.

A test worth running: attach 4000000000000341, create a subscription, let the renewal fail, and confirm your system sends exactly one email and not four. Duplicate dunning emails from overlapping webhook handlers are the most common bug in this area and they are invisible until a real customer complains.

Testing authentication and 3D Secure

Authentication has its own set of cards, because the interesting cases are about whether a payment can complete without the customer being present.

Card numberBehaviour
4000002500003155Requires authentication for off-session payments unless the card was previously set up. On-session payments always require authentication.
4000002760003184Requires authentication on every transaction, whatever the setup status.
4000003800000446Already set up for off-session use. One-time and on-session payments need authentication; off-session payments succeed.
40000000000032203D Secure must be completed. Issued in Ireland.
40000084000000273D Secure must be completed. Issued in the US.
40000000322000003D Secure required on all transactions, goes through the frictionless flow and succeeds.

The first and third of those are the pair that matters for subscriptions. Between them they show you the difference between a card that will quietly renew for years and one that will demand the customer's attention every cycle. More on that in the authentication_required guide.

Testing the codes that block retries

Three of the nine codes that stop Stripe executing retries have test cards: lost_card, stolen_card and incorrect_number. That is enough to verify the behaviour that surprises people, which is that the retry schedule keeps running and attempt_count keeps rising while nothing is actually being charged.

Run 4000000000009979 through a subscription renewal and watch the invoice. If your internal reporting claims eight retry attempts on that invoice, your reporting is describing a schedule, not a set of charges. That distinction is worth catching in test mode rather than in a board meeting.

What test mode will not tell you

Test cards return a fixed, documented result every time. Real cards do not. A real do_not_honor might approve on Thursday for reasons nobody outside the issuing bank will ever explain, and no amount of test mode work will teach you how often that happens for your customers.

So use test mode to prove your logic is correct: right branch for the right code, one email not four, access revoked at the right status. Do not use it to estimate recovery rates. Those come from your own production data and from nowhere else, which is also why this site does not publish a recovery rate benchmark for you to borrow.

Questions people actually ask

What is the Stripe test card for a declined payment?

4000000000000002 gives a generic decline with error code card_declined and decline code generic_decline. For a specific reason use a specific card: 4000000000009995 for insufficient funds, 4000000000009987 for a lost card, 4000000000009979 for a stolen card.

Which Stripe test card fails only when charged?

4000000000000341. It succeeds when attached to a Customer object and fails when you attempt the charge. This is the right card for testing renewal failures, dunning sequences and webhook handlers, because it reproduces the situation where a card worked at signup and broke later.

What is the Stripe test card for an expired card?

4000000000000069. It returns the error code expired_card. Note that this comes back as an error code rather than a decline_code, so handlers that only inspect decline_code will miss it.

How do I test 3D Secure in Stripe?

4000002760003184 requires authentication on every transaction. 4000002500003155 requires it for off-session payments unless the card was previously set up, which is the more realistic subscription case. 4000000032200000 requires 3D Secure but passes through the frictionless flow and succeeds.

Can I test Smart Retries with test cards?

You can exercise the retry and webhook behaviour, including watching attempt_count increment on codes that block execution. What you cannot learn is real recovery rates, because test cards return a deterministic result and real issuers do not.

Where this came from

Checked against primary sources on 28 July 2026. If Stripe changes something and this page has not caught up, tell us and it gets fixed.

If you would rather not build this yourself

RecoverFlow watches your Stripe account for failed subscription payments, stops retrying the ones that cannot succeed, and emails the customers whose card simply needs replacing. It charges 25% of what it actually recovers, with a $29 monthly floor, and nothing at all if it recovers nothing.

It is early. It is run by one person. If Stripe's own free retry settings are enough for you, use those instead, and there is a page on this site that says exactly when that is the right call.

See how the pricing works