---
description: >-
  Validate a card without charging it using the Check Card Account API. Returns AVS and CVC results for all cards, plus Visa ANI cardholder name verification for Visa cards.
---

# Check Card Account (ANI)

The Check Card Account API validates a card without processing a payment. It performs up to three verification checks and returns the results:

- **AVS** — Address Verification Service (billing address match) — all card networks
- **CVC** — Card Verification Code (security code match) — all card networks
- **AAV Cardholder Name** — Visa [Account Name Inquiry](https://corporate.visa.com/content/dam/VCOM/regional/na/us/support-legal/documents/account-name-inquiry-onesheet-merchant-version.pdf) (cardholder name match against issuer records) — **Visa cards only**

AVS and CVC verification are standard checks performed for any card. The cardholder name check is powered by Visa's **Account Name Inquiry (ANI)** product, which queries the issuing bank's records to verify that the name submitted matches the legal name on the account. ANI is only available for Visa cards — for non-Visa cards, the `aavCardholderNameResult` field will return `N/A`.

## What is Visa ANI?

[Account Name Inquiry (ANI)](https://corporate.visa.com/content/dam/VCOM/regional/na/us/support-legal/documents/account-name-inquiry-onesheet-merchant-version.pdf) is a Visa product that enables merchants to verify the cardholder's name directly with the issuing bank before or independently of a financial transaction. When a card is submitted, Visa forwards the provided first, middle, and last name to the issuer, who compares them against the legal name on the account and returns a match result.

Key details about Visa ANI:

- **Visa only** — ANI is a Visa network service. It is not available for Mastercard, Amex, Discover, or other networks.
- **Issuer participation** — ANI became mandatory for U.S. and Canadian Visa issuers in October 2023, meaning most Visa issuers in these markets support it. Some issuers outside these markets may not yet support ANI, in which case the result will be `N/A`.
- **Name matching** — Visa checks first, middle, and last name components separately against the issuer's records. At minimum, the last name must be provided. The issuer returns the closest match when multiple names are on file (e.g., joint accounts).
- **Independent of payment** — ANI operates independently of the financial transaction. No funds are held or moved.
- **Exclusions** — Business/corporate cards and non-reloadable prepaid cards without a registered name are not supported for ANI.

## Use Cases

- **Onboarding** — Validate a customer's card before storing it for future charges
- **Fraud prevention** — Confirm the person submitting the card is the actual cardholder
- **KYC enhancement** — Cross-reference the name on the card with the name provided during identity verification
- **Card-on-file verification** — Check that a stored card is still valid and belongs to the expected person

## How It Works

```
1. Tokenize card          2. POST /check-card-account          3. Read results
   (client-side)             (server-side)
       │                          │                             For all cards:
       ▼                          ▼                               → AVS result
   inyo.js encrypts       Gateway verifies AVS + CVC             → CVC result
   card + name →          for all cards. If Visa,
   returns cardTokenId    also queries ANI for                  For Visa cards only:
                          cardholder name match →                 → ANI name result
```

> **Note:** This API does **not** charge the card or create a payment. It is purely a validation call. No amount is required in the request.

---

## Endpoint

```
POST https://sandbox-gw.simpleps.com/check-card-account
```

**Headers:**

| Header | Value |
|---|---|
| `Authorization` | `Bearer {accessToken}` |
| `Content-Type` | `application/json` |

## Request Body

The payload is simplified compared to standard payment requests — no `amount`, `paymentType`, or `capture` fields are needed.

### Root Object

| Field | Type | Required | Description |
|---|---|---|---|
| `externalPaymentId` | string | ✅ | Your unique identifier for this validation request (idempotency key) |
| `ipAddress` | string | ✅ | Requester's IPv4 or IPv6 address |
| `sender` | object | ✅ | Cardholder details |

### `sender` Object

| Field | Type | Required | Description |
|---|---|---|---|
| `firstName` | string | ✅ | Cardholder's first name (compared against issuer records via Visa ANI for Visa cards) |
| `lastName` | string | ✅ | Cardholder's last name (compared against issuer records via Visa ANI for Visa cards) |
| `email` | string | ❌ | Cardholder's email address |
| `address` | object | ❌ | Billing address (used for AVS verification) |
| `paymentMethod` | object | ✅ | Tokenized card details |

### `sender.address` Object

| Field | Type | Required | Description |
|---|---|---|---|
| `countryCode` | string | ✅ | ISO Alpha-3 country code (e.g., `"USA"`) |
| `stateCode` | string | ✅ | State/province abbreviation (e.g., `"NY"`) |
| `city` | string | ✅ | City name |
| `line1` | string | ✅ | Street address line 1 |
| `line2` | string | ❌ | Street address line 2 |
| `zipCode` | string | ✅ | Postal/ZIP code |

### `sender.paymentMethod` Object

| Field | Type | Required | Description |
|---|---|---|---|
| `type` | string | ✅ | `"CARD"` |
| `cardTokenId` | string | ✅ | Token UUID from the [tokenizer](tokenizing-cards.md) |

## Example Request

```bash
curl -X POST https://sandbox-gw.simpleps.com/check-card-account \
  -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...' \
  -H 'Content-Type: application/json' \
  -d '{
    "externalPaymentId": "card-check-001",
    "ipAddress": "203.0.113.42",
    "sender": {
      "firstName": "John",
      "lastName": "Smith",
      "email": "john.smith@example.com",
      "address": {
        "countryCode": "US",
        "stateCode": "NY",
        "city": "New York",
        "line1": "123 Main Street",
        "zipCode": "10001"
      },
      "paymentMethod": {
        "type": "CARD",
        "cardTokenId": "ab5fc589-8b48-4531-94c0-68b0629c13fe"
      }
    }
  }'
```

## Response

### Approved (200)

All three verification checks passed:

```json
{
  "paymentId": "dce568c6-98ec-456c-bb33-4a6809c4fff8",
  "status": "APPROVED",
  "avsResult": "APPROVED",
  "cvcResult": "APPROVED",
  "aavCardholderNameResult": "APPROVED",
  "reasonCode": "00"
}
```

### Rejected (200)

One or more checks failed — the card or identity could not be verified:

```json
{
  "paymentId": "dce568c6-98ec-456c-bb33-4a6809c4fff8",
  "status": "REJECTED",
  "avsResult": "APPROVED",
  "cvcResult": "APPROVED",
  "aavCardholderNameResult": "FAILED",
  "reasonCode": "PAY_084"
}
```

### 3DS Challenge (200)

The issuing bank requires cardholder authentication before returning results:

```json
{
  "paymentId": "dce568c6-98ec-456c-bb33-4a6809c4fff8",
  "status": "CHALLENGE",
  "redirectAcsUrl": "https://sandbox-gw.simpleps.com/secure-code/start-challenge?token=dce568c6-...",
  "avsResult": "N/A",
  "cvcResult": "N/A",
  "aavCardholderNameResult": "N/A"
}
```

When you receive `CHALLENGE`, redirect the cardholder to `redirectAcsUrl`. See [Handling 3D Secure](payment/pulling-funds/cards/authorizing/handling-3d-secure.md) for the complete flow.

## Response Fields

| Field | Type | Description |
|---|---|---|
| `paymentId` | string | Inyo's unique identifier for this validation |
| `status` | string | `APPROVED`, `REJECTED`, or `CHALLENGE` |
| `redirectAcsUrl` | string | 3DS challenge URL (only present when `status` = `CHALLENGE`) |
| `avsResult` | string | Address verification result (see below) |
| `cvcResult` | string | Card verification code result (see below) |
| `aavCardholderNameResult` | string | Cardholder name verification result (see below) |
| `reasonCode` | string | Response code (see [Response Codes](domain-tables/response-code.md)) |

## Understanding the Verification Results

### AVS Result (`avsResult`)

Compares the billing address provided in the request with the address on file at the card issuer.

| Value | Meaning | Action |
|---|---|---|
| `APPROVED` | Address matches issuer records | ✅ Low fraud risk |
| `FAILED` | Address does not match | ⚠️ Elevated fraud risk |
| `NOT_SENT` | No billing address was provided | ℹ️ No verification performed |
| `N/A` | Not applicable (e.g., 3DS challenge pending) | ℹ️ Check after challenge completes |

### CVC Result (`cvcResult`)

Validates the 3 or 4-digit security code printed on the card.

| Value | Meaning | Action |
|---|---|---|
| `APPROVED` | CVC matches issuer records | ✅ Card in possession |
| `FAILED` | CVC does not match | ⚠️ High fraud risk |
| `NOT_SENT` | CVC was not provided | ℹ️ No verification performed |
| `N/A` | Not applicable | ℹ️ Check after challenge completes |

### AAV Cardholder Name Result (`aavCardholderNameResult`)

**Visa cards only.** Verifies whether the `firstName` and `lastName` in the request match the legal name registered with the issuing bank. This is powered by Visa's [Account Name Inquiry (ANI)](https://corporate.visa.com/content/dam/VCOM/regional/na/us/support-legal/documents/account-name-inquiry-onesheet-merchant-version.pdf) service.

| Value | Meaning | Action |
|---|---|---|
| `APPROVED` | Name matches issuer records | ✅ Confirmed cardholder identity |
| `FAILED` | Name does not match | ⚠️ Possible identity mismatch — investigate |
| `N/A` | Not available — card is not Visa, issuer does not support ANI, or 3DS pending | ℹ️ Fall back to AVS and CVC results |

> **Important:** ANI is only performed for **Visa cards**. For Mastercard, Amex, Discover, and other networks, `aavCardholderNameResult` will always return `N/A`. In these cases, rely on AVS and CVC for verification.

> **Name formatting:** The cardholder name comparison is performed by the Visa issuer, which checks first, middle, and last name components separately. Ensure you pass the name **exactly as it appears on the card**. Visa supports up to 35 characters per name field. Suffixes (Jr., III) and prefixes (Dr.) are not supported by ANI and should be omitted.

## Integration Example

### Step 1 — Tokenize the Card

Use `inyo.js` to collect and tokenize the card data client-side. The cardholder name entered in the `data-field="cardholder"` input is included in the token.

```javascript
const tokenizer = new InyoTokenizer({
  targetId: '#payment-form',
  publicKey: 'YOUR_PUBLIC_KEY',
  storeLaterUse: false,
  threeDSData: { enable: true, enablePostMessage: true },
  successCallback: (response) => {
    if (response.reasonCode === 'WAITING_TRANSACTION') {
      checkCardAccount(response.additionalData.token);
    }
  },
  errorCallback: (err) => console.error('Tokenization failed:', err)
});
```

### Step 2 — Call Check Card Account

Send the token to your backend, which calls the Check Card Account API:

```javascript
async function checkCardAccount(cardTokenId) {
  const response = await fetch('https://sandbox-gw.simpleps.com/check-card-account', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      externalPaymentId: crypto.randomUUID(),
      ipAddress: customerIpAddress,
      sender: {
        firstName: 'John',
        lastName: 'Smith',
        email: 'john.smith@example.com',
        paymentMethod: {
          type: 'CARD',
          cardTokenId: cardTokenId
        }
      }
    })
  });

  const result = await response.json();

  if (result.status === 'CHALLENGE' && result.redirectAcsUrl) {
    // Handle 3DS — redirect or open iframe
    window.open(result.redirectAcsUrl, '_blank');
    return;
  }

  // Evaluate all three verification signals
  console.log('AVS:', result.avsResult);
  console.log('CVC:', result.cvcResult);
  console.log('ANI (Name):', result.aavCardholderNameResult);
}
```

### Step 3 — Evaluate Results

Combine all signals to make a decision. Remember that `aavCardholderNameResult` is only meaningful for Visa cards — for other networks it will be `N/A`.

```javascript
function evaluateCardCheck(result) {
  if (result.status === 'REJECTED') {
    return { accept: false, reason: 'Card validation rejected' };
  }

  // CVC mismatch — card not in possession
  if (result.cvcResult === 'FAILED') {
    return { accept: false, reason: 'Invalid security code' };
  }

  // Visa ANI: name mismatch — high risk
  // (N/A means non-Visa card or issuer doesn't support ANI — not a failure)
  if (result.aavCardholderNameResult === 'FAILED') {
    return { accept: false, reason: 'Cardholder name does not match issuer records (Visa ANI)' };
  }

  // All available checks passed
  if (result.avsResult === 'APPROVED' && result.cvcResult === 'APPROVED') {
    const aniStatus = result.aavCardholderNameResult === 'N/A'
      ? 'not available (non-Visa or unsupported issuer)'
      : 'name verified';
    return { accept: true, reason: `AVS + CVC passed; ANI: ${aniStatus}` };
  }

  // Partial results — use your own risk logic
  return { accept: true, reason: 'Partial verification — review recommended' };
}
```

## Testing

Use the following test card in sandbox for Check Card Account:

| Card Number | Network | Description |
|---|---|---|
| `4462 0300 0000 0000` | Visa Debit | Standard ANI test card |

Use the cardholder name `AUTHORISED` to simulate an approved result. See [Test Data — Cards](test-data/cards.md) for CVV and AVS simulation values.

## Best Practices

1. **Always send the billing address** — Including the address enables AVS verification alongside CVC (and ANI for Visa), giving you multiple independent fraud signals regardless of card network.

2. **Match the tokenizer name to the API name** — The `cardholder` field in the tokenizer form should contain the same name you pass as `sender.firstName` and `sender.lastName`. For Visa ANI, name mismatches between the tokenized name and the API name will cause the issuer to return a no-match result.

3. **Don't rely on a single signal** — Evaluate AVS + CVC together for all cards, and add the ANI result for Visa. A single `FAILED` result doesn't necessarily mean fraud, but multiple failures are a strong indicator.

4. **Handle `N/A` gracefully** — The `aavCardholderNameResult` field will return `N/A` for all non-Visa cards, and for Visa cards from issuers that don't yet support ANI. This is expected behavior — fall back to AVS and CVC results for your fraud decision.

5. **Use before storing cards** — Run a Check Card Account call before saving a card token with `storeLaterUse: true` to confirm the card is valid and belongs to the expected person.

6. **Use the legal name on the card** — Visa ANI compares against the legal name the issuer has on file, not nicknames or preferred names. Omit suffixes (Jr., III) and prefixes (Dr.) as they are not supported by Visa ANI.

## What's Next

- [Tokenizing Cards](tokenizing-cards.md) — Set up client-side card tokenization
- [Handling AVS / CVC](payment/pulling-funds/cards/authorizing/handling-avs-cvc.md) — Deep dive into address and security code verification
- [Handling 3D Secure](payment/pulling-funds/cards/authorizing/handling-3d-secure.md) — Handle CHALLENGE responses
- [Authorizing a Card Payment](payment/pulling-funds/cards/authorizing/) — Create actual payment transactions after validation
