Credit Card Validator
DevValidate card numbers with the Luhn checksum and detect the issuer brand (Visa, Mastercard, Amex, UnionPay, Discover). Runs entirely in your browser.
Remote URLs are not fetched; paste your JSON directly.
- Brand
- Luhn check
- Length
On this page
What is a card number validator?#
A payment card number (the PAN, or Primary Account Number) is not a random string. Its leading digits are a BIN prefix that identifies the issuer (Visa starts with 4, Mastercard with 51–55 or 2221–2720, and so on), its total length falls in a narrow band per brand, and its final digit is a check digit computed so the whole number satisfies the Luhn algorithm. A validator pulls those three signals apart and tells you, for any string of digits, whether it is well-formed — not whether it is a real, issued, payable card.
This page does exactly that, entirely in your browser. Type or paste a number and it identifies the brand from the BIN prefix, formats the digits into readable 4-groups, runs the Luhn checksum, and checks the length against what that brand actually uses. It is the tool you reach for when building a checkout form (does my field-level validation match real BIN rules?), when learning how Luhn works, or when sanity-checking a test fixture.
Never enter a real card number. Use test PANs (the ones payment gateways publish for sandbox use) or numbers you generated yourself for learning. Everything here runs locally and nothing is transmitted, but treating any PAN as sensitive is the right habit.
How to use it#
- Read the privacy note above the input — it confirms the number never leaves your browser.
- Type or paste a number into the Card number field. Spaces, dashes, dots, and letters are stripped automatically; you can paste
4111-1111 1111.1111and it will be read as4111111111111111. - Click Sample to load a well-known Visa test PAN, or Clear to reset.
- Read the result card:
- The verdict line says whether the number is well-formed.
- The brand badge shows the detected issuer (Visa, Mastercard, American Express, Discover, UnionPay) or “unknown” when no BIN prefix matches.
- Grouped shows the digits formatted in runs of 4, ready to copy.
- The three check rows report brand, Luhn (pass / fail), and length (ok / out of range) separately, so you can see which rule failed rather than just a flat “invalid”.
Key features#
- Luhn checksum, implemented from scratch. The same algorithm cards have carried since the 1960s: walking the digits right-to-left, doubling every second one, summing, and checking divisibility by ten. The check digit at the end is what makes a typo of a single digit always fail.
- BIN prefix detection for five brands. Visa, Mastercard, American Express, Discover, and UnionPay, matched in priority order so the
6-prefixed brands (Discover 6011/65 vs UnionPay 62) do not collide. - Per-brand length checking. Amex is 15 digits; Visa is 13 or 16; Discover and UnionPay can be 16 through 19. The length rule applied is the one for the brand detected, falling back to the general 12–19 range when the prefix is unknown.
- Locale-safe digit normalization. Arabic-Indic (٤١١١), Persian, Devanagari, Bengali, and fullwidth (123) digit glyphs are all transliterated to ASCII 0–9 before validation, so the same PAN validates regardless of the user’s input method or locale.
- 4-digit grouping for display. A 16-digit PAN becomes
4111 1111 1111 1111; a 15-digit Amex becomes the familiar3782 8224 6310 005(4-4-4-3). - Strictly local. There is no backend and no network request. The PAN is processed in memory and rendered into the result card on the same keystroke.
Worked example#
Click Sample to load the canonical Visa test PAN, or type 4111 1111 1111 1111. The result card reads:
verdict Valid
brand Visa
grouped 4111 1111 1111 1111
Luhn pass
length ok (16 digits)
Now try an American Express test PAN with awkward spacing — paste 3782 822463 10005. The tool strips the spaces, detects Amex from the 37 prefix, and reformats it into Amex’s own grouping:
verdict Valid
brand American Express
grouped 3782 8224 6310 005
Luhn pass
length ok (15 digits)
Finally, change one digit of the Visa number to 4111 1111 1111 1112. The brand and length are still fine, but Luhn now fails — and the tool tells you so explicitly, instead of hiding which check broke:
verdict Invalid
brand Visa
grouped 4111 1111 1111 1112
Luhn fail
length ok (16 digits)
That separation matters when you are debugging a form: a failing Luhn points at a typo, while a failing length points at the wrong brand or a truncated paste.
FAQ#
Does “valid” mean the card will actually work?#
No. “Valid” only means the number is well-formed — its prefix maps to a known brand, its length matches that brand, and it satisfies Luhn. It says nothing about whether the card was ever issued, is active, or has funds. Treat this as a format check, the same way you would validate an email’s shape without knowing the inbox exists.
Why does Luhn catch every single-digit typo?#
Because of how the checksum doubles alternating digits: changing one digit shifts the sum by an amount that is never a multiple of ten, and swapping two adjacent digits changes the sum in a way Luhn also detects (with one narrow exception). It was designed precisely to catch the typing mistakes humans make at a keypad.
The number I pasted has non-Latin digits. Will it still work?#
Yes. The validator transliterates Arabic-Indic, Persian, Devanagari, Bengali, and fullwidth digit glyphs to ASCII before doing anything else, so ٤١١١ is treated as 4111. This keeps validation consistent across locales and input methods, and the displayed “grouped” form always uses ASCII digits.
Which card brands are recognized?#
Visa, Mastercard, American Express, Discover, and UnionPay, by their public BIN prefix ranges. Numbers with a prefix that matches none of these (for example, starting with 1 or 9) report “unknown” brand, but if the length is in the general 12–19 range and Luhn passes, the number is still reported as well-formed — it simply is not one of the five modelled brands.