What the algorithm does
Luhn is a mod-10 check digit scheme published by Hans Peter Luhn at IBM in 1954 and long out of patent. Working right to left, you double every second digit; if doubling takes it past nine you subtract nine. Add everything up and the total has to be a multiple of ten. The final digit of the number is chosen at issue time to make that come out even.
The scheme catches every single-digit error and every transposition of adjacent digits except 09 ↔ 90. That is the entire design brief. It was built for a world of card imprinters and phone-in authorisations, where the expensive failure was a clerk reading a digit wrong, and it is still doing that job in payment forms, IMEI numbers, some national provider IDs and a scattering of loyalty schemes.
Why a pass means so little
The check digit adds no entropy. Given fifteen arbitrary digits there is always exactly one sixteenth digit that makes the sum come out right, so about one in ten random sixteen-digit strings passes Luhn. The set of Luhn-valid sixteen-digit numbers has on the order of 1015 members. Almost all of them correspond to nothing.
This matters because "validates the card number" gets written in tickets and then believed. What a client-side Luhn check buys you is a faster error message for the user who fat-fingered a digit — worth having, and that is the whole return. Whether a card can be charged is settled by the issuer during authorisation, against the expiry date, the CVV, the address check, the available balance and whatever fraud scoring the network applies. None of that is visible from the digits.
Leading digits, and what they are worth
The first six to eight digits are the Issuer Identification Number, formerly the BIN, and the top-level ranges are public: Visa starts with 4, Mastercard occupies 51-55 plus the 2221-2720 block opened in 2017, Amex is 34 and 37, Discover is 6011 and 644-649 and 65. Matching those tells you which brand mark to show next to the field and roughly how many digits to expect.
It does not identify the issuing bank, the card product, or whether the range is currently allocated. Commercial IIN databases exist for that and they are commercial because the data changes and has to be maintained. Ranges also move: the 2-series Mastercard block did not exist before 2017, and code that hardcoded "Mastercard means 51-55" started rejecting real cards. If you find yourself building brand detection, get the range table from your payment provider rather than a blog post, and expect to update it.
Getting test numbers
This page checks numbers; it does not generate them, and that is deliberate. Every payment provider publishes its own test card numbers, and they are not interchangeable — Stripe, Adyen, Braintree, Square and PayPal each have sandbox numbers that trigger specific outcomes on their side, including the ones you actually need to test, like a decline, an expired card, an insufficient-funds response and a 3-D Secure challenge. A number you invented that happens to satisfy Luhn will fail in the sandbox for reasons that teach you nothing. Go to your provider's testing page, take the list from there, and put those in your fixtures.
Questions people ask
Can I check whether my own card is valid?
You can check that you typed it without a slip, and nothing more. Whether a card works is a question only the issuer answers, during an authorisation, using the expiry date and CVV and the account state — none of which a checksum can see. That said, do not paste a live card number here. This page runs entirely in your browser, but the habit of typing card details into whatever form asks for them is exactly the habit that phishing depends on.
Does a passing checksum mean the card number was issued?
No. About one in ten random strings of the right length passes Luhn, because the check digit is fully determined by the other digits rather than adding information. A pass means "consistent", not "real". The number 4539148803436467 in the default field passes cleanly and belongs to nobody.
Will this generate test card numbers for me?
No, on purpose. Use the sandbox numbers published by whichever payment provider you are integrating — Stripe, Adyen, Braintree, Square and the rest each publish their own, and only theirs will trigger the decline, expiry and 3-D Secure paths you need to exercise. An invented Luhn-valid number does not do that.
What else uses Luhn?
IMEI numbers on phones, some national provider identifiers such as the US NPI, various loyalty and gift card schemes, and a long tail of internal account numbering. If you ever need to add a check digit to your own identifiers, Luhn is a reasonable choice for exactly the reason it is a poor security measure: it is simple, it catches the typos people actually make, and it makes no claim beyond that.