Take it with you
Copy the check
The whole Luhn check fits in about fifteen lines. Each version below does the same thing: strip spaces and dashes, require 12 to 19 digits, then double, fold and add.
export function passesLuhn(input: string): boolean {
const digits = input.replace(/[\s-]/g, "");
if (!/^\d{12,19}$/.test(digits)) return false;
let sum = 0;
for (let i = 0; i < digits.length; i++) {
let d = Number(digits[digits.length - 1 - i]);
if (i % 2 === 1) {
d *= 2;
if (d > 9) d -= 9;
}
sum += d;
}
return sum % 10 === 0;
}Before you ship it
- Run the same check on your server. Anything a browser does can be skipped by someone who is not using your page.
- Do not log card numbers, even failed ones. If you can, avoid handling them at all and use your payment provider's hosted fields.
- Do not reject a number only because its brand is unknown to you. New ranges appear, so let the payment provider decide.
- Accept spaces and dashes when people paste a number, and format it for them as they type.