splitforms.com

Free tool - runs in your browser

Credit card regex tester

Test card number patterns for Visa, Mastercard (including the 2221-2720 2-series), American Express, Discover, JCB, Diners Club and UnionPay. Paste numbers one per line with or without spaces and dashes. Each line shows match or no match, the detected brand and a Luhn checksum result. Copy JavaScript, Python or an HTML pattern when you are ready.

Visa, Mastercard (51-55 and 2221-2720), Amex, Discover (6011, 65), Diners and JCB. UnionPay (62) is not included. Strip spaces and dashes first: value.replace(/[\s-]/g, '').

6 of 7 match

  • MatchLuhn: valid4111 1111 1111 1111Visa
  • MatchLuhn: valid5555-5555-5555-4444Mastercard
  • MatchLuhn: valid2223003122003222Mastercard
  • MatchLuhn: valid378282246310005American Express
  • MatchLuhn: valid6011111111111117Discover
  • MatchLuhn: invalid4111111111111112Visa
  • No matchLuhn: invalid1234 5678 9012 3456Unknown brand

Everything runs in your browser and nothing is sent. Use test numbers only: never store or send real card numbers through your own forms. Take payments with a payment provider's hosted card field (Stripe Elements, PayPal, Square) so card data never touches your server.

Card number patterns by brand

Each pattern checks the issuer prefix and the digit count on a number with spaces and dashes removed (value.replace(/[\s-]/g, '')). Default pattern: ^(?:4\d{12}(?:\d{3})?|(?:5[1-5]\d{2}|222[1-9]|22[3-9]\d|2[3-6]\d{2}|27[01]\d|2720)\d{12}|3[47]\d{13}|6(?:011|5\d{2})\d{12}|3(?:0[0-5]|[68]\d)\d{11}|(?:2131|1800|35\d{3})\d{11})$. Every preset below is checked against its match and no-match samples, and every match sample passes the Luhn check.

PresetRegexMatch / no match examplesNotes
Any major card^(?:4\d{12}(?:\d{3})?|(?:5[1-5]\d{2}|222[1-9]|22[3-9]\d|2[3-6]\d{2}|27[01]\d|2720)\d{12}|3[47]\d{13}|6(?:011|5\d{2})\d{12}|3(?:0[0-5]|[68]\d)\d{11}|(?:2131|1800|35\d{3})\d{11})$Match: 4111111111111111, 5555555555554444, 2223003122003222, 378282246310005, 6011111111111117, 3530111333300000, 30569309025904
No match: 1234567890123456, 411111111111, 2721000000000000, 6200000000000005; empty string
Visa, Mastercard (51-55 and 2221-2720), Amex, Discover (6011, 65), Diners and JCB. UnionPay (62) is not included. Strip spaces and dashes first: value.replace(/[\s-]/g, '').
Visa^4\d{12}(?:\d{3})?$Match: 4111111111111111, 4012888888881881, 4222222222222
No match: 5555555555554444, 41111111111111, 411111111111111111; empty string
Starts with 4; 13 or 16 digits. Some newer Visa cards use 19 digits: add (?:\d{3})? again if you accept them. Strip spaces and dashes first: value.replace(/[\s-]/g, '').
Mastercard (51-55 and 2-series)^(?:5[1-5]\d{2}|222[1-9]|22[3-9]\d|2[3-6]\d{2}|27[01]\d|2720)\d{12}$Match: 5555555555554444, 5105105105105100, 2223003122003222, 2720990000000007
No match: 5011111111111111, 2220999999999999, 2721000000000000, 555555555555444; empty string
16 digits. First four digits 5100-5599 or 2221-2720 (the 2-series range added in 2017). Strip spaces and dashes first: value.replace(/[\s-]/g, '').
American Express^3[47]\d{13}$Match: 378282246310005, 371449635398431, 340000000000009
No match: 3782822463100055, 37828224631000, 358282246310005; empty string
Starts with 34 or 37 and has exactly 15 digits (usually grouped 4-6-5). Strip spaces and dashes first: value.replace(/[\s-]/g, '').
Discover^6(?:011|5\d{2})\d{12}$Match: 6011111111111117, 6011000990139424, 6500000000000002
No match: 6012111111111117, 601111111111111, 6411111111111111; empty string
16 digits starting with 6011 or 65. Discover also issues 644-649 and some 622 ranges; widen the prefix if you need them. Strip spaces and dashes first: value.replace(/[\s-]/g, '').
JCB^(?:2131|1800|35\d{3})\d{11}$Match: 3530111333300000, 3566002020360505, 213100000000001, 180000000000002
No match: 353011133330000, 3430111333300000, 2132000000000000; empty string
16 digits starting with 35, or the older 15-digit 2131 and 1800 prefixes. Strip spaces and dashes first: value.replace(/[\s-]/g, '').
Diners Club^3(?:0[0-5]|[68]\d)\d{11}$Match: 30569309025904, 38520000023237, 36000000000008
No match: 30669309025904, 3056930902590, 305693090259041; empty string
14 digits starting with 300-305, 36 or 38. Newer Diners cards starting 54/55 run on the Mastercard network and match that preset. Strip spaces and dashes first: value.replace(/[\s-]/g, '').
UnionPay^62\d{14,17}$Match: 6200000000000005, 6212345678901265, 6212345678901234569
No match: 621234567890126, 62123456789012345678, 6312345678901265; empty string
Starts with 62 and has 16 to 19 digits. Some UnionPay cards do not pass the Luhn check, so do not reject them on Luhn alone. Strip spaces and dashes first: value.replace(/[\s-]/g, '').

Regex plus the Luhn checksum

card-check.js

function luhn(digits) {
  let sum = 0;
  let double = false;
  for (let i = digits.length - 1; i >= 0; i--) {
    let d = Number(digits[i]);
    if (double) { d *= 2; if (d > 9) d -= 9; }
    sum += d;
    double = !double;
  }
  return sum % 10 === 0;
}

const CARD_RE = /^(?:4\d{12}(?:\d{3})?|(?:5[1-5]\d{2}|222[1-9]|22[3-9]\d|2[3-6]\d{2}|27[01]\d|2720)\d{12}|3[47]\d{13}|6(?:011|5\d{2})\d{12}|3(?:0[0-5]|[68]\d)\d{11}|(?:2131|1800|35\d{3})\d{11})$/;
const digits = value.replace(/[\s-]/g, "");
const ok = CARD_RE.test(digits) && luhn(digits);

Strip separators, test the brand pattern, then run the Luhn check: from the right, double every second digit, subtract 9 from any result over 9, and add everything up. A valid number gives a total divisible by 10. 4111 1111 1111 1111 passes; 4111 1111 1111 1112 matches the Visa regex but fails Luhn. On a text input, the pattern attribute can enforce the digit format, and inputmode="numeric" with autocomplete="cc-number" gives a number keypad and autofill.

Do not collect card numbers in your own forms

Never store or send real card numbers through a contact form, email or database. That puts you in PCI DSS scope. Use a payment provider's hosted field or checkout so card data goes straight to the provider. Use these patterns for test data, for masking numbers that people paste into the wrong field, or for checks inside a provider's own form. For other form fields, try the phone regex tester.

Credit card regex FAQ

Why is a credit card regex not enough on its own?

A regex only checks the prefix and the number of digits. 4111111111111112 has a Visa prefix and 16 digits, so it matches, but it is not a real card number. The last digit of a card number is a Luhn (mod 10) check digit that catches most typos, such as one wrong digit or two swapped neighbours. Run the Luhn check after the regex. Neither check tells you whether the card exists or has funds; only the payment provider can confirm that.

Does the regex match Mastercard 2-series numbers?

Yes. Since 2017 Mastercard issues 16-digit cards whose first four digits are 2221 to 2720, as well as the older 51 to 55 range. The Mastercard preset matches both: (?:5[1-5]\d{2}|222[1-9]|22[3-9]\d|2[3-6]\d{2}|27[01]\d|2720)\d{12}. Old patterns that only check ^5[1-5] reject valid cards such as 2223003122003222.

How many digits does an American Express card have?

American Express cards have 15 digits and start with 34 or 37, so the pattern is ^3[47]\d{13}$. They are usually printed in 4-6-5 groups, such as 3782 822463 10005, and use a 4-digit security code on the front. Visa, Mastercard and Discover use 16 digits, and Diners Club uses 14.

Should a contact form accept credit card numbers?

No. Do not collect card numbers in a contact form, an email or any form that stores entries. Storing, sending or even logging card data brings your systems into PCI DSS scope. Take payments with a payment provider's hosted field or checkout page, such as Stripe Elements or PayPal, so the card number goes straight to the provider and never reaches your server. Use this tester with test numbers only.

More free form tools

Form backend cost calculator

Enter monthly submissions and compare the cheapest listed plan across eight form backends.

Email deliverability checker

Enter a domain to check its SPF, DMARC and MX records and get a plain-English fix for each.

SPF record checker

Look up a domain's SPF record, see each mechanism explained and count DNS lookups against the 10-lookup limit.

DMARC record generator

Pick a policy and report address and copy a ready _dmarc TXT record.

DMARC checker

Look up a domain's DMARC record and see the policy and every tag explained.

DKIM record checker

Enter a domain and selector to check its DKIM key, with presets for common senders.

SPF record generator

Tick your email providers and copy one SPF TXT record with a lookup count.

Contact form spam checker

Paste form HTML to audit its honeypot, endpoint, CAPTCHA markers and spam resistance.

Honeypot field generator

Generate a hidden anti-spam input with your chosen name and hiding technique.

Form action URL tester

Check a form action URL for reachability, CORS headers, POST acceptance and backend.

Email obfuscator

Encode your email so spam scrapers can't read it but people can still click it.

Mailto link generator

Build a mailto: URL with recipients, CC, BCC, subject and a pre-filled body.

HMAC-SHA256 generator

Generate and verify webhook signatures for common providers in your browser.

URL encoder and decoder

Encode text, build an x-www-form-urlencoded body or parse a query string.

UTM builder

Build campaign URLs with UTM parameters, tag a CSV in bulk and check tagged links.

HTML to JSX converter

Paste HTML and get JSX or a working React/Next.js form component.

Image to Base64 converter

Convert images to Base64 data URLs in your browser and copy HTML and CSS snippets.

Base64 to image converter

Paste a Base64 data URI to preview and download the decoded image.

Base64 decode & encode

Decode Base64 to readable UTF-8 text or encode text to Base64, locally in your browser.

URL to Base64 converter

Fetch a direct image URL in your browser and get its Base64 data URL.

AI form generator

Describe your form in plain English and copy working HTML.

See all free tools