// FREE TOOL · STRIPE TEST CARDS

Stripe test cards

The one you want is 4242 4242 4242 4242, with any three-digit CVC (four digits for American Express), any future expiry date such as 12/34, and anything you like in the remaining fields. It works only against your Stripe test API keys. The table below carries 55 test cards checked against Stripe's own testing reference on 4 September 2026 — search it, click a number to copy it, and download the whole set as JSON or CSV for your test suite. Every failure card also lists the error code, the decline code and the webhook event it produces, which is the part the official documentation keeps on three separate pages.

FreeNo signup55 cardsJSON + CSV download
stripe · test cards

Click any number to copy it without spaces. Nothing is sent anywhere — the table and the downloads are built on this page. The download follows the filter, so you can export just the decline cards.

NumberSimulatesBrandPaymentMethodCodes and event
Successful payment, by card brand · 15
Any 3 digits · Any future date Successful payment Visa pm_card_visa payment_intent.succeeded
Any 3 digits · Any future date Successful payment on a debit card Visa (debit) pm_card_visa_debit payment_intent.succeeded
Any 3 digits · Any future date Successful payment Mastercard pm_card_mastercard payment_intent.succeeded
Any 3 digits · Any future date Successful payment on a 2-series BIN Mastercard (2-series) payment_intent.succeeded
Any 3 digits · Any future date Successful payment on a debit card Mastercard (debit) pm_card_mastercard_debit payment_intent.succeeded
Any 3 digits · Any future date Successful payment on a prepaid card Mastercard (prepaid) pm_card_mastercard_prepaid payment_intent.succeeded
Any 4 digits · Any future date Successful payment (15 digits, 4-digit CVC) American Express pm_card_amex payment_intent.succeeded
Any 4 digits · Any future date Successful payment, second Amex BIN American Express payment_intent.succeeded
Any 3 digits · Any future date Successful payment Discover pm_card_discover payment_intent.succeeded
Any 3 digits · Any future date Successful payment on a 19-digit card number UnionPay (19-digit) payment_intent.succeeded
Any 3 digits · Any future date Successful payment Diners Club pm_card_diners payment_intent.succeeded
Any 3 digits · Any future date Successful payment on a 14-digit card number Diners Club (14-digit) payment_intent.succeeded
Any 3 digits · Any future date Successful payment JCB pm_card_jcb payment_intent.succeeded
Any 3 digits · Any future date Successful payment UnionPay pm_card_unionpay payment_intent.succeeded
Any 3 digits · Any future date Successful payment on a co-branded French card Cartes Bancaires / Visa pm_card_visa_cartesBancaires payment_intent.succeeded
Declines · 10
Any 3 digits · Any future date Generic decline Visa pm_card_visa_chargeDeclined card_declineddecline_code generic_declinepayment_intent.payment_failed
Any 3 digits · Any future date Insufficient funds decline Visa pm_card_visa_chargeDeclinedInsufficientFunds card_declineddecline_code insufficient_fundspayment_intent.payment_failed
Any 3 digits · Any future date Lost card decline Visa pm_card_visa_chargeDeclinedLostCard card_declineddecline_code lost_cardpayment_intent.payment_failed
Any 3 digits · Any future date Stolen card decline Visa pm_card_visa_chargeDeclinedStolenCard card_declineddecline_code stolen_cardpayment_intent.payment_failed
Any 3 digits · Any future date Expired card decline Visa pm_card_chargeDeclinedExpiredCard expired_cardpayment_intent.payment_failed
Any 3 digits · Any future date Incorrect CVC decline (send a CVC, or the check is skipped) Visa pm_card_chargeDeclinedIncorrectCvc incorrect_cvcpayment_intent.payment_failed
Any 3 digits · Any future date Processing error decline Visa pm_card_chargeDeclinedProcessingError processing_errorpayment_intent.payment_failed
Any 3 digits · Any future date Incorrect number — fails the Luhn check on purpose Visa incorrect_numberno event — rejected before the API
Any 3 digits · Any future date Exceeding velocity limit decline Visa pm_card_visa_chargeDeclinedVelocityLimitExceeded card_declineddecline_code card_velocity_exceededpayment_intent.payment_failed
Any 3 digits · Any future date Attaches to a Customer, then fails when charged Visa pm_card_chargeCustomerFail card_declinedpayment_intent.payment_failed
Radar, fraud and address checks · 9
Any 3 digits · Any future date Highest risk — Radar always blocks it Visa pm_card_radarBlock card_declineddecline_code generic_declinepayment_intent.payment_failed
Any 3 digits · Any future date Risk level "highest" — Radar may block it, depending on your rules Visa pm_card_riskLevelHighest card_declineddecline_code generic_declinepayment_intent.payment_failed
Any 3 digits · Any future date Risk level "elevated" — Radar may queue it for manual review Visa pm_card_riskLevelElevated review.opened
Any 3 digits · Any future date High fraud dispute score Visa pm_card_highFraudDisputeScore review.opened
Any 3 digits · Any future date High early fraud warning score Visa pm_card_highEfwScore review.opened
Any 3 digits · Any future date Free trial abuse — blocked when that control is on Visa pm_card_freeTrialAbuseBlock card_declineddecline_code generic_declinepayment_intent.payment_failed
Any 3 digits · Any future date CVC check fails (only if you send a CVC) Visa pm_card_cvcCheckFail card_declineddecline_code generic_declinepayment_intent.payment_failed
Any 3 digits · Any future date Postal code check fails (only if you send a postal code) Visa pm_card_avsZipFail card_declineddecline_code generic_declinepayment_intent.payment_failed
Any 3 digits · Any future date Both the postal code and line 1 address checks fail Visa pm_card_avsFail card_declineddecline_code generic_declinepayment_intent.payment_failed
Disputes and fraud warnings · 8
Any 3 digits · Any future date Charge succeeds, then is disputed as fraudulent Visa pm_card_createDispute charge.dispute.created
Any 3 digits · Any future date Charge succeeds, then is disputed as fraudulent on Discover Discover charge.dispute.created
Any 3 digits · Any future date Charge succeeds, then is disputed as product not received Visa pm_card_createDisputeProductNotReceived charge.dispute.created
Any 3 digits · Any future date Charge succeeds, then receives an inquiry rather than a chargeback Visa pm_card_createDisputeInquiry charge.dispute.created
Any 3 digits · Any future date Charge succeeds, then an early fraud warning arrives Visa pm_card_createIssuerFraudRecord radar.early_fraud_warning.created
Any 3 digits · Any future date Charge succeeds, then is disputed more than once Visa pm_card_createMultipleDisputes charge.dispute.created
Any 3 digits · Any future date Dispute eligible for Visa Compelling Evidence 3.0 Visa pm_card_createCe3EligibleDispute charge.dispute.created
Any 3 digits · Any future date Dispute eligible for Smart Disputes Visa pm_card_createAutoRepresentmentEligibleDispute charge.dispute.created
Refunds and balance timing · 4
Any 3 digits · Any future date Refund starts pending, then succeeds later Visa pm_card_pendingRefund refund.updated
Any 3 digits · Any future date Refund looks successful, then fails later Visa pm_card_refundFail refund.failed
Any 3 digits · Any future date Domestic charge lands straight in the available balance Visa pm_card_bypassPending payment_intent.succeeded
Any 3 digits · Any future date International charge lands straight in the available balance Visa pm_card_bypassPendingInternational payment_intent.succeeded
3D Secure · 9
Any 3 digits · Any future date 3DS required, and the challenge succeeds Visa (IE) pm_card_threeDSecure2Required payment_intent.requires_action
Any 3 digits · Any future date 3DS required on a US-issued card, challenge succeeds Visa (US) payment_intent.requires_action
Any 3 digits · Any future date 3DS succeeds, then the payment is declined anyway Visa pm_card_threeDSecureRequiredChargeDeclined card_declinedpayment_intent.payment_failed
Any 3 digits · Any future date 3DS lookup itself errors, and the payment is declined Visa pm_card_threeDSecureRequiredProcessingError card_declinedpayment_intent.payment_failed
Any 3 digits · Any future date 3DS supported but not required by default rules Visa pm_card_threeDSecureOptional payment_intent.succeeded
Any 3 digits · Any future date 3DS supported, but attempting it produces a processing error Visa pm_card_threeDSecureOptionalProcessingError card_declinedpayment_intent.payment_failed
Any 3 digits · Any future date Off-session payments need 3DS until the card is set up for future use Visa pm_card_authenticationRequiredOnSetup payment_intent.requires_action
Any 3 digits · Any future date 3DS required on every transaction, however the card is set up Visa pm_card_authenticationRequired payment_intent.requires_action
Any 3 digits · Any future date Already set up for off-session use; on-session payments still authenticate Visa pm_card_authenticationRequiredSetupForOffSession payment_intent.requires_action

How to use a Stripe test card

Three steps. Test cards are accepted only by test API keys, so nothing here can touch a real card or a real customer.

  1. Switch to test keys. Use your test publishable and secret keys, or a sandbox. Stripe's services agreement forbids putting real card details through a test flow, and it also forbids putting test numbers through a live one — they are simply declined.
  2. Pick the card for the outcome you want. Use 4242 4242 4242 4242 for a plain success. To exercise your error handling, pick the card whose row names the decline code you want to see, and give it any three-digit CVC and any future expiry date.
  3. In server code, use the PaymentMethod instead. Stripe recommends passing a token such as pm_card_visa rather than raw digits in API calls, so your test code never contains a card number. The PaymentMethod column carries the token for every card that has one.

Which card triggers which failure — and what your webhook will see

Handling a failed payment well means holding three things in your head at once: the error.code your API call throws, the decline_code the issuer attached to it, and the event that later lands on your webhook endpoint. Stripe documents those on three different pages, so most integrations are written against one of them and surprised by the other two. This is the same information as one row per outcome.

Test cardWhat it simulateserror.codedecline_codeWebhook event
4000 0000 0000 0002Generic declinecard_declinedgeneric_declinepayment_intent.payment_failed
4000 0000 0000 9995Insufficient fundscard_declinedinsufficient_fundspayment_intent.payment_failed
4000 0000 0000 9987Lost cardcard_declinedlost_cardpayment_intent.payment_failed
4000 0000 0000 9979Stolen cardcard_declinedstolen_cardpayment_intent.payment_failed
4000 0000 0000 6975Too many attempts on one cardcard_declinedcard_velocity_exceededpayment_intent.payment_failed
4000 0000 0000 0069Expired cardexpired_cardnonepayment_intent.payment_failed
4000 0000 0000 0127Wrong CVCincorrect_cvcnonepayment_intent.payment_failed
4000 0000 0000 0119Processing error at the networkprocessing_errornonepayment_intent.payment_failed
4242 4242 4242 4241Number that fails the Luhn checkincorrect_numbernonenone — rejected before a charge exists
4100 0000 0000 0019Radar blocks it, alwayscard_declinedgeneric_declinepayment_intent.payment_failed
4000 0000 0000 9235Elevated risk, queued for reviewnone — the charge is creatednonereview.opened
4000 0000 0000 0101CVC check fails at Radarcard_declinedgeneric_declinepayment_intent.payment_failed
4000 0000 0000 0036Postal code check fails at Radarcard_declinedgeneric_declinepayment_intent.payment_failed
4000 0000 0000 0259Charge succeeds, then a fraud disputenonenonecharge.dispute.created
4000 0000 0000 2685Charge succeeds, then "product not received"nonenonecharge.dispute.created
4000 0000 0000 5423Charge succeeds, then an early fraud warningnonenoneradar.early_fraud_warning.created
4000 0000 0000 7726Refund starts pending, later succeedsnonenonerefund.updated
4000 0000 0000 5126Refund looks fine, later failsnonenonerefund.failed
4000 0000 0000 32203D Secure challenge requirednonenonepayment_intent.requires_action
4000 0084 0000 1629Authenticates, then declines anywaycard_declinednonepayment_intent.payment_failed
4000 0084 0000 12803D Secure lookup itself errorscard_declinednonepayment_intent.payment_failed

Two habits fall out of reading it as one table. First, card_declined is not a reason, it is a category — the reason is in decline_code, and only three of the eight declines above even carry one. If your error handler switches on error.code alone, insufficient funds and a stolen card look identical to it, and you will show the wrong message to the customer whose card simply ran out of money.

Second, some outcomes never appear in the response at all. A charge queued for review, a dispute opened three weeks later, an asynchronous refund that flips from succeeded to failed — none of those are visible at the moment of the API call. They arrive as events, or they do not arrive at all because the endpoint was never built. That is the failure mode worth testing on purpose: block the card, then check what your system did with the event.

Two footnotes the table cannot hold. Stripe skips the CVC and postal code checks entirely if you do not send those fields, so the cards that simulate a failed check quietly succeed unless your form actually collects them. And for Radar-blocked payments, generic_decline is documented as the code that covers "Radar or Adaptive Acceptance blocked the payment" — which is deliberate: the customer must not be told that they were flagged as fraudulent.

Testing 3D Secure

3D Secure is the authentication step European regulation requires for most online card payments, and it is where a working integration most often falls over — because the happy path never sees it. A payment that needs authentication does not fail and does not succeed: it comes back with the PaymentIntent in requires_action, and your front end has to hand control to Stripe.js so the customer can complete the challenge.

Nine cards in the table exercise the branches, and the distinction that saves the most time is required versus supported:

  • 4000 0000 0000 3220 — authentication is required and succeeds. This is the card to build against. Use it, and you will discover whether your client actually calls the confirmation step or silently treats requires_action as a failure.
  • 4000 0000 0000 3055 — 3D Secure is supported but not requested by default. Useful for checking that you have not made authentication mandatory by accident.
  • 4000 0084 0000 1629 and 4000 0084 0000 1280 — the two ways the flow can end badly: the customer authenticates and the issuer declines anyway, and the lookup itself errors out. Both come back as card_declined, so an error handler that assumes a completed challenge means a completed payment will show a success screen for a payment that never happened.
  • 4000 0025 0000 3155 and 4000 0027 6000 3184 — the saved-card cases. The first needs authentication for off-session charges until the card is set up for future payments; the second always needs it. If you plan to charge people later without them present, these two are the difference between a working renewal and a dead one.

One thing that catches people out: only the cards in this group genuinely test 3D Secure. Other test cards may trigger it, but Stripe returns attempt_acknowledged and skips the extra steps, so your challenge UI never renders and you conclude, wrongly, that it works. Redirects also do not happen for payments created directly in the Stripe Dashboard — drive it from your own front end or from an API call.

Testing refunds, disputes and the things that arrive late

Refunds in live mode are not instant and are not guaranteed. A refund can report success and fail hours later, or sit at pending and resolve afterwards. Almost every test suite misses this, because with any ordinary test card refunds settle immediately and never change status again. Two cards restore the real behaviour: 4000 0000 0000 7726 starts the refund pending and later moves it to succeeded, and 4000 0000 0000 5126 reports succeeded and later fails. Both emit an event afterwards, which is exactly the code path you want to have written before a customer is on the phone about money they never got back.

Disputes work the same way in slow motion. The charge succeeds normally, then a chargeback appears days later, with charge.dispute.created as the only notification you will get. 4000 0000 0000 0259 raises a fraud dispute, 4000 0000 0000 2685 raises "product not received", and 4000 0000 0000 1976 raises an inquiry rather than a full chargeback — worth separating, because an inquiry can often be closed without escalation and a chargeback cannot. 4000 0000 0000 5423 produces an early fraud warning instead, which is the network telling you a dispute is probably coming while there is still time to refund voluntarily.

To simulate the outcome as well as the event, respond to the dispute with the literal evidence strings Stripe reserves for testing: winning_evidence closes it as won, losing_evidence closes it as lost, and escalate_inquiry_evidence turns an inquiry into a real chargeback. Pass whichever one as the uncategorized text field.

Last of the late-arriving group: 4000 0000 0000 0077 puts the funds straight into your available balance rather than the pending one. That is not a payments test, it is a bookkeeping test — useful if anything downstream reconciles payouts and you would rather not wait out a settlement window to find out whether it works.

Download the fixtures as JSON or CSV

A table you have to copy by hand is a table you will get wrong. The two download buttons at the top of the page give you the same 55 cards as machine-readable files, generated in the browser from the data this page is rendered from — so what you download cannot drift from what you just read.

The JSON is an object with source, checked, count and a cards array. Each card carries a stable id you can reference from a test name, the digits, the brand, the group, a one-line description, the CVC and expiry rules, and the three cross-reference fields: payment_method, error_code, decline_code and webhook_event. Fields that do not apply are null rather than absent, so a parser never has to guard for missing keys.

The CSV carries the same eleven columns with RFC 4180 quoting, which means it opens in a spreadsheet and loads in pandas without a converter argument. Handy for a seed script, or for the QA spreadsheet someone will inevitably ask you for.

Both downloads follow whatever filter is applied. Narrow the table to declines, press Download JSON, and you get ten rows rather than fifty-five — which is usually what a parameterised test wants:

test.each(fixtures.cards.filter(c => c.group === 'decline'))(
  '$id surfaces $decline_code',
  async ({ payment_method, error_code, decline_code }) => { /* … */ },
);

The files carry the source URL and the date they were checked, because a card list without a date is a card list you cannot trust in six months. If Stripe changes a number, the honest fix is to re-check the source rather than to keep a stale copy in your repository.

What you are actually building

Nobody looks up test cards for fun. You are here because you are wiring a checkout, and the checkout is one piece of a larger thing: a catalogue, a price the customer cannot edit, a session created somewhere with a secret, a webhook that decides whether the order counts as paid, and then everything that happens after the money arrives.

The piece that goes wrong most often is not the card. It is the price. A static site that keeps its prices in HTML and posts an amount to a checkout endpoint is trusting the browser with the number, and the browser is not trustworthy — that is a whole class of bug the test cards will never catch, because a tampered payment succeeds beautifully.

Clize builds on Stripe Checkout for exactly this reason and puts the price on the server side: a hosted store prices every basket against the _catalog.json deployed with the site and ignores whatever amount the client claims. If that is the shape of your problem, the catalogue file has a generator and a validator here, and if you only need one customer to pay one amount, clize pay link --amount 49 returns a live Stripe Checkout URL without a Stripe account of your own — that charge is real money, so keep it well away from the numbers on this page.

// FAQ

What is the Stripe test card number?

The standard one is 4242 4242 4242 4242, a Visa that always succeeds. Pair it with any three-digit CVC, any future expiry date such as 12/34, and any values in the remaining fields. It works only with your Stripe test API keys; against live keys it is declined.

What expiry date and CVC should I use with a Stripe test card?

Any date in the future works — 12/34 is the example Stripe itself uses. The CVC is any three digits, except on American Express cards, where it is any four. Stripe skips the CVC check entirely when you do not send one, which is why the card that simulates a failed CVC check appears to succeed if your form omits the field.

Why is my Stripe test card being declined?

Three usual causes. You are sending it to live API keys, which reject test numbers by design. You copied a card that is meant to decline — 4000 0000 0000 0002 and everything in the Declines group exist for that. Or you used a number that fails the Luhn check, such as 4242 4242 4242 4241, which returns incorrect_number before a charge is created.

Can I use a Stripe test card in live mode?

No. Test numbers are only accepted by test API keys, and real card details must never be used in a test environment — Stripe's services agreement prohibits it. Keep the two sets of keys apart in configuration, because the failure is silent in one direction and expensive in the other.

How do I test a 3D Secure payment in Stripe?

Use 4000 0000 0000 3220, which requires authentication and completes it successfully. The PaymentIntent comes back as requires_action, and your front end must hand off to Stripe.js so the customer can pass the challenge. Only the cards in the 3D Secure group genuinely test this flow; other cards may trigger it but Stripe returns attempt_acknowledged and skips the extra step.

Which Stripe test card creates a dispute or a chargeback?

Use 4000 0000 0000 0259 for a fraud dispute, 4000 0000 0000 2685 for "product not received", and 4000 0000 0000 1976 for an inquiry rather than a full chargeback. The charge succeeds first and the dispute arrives later as a charge.dispute.created event. Respond with the literal strings winning_evidence or losing_evidence to close it as won or lost.

Is anything I type into this page uploaded anywhere?

No. The table is plain HTML rendered with the page, and the search, the click-to-copy and both downloads are a small script running in your browser. There is no account, no signup and no network request, so the page works offline once it has loaded.

clize pay link — a live checkout URL in one command

When the test cards are done, take a real payment.

One command returns a live Stripe Checkout link with no Stripe account, no key and no onboarding form. Real money, so mind which set of numbers you are holding.

$ npm i -g @clize/clize && clize login
$ clize pay link --amount 49 --for "invoice 1042"
[ Agent Storefront → ]