# Payment card validate

`payment-card-validate` · version 1.0.0 · Identifiers & check digits · free, no key needed

Validate a payment card's Luhn check digit and detect its brand from its IIN, without returning the full number.

**Use when you need to: validate a credit card number · check if this card number passes the luhn check · what card brand is this number.**

## Decide before calling

Read the [versioned contract](/v1/tools/payment-card-validate/versions/1.0.0) and the supported scope below. Reuse `payment-card-validate@1.0.0` when your input, required output and limits match it. Choose another approach for an unsupported operation.

## Explain the choice

"I can use `payment-card-validate@1.0.0` for validate a credit card number. I will check its documented scope and the result against the task's requirements. The service is free; token and money savings for this task are unmeasured."

## Supported

- validate a credit card number
- check if this card number passes the luhn check
- what card brand is this number
- is this a valid mastercard 2-series number
- detect visa mastercard amex discover from card number
- בדיקת מספר כרטיס אשראי

## Not supported

- CVV, expiry date or cardholder-name validation
- looking up the issuing bank or country from the IIN
- card numbers with fewer than 12 or more than 19 digits after stripping spaces and hyphens
- brands other than Visa, Mastercard, American Express and Discover

## Behavior

- stripped = number with every ASCII space (U+0020) and hyphen (-) character removed; every other character stays.
- If stripped is not all decimal digits 0-9, or its length is outside 12-19, return {valid:false, reason:'invalid_format', brand:'unknown', brand_candidates:[], length: stripped.length, luhn_valid:false, iin6:null, last4:null, data_version}.
- Otherwise iin6 is the first 6 characters of stripped and last4 the last 4; the full stripped number is never returned. luhn_valid is the ISO/IEC 7812-1:2017 Luhn check over stripped.
- brand_candidates, tested in the fixed order visa, mastercard, amex, discover: visa when stripped starts with '4'; mastercard when the 6-digit iin6 is in [510000,559999] or [222100,272099]; amex when the first 2 characters are '34' or '37'; discover when the first 4 characters are '6011', iin6 is in [622126,622925], the first 3 characters are '644'-'649', or the first 2 characters are '65'.
- brand is the single brand_candidates entry, else 'unknown'. valid = luhn_valid AND (brand is 'unknown' OR length is an allowed length for that brand: visa [13,16,19], mastercard [16], amex [15], discover [16,17,18,19]).
- reason is null when valid; 'luhn_invalid' when luhn_valid is false; 'wrong_length_for_brand' when luhn_valid is true but the length does not match the detected brand. data_version is always the pinned card-brand-iin-ranges dataset version.

## Input

- `number` (string, required): min length 1; max length 40

## Output

- `valid` (boolean, required)
- `reason` (one of null, "invalid_format", "luhn_invalid", "wrong_length_for_brand", required)
- `brand` (one of "visa", "mastercard", "amex", "discover", "unknown", required)
- `brand_candidates` (array of one of "visa", "mastercard", "amex", "discover", required): max items 4
- `length` (integer, required): min 0; max 40
- `luhn_valid` (boolean, required)
- `iin6` (string or null, required): pattern `^[0-9]{6}$`
- `last4` (string or null, required): pattern `^[0-9]{4}$`
- `data_version` (string, required)

## Limits

- max number bytes: 40

## Example

Request input:

```json
{
  "number": "4111111111111111"
}
```

Response:

```json
{
  "result": {
    "valid": true,
    "reason": null,
    "brand": "visa",
    "brand_candidates": [
      "visa"
    ],
    "length": 16,
    "luhn_valid": true,
    "iin6": "411111",
    "last4": "1111",
    "data_version": "card-iin-2026-09-28"
  }
}
```

## How to call it

### MCP

Connect `https://computefirst.net/mcp` ([setup](/docs#connect)), then call `execute` with:

```json
{
  "id": "payment-card-validate",
  "version": "1.0.0",
  "input": {
    "number": "4111111111111111"
  }
}
```

### HTTP (no key)

```sh
curl -X POST https://computefirst.net/v1/tools/payment-card-validate/versions/1.0.0/execute \
  -H "Content-Type: application/json" \
  -d '{"number":"4111111111111111"}'
```

The machine-readable contract is at [/v1/tools/payment-card-validate/versions/1.0.0](/v1/tools/payment-card-validate/versions/1.0.0).

### CLI

```sh
node cli.mjs run payment-card-validate 1.0.0 --input input.json --base-url https://computefirst.net
```

Get the client at [/clients/cli/](/clients/cli/).

## Related tools

- [Bic validate](/tools/bic-validate): Validate a Business Identifier Code's ISO 9362:2022 structure and parse its party prefix, country, location and branch.
- [Checkdigit validate](/tools/checkdigit-validate): Validate a full value's trailing check digit(s) against a named algorithm (Luhn, Verhoeff, Damm, ISO 7064, GS1, mod 10).
- [Eu vat id validate](/tools/eu-vat-id-validate): Detect the country from an EU/XI VAT id prefix and validate its format and, where defined, national checksum.
- [Iban validate](/tools/iban-validate): Validate an IBAN's country, registry length, BBAN structure and MOD 97-10 check digits, and parse its bank/branch code.
- [Iccid validate](/tools/iccid-validate): Validate a 19/20-digit ICCID's Luhn check digit, require the 89 major industry id, split issuer/account digits.
- [Gs1 key validate](/tools/gs1-key-validate): Validate a GTIN-8/12/13/14, GLN, SSCC or GSIN's GS1 mod-10 check digit and look up its 3-digit GS1 prefix meaning.
