Every payment integration needs card numbers to test with, and the first instinct — a real card, maybe your own — is the wrong one. A real card in a test environment is a compliance problem, a fraud-monitoring problem, and still not very good test data, because one card exercises one brand, one length and one outcome.
There are two kinds of number that do the job properly, and they are not interchangeable.
Sandbox cards are published by your payment processor. They only work in test mode, and each one triggers a specific outcome: success, a particular decline, a 3-D Secure challenge.
Generated numbers are built to pass the checks a form can run offline — brand prefix, length and the Luhn checksum — but belong to no account. They never reach a processor successfully, and that is the point: they test everything up to the processor.
Stripe test cards
Stripe's test numbers work with any future expiry date, any CVC (three digits, four for Amex) and any postal code, in test mode only.
| Scenario | Number |
|---|---|
| Visa — succeeds | 4242 4242 4242 4242 |
| Visa debit — succeeds | 4000 0566 5566 5556 |
| Mastercard — succeeds | 5555 5555 5555 4444 |
| Mastercard 2-series — succeeds | 2223 0031 2200 3222 |
| American Express — succeeds | 3782 822463 10005 |
| Discover — succeeds | 6011 1111 1111 1117 |
| Generic decline | 4000 0000 0000 0002 |
| Insufficient funds | 4000 0000 0000 9995 |
| Expired card | 4000 0000 0000 0069 |
| Incorrect CVC | 4000 0000 0000 0127 |
| Requires 3-D Secure authentication | 4000 0025 0000 3155 |
The 3-D Secure card is the one most teams forget. Strong Customer Authentication is mandatory for most card payments in the European Economic Area and the UK, and a checkout that has never seen an authentication challenge will eventually break on a real one.
Other processors
Braintree accepts the classic test numbers — 4111 1111 1111 1111 (Visa), 5555 5555 5555 4444 (Mastercard), 3782 822463 10005 (Amex), 6011 1111 1111 1117 (Discover) — and simulates processor declines through the transaction amount rather than the card number: amounts in a documented range return the decline code matching the amount.
Adyen publishes test cards per brand and region. Its convention is an expiry of 03/2030 and a CVC of 737 for most of them; other values can produce different results.
PayPal sandbox payments use sandbox buyer accounts created in the developer dashboard, which also generates card numbers for those accounts.
In every case, the processor's own documentation is the source of truth. Numbers and trigger conventions do change, and a decline card that silently starts succeeding will make a test pass for the wrong reason.
When generated numbers are the better choice
Sandbox cards are few, and they all look alike: most are Visa, most are sixteen digits, most start with 4. That is fine for testing a processor integration and poor for testing the form in front of it. Generated numbers give you variety on demand. Use them for:
- Front-end validation — brand detection, length checks, Luhn validation and formatting as the user types.
- Fixtures for storage, masking, receipts and admin screens, where you need hundreds of distinct cards and no processor call.
- Database and analytics tests — checking that a full number never lands in a log, an event or an export.
- Load tests of everything except the payment call itself.
The credit card generator produces Luhn-valid numbers for Visa, Mastercard (both the 51–55 and 2221–2720 ranges), American Express, Discover, JCB and Diners Club, with CVCs of the right length and expiry dates you can push into the past.
Brand prefixes and lengths
| Brand | Prefix (IIN range) | Length | Security code |
|---|---|---|---|
| Visa | 4 | 16 (also 13 and 19) | 3 |
| Mastercard | 51–55, 2221–2720 | 16 | 3 |
| American Express | 34, 37 | 15 | 4 |
| Discover | 6011, 644–649, 65 | 16–19 | 3 |
| JCB | 3528–3589 | 16–19 | 3 |
| Diners Club | 300–305, 36, 38 | 14–19 | 3 |
Brand detection that relies on a hard-coded list is the most common source of real-world payment bugs. Mastercard began issuing 2-series cards in 2017, and forms that only recognise ^5[1-5] still reject them.
A checklist for testing a payment form
- Every brand you accept, including a 15-digit Amex and a 14-digit Diners number if you take them.
- A brand you do not accept, to check the error message.
- Mastercard 2-series, to check brand detection.
- A four-digit CVC for Amex — and a three-digit one for everything else.
- Paste with spaces and dashes. The field should strip them; the cursor should not jump.
- A card expiring this month. It is still valid until the month ends, and "expiry must be in the future" logic often rejects it.
- An expired card, rejected before submission.
- One Luhn failure — change the last digit — rejected client-side, without a network call.
- Browser autofill, with
autocomplete="cc-number",cc-expandcc-cscon the fields. - The sandbox outcomes: success, generic decline, insufficient funds and 3-D Secure, each producing a clear message.
- Logging. Search your logs, analytics events and error reports for the full test number. It should appear nowhere.
Why real cards do not belong in tests
PCI DSS v4.0 requirement 6.5.5 states that live card numbers are not used in pre-production environments unless those environments are included in the cardholder data environment and protected accordingly. In practice, one real card number in a staging database brings staging into PCI scope. Real cards also trip fraud monitoring when they are charged and refunded repeatedly.
There is no test that needs a real card. Use sandbox cards for anything that touches the processor, generated numbers for everything else, and keep the boundary between them clear. For why generated identifiers must carry valid checksums at all, read Check digits that test data must satisfy.