What the Luhn algorithm is
Luhn (also called "mod 10") is a checksum that catches typos in card numbers. Hans Peter Luhn at IBM designed it in 1954. It's not cryptographic security — anyone can compute it. Its only purpose is detecting human-entry errors.
The algorithm: walk the digits right to left. Multiply the digits in even positions (counting from 1 on the right, so even = 2, 4, 6...) by 2. If the result exceeds 9, subtract 9 (or sum the digits). Sum all digits. If the total is a multiple of 10, the number is Luhn-valid.
Card number anatomy
- BIN/IIN: the first 6-8 digits identify the issuer (bank). That's why numbers start differently per brand.
- Account number: the middle digits. Identify the holder within the issuer.
- Luhn check digit: the last digit. Calculated so the total satisfies mod 10.
Brands have assigned ranges:
- Visa: starts with 4. Length: 13, 16 or 19.
- Mastercard: starts with 51-55 or 2221-2720. Length: 16.
- American Express: starts with 34 or 37. Length: 15.
- Discover: starts with 6011, 644-649 or 65. Length: 16.
- Diners Club: starts with 36, 38 or 300-305. Length: 14-19.
- JCB: starts with 35. Length: 16.
Official test cards by processor
If you want to test a full checkout, you don't want these numbers — you want what each processor publishes for sandbox mode. Those work only in test environments. Common ones:
- Stripe: 4242 4242 4242 4242 (Visa, success). 4000 0000 0000 0002 (declined). Docs: stripe.com/docs/testing.
- PayPal: the PayPal sandbox includes its own test card when you create a tester account.
- Square: 4111 1111 1111 1111 (Visa). 5105 1051 0510 5100 (Mastercard).
- Braintree: 4111 1111 1111 1111 (Visa). 5555 5555 5555 4444 (Mastercard).
- Adyen: 4111 1111 1111 1111 with CVV 737 and expiry 03/30.
What generic Luhn-valid numbers ARE good for
Real cases where you need a number that passes Luhn but never reaches the processor:
- Validator unit tests. If your code rejects Luhn-invalid cards, you need valid cases to confirm it accepts them.
- E2E tests with mocked processor. Your app's form requires Luhn-valid on the frontend, but the backend is stubbed.
- Form validation outside checkout. If you store cards in an internal app (e.g. a manual payment management system), you want to validate format without charging.
- Visual demos. Showing payment UIs with numbers that "look real" without using a real one.
What you must NEVER do
- Try them on real checkouts. It's attempted fraud, even if they don't work. Your IP gets logged.
- Share them as if they were real. Plainly deceptive.
- Use them as identity credentials. Some systems use cards for identity verification. A Luhn-valid number is not an identity.
- Store them unflagged. If you persist them, mark them clearly as synthetic.
PCI DSS and synthetic data
The PCI DSS standard (which governs cardholder data handling) acknowledges that synthetic data falls outside its scope: if the number doesn't correspond to a real account, it isn't a PAN ("Primary Account Number") in the standard's sense. That lets you use them in development environments without treating the database as a PCI system.
Even so, isolate the data: don't mix production with synthetic, don't log the numbers in accessible systems, don't email them.