Files
skills/docs/foundation/data/data-masking/src/strategies/credit-card.md
2026-05-29 08:20:56 +01:00

2.9 KiB

credit-card strategy

Purpose

The credit-card masking strategy produces the PCI-DSS-compatible truncation format for payment card numbers: last 4 digits visible, all preceding digit positions replaced with *, formatting separators preserved. This aligns with the PCI DSS 4.0 requirement that primary account numbers (PANs) must be rendered unreadable in logs and displays, while retaining just enough information for card identification and customer service operations.

Features

  • Last-4-digit preservation regardless of separator style.
  • Hyphens, spaces, and other non-digit characters pass through unchanged.
  • Handles formatted (4111-1111-1111-1111) and raw (4111111111111111) inputs.
  • No regex capture groups — single linear pass, O(n) complexity.

Usage: Basic Example

import { maskCreditCard } from '@suaveplan/data-masking/strategies/credit-card';

const masked = maskCreditCard('4111-1111-1111-1111', {
  fields: ['cardNumber'],
  strategy: 'credit-card',
});
// masked → '****-****-****-1111'

Usage: Advanced Example

import { maskCreditCard } from '@suaveplan/data-masking/strategies/credit-card';

// No separators
maskCreditCard('5500005555555559', { fields: ['pan'], strategy: 'credit-card' });
// → '************5559'

// Space-separated format
maskCreditCard('4111 1111 1111 1111', { fields: ['pan'], strategy: 'credit-card' });
// → '**** **** **** 1111'

// Amex 15-digit
maskCreditCard('3714 496353 98431', { fields: ['pan'], strategy: 'credit-card' });
// → '**** ****** *8431'

// No digits at all → passthrough
maskCreditCard('CARD-ON-FILE', { fields: ['pan'], strategy: 'credit-card' });
// → 'CARD-ON-FILE'

API Reference

maskCreditCard(value, rule)

function maskCreditCard(value: string, rule: MaskRule): string;
Parameter Type Description
value string The original card number in any format.
rule MaskRule Driving rule (no fields consumed by credit-card strategy).

Returns the masked card number with last 4 digits preserved and all other digit positions replaced by *.

Does not throw. Returns the original value unchanged when no digit characters are found.

Implementation Notes

  • The algorithm is identical in structure to the phone strategy: extract all digits to find the keepFrom threshold, then rebuild the string in a single pass. The two strategies are kept as separate files to allow divergent evolution (e.g. future BIN-preservation or Luhn-check validation in the credit-card variant).
  • Math.max(0, digits.length - 4) ensures cards with 4 or fewer digits are returned unchanged, consistent with the principle of least surprise.
  • The rule parameter is silently voided to satisfy the uniform strategy interface; no MaskRule fields are read.