Skip to main content

cardnum

$cardnum

Validates a payment card number (PAN) using the Luhn algorithm and normalizes its formatting based on the detected card network.

Processing steps:

  1. Strip formatting characters (spaces, dashes, dots)
  2. Validate: digits only, length 12–19 (ISO 7812), Luhn checksum
  3. Detect card network from IIN (Issuer Identification Number) prefix
  4. Format with network-appropriate digit grouping

Recognized networks and their grouping:

  • Amex (34, 37): #### ###### #####
  • Diners Club (300–305, 36, 38): #### ###### ####
  • JCB (3528–3589): #### #### #### ####
  • Discover (6011, 65, 644–649, 622126–622925): #### #### #### ####
  • Mastercard (51–55, 2221–2720): #### #### #### ####
  • Visa (4): #### #### #### ####
  • Unrecognized: #### #### #### #### (default grouping)

Network detection is best-effort and does not affect validation — any number that passes the Luhn check with a valid length is accepted. Unrecognized prefixes receive default 4-4-4-4 grouping.

Parameters

  • mask (boolean or string, default false): When truthy, replaces leading digits with a mask character, revealing only the trailing digits. true uses '•'; a string value uses its first character.
  • reveal (number, default 4): Number of trailing digits to leave visible when mask is enabled.

Example

// Validate and format
new Schema('string').validator('$cardnum')
// '4111111111111111' → '4111 1111 1111 1111'
// '378282246310005' → '3782 822463 10005'

// Masked for output (serializer — masking is a lossy presentation transform)
new Schema('string').serializer({'$cardnum': {mask: true}})
// '4111111111111111' → '•••• •••• •••• 1111'

// Custom mask character, reveal 6 digits
new Schema('string').serializer({'$cardnum': {mask: '*', reveal: 6}})
// '4111111111111111' → '**** **** **11 1111'