Inyo

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 (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) 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:

HeaderValue
AuthorizationBearer {accessToken}
Content-Typeapplication/json

Request Body

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

Root Object

FieldTypeRequiredDescription
externalPaymentIdstringYour unique identifier for this validation request (idempotency key)
ipAddressstringRequester's IPv4 or IPv6 address
senderobjectCardholder details

sender Object

FieldTypeRequiredDescription
firstNamestringCardholder's first name (compared against issuer records via Visa ANI for Visa cards)
lastNamestringCardholder's last name (compared against issuer records via Visa ANI for Visa cards)
emailstringCardholder's email address
addressobjectBilling address (used for AVS verification)
paymentMethodobjectTokenized card details

sender.address Object

FieldTypeRequiredDescription
countryCodestringISO Alpha-3 country code (e.g., "USA")
stateCodestringState/province abbreviation (e.g., "NY")
citystringCity name
line1stringStreet address line 1
line2stringStreet address line 2
zipCodestringPostal/ZIP code

sender.paymentMethod Object

FieldTypeRequiredDescription
typestring"CARD"
cardTokenIdstringToken UUID from the tokenizer

Example Request

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": "[email protected]",
      "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:

{
  "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:

{
  "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:

{
  "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 for the complete flow.

Response Fields

FieldTypeDescription
paymentIdstringInyo's unique identifier for this validation
statusstringAPPROVED, REJECTED, or CHALLENGE
redirectAcsUrlstring3DS challenge URL (only present when status = CHALLENGE)
avsResultstringAddress verification result (see below)
cvcResultstringCard verification code result (see below)
aavCardholderNameResultstringCardholder name verification result (see below)
reasonCodestringResponse code (see Response Codes)

Understanding the Verification Results

AVS Result (avsResult)

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

ValueMeaningAction
APPROVEDAddress matches issuer records✅ Low fraud risk
FAILEDAddress does not match⚠️ Elevated fraud risk
NOT_SENTNo billing address was providedℹ️ No verification performed
N/ANot 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.

ValueMeaningAction
APPROVEDCVC matches issuer records✅ Card in possession
FAILEDCVC does not match⚠️ High fraud risk
NOT_SENTCVC was not providedℹ️ No verification performed
N/ANot 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) service.

ValueMeaningAction
APPROVEDName matches issuer records✅ Confirmed cardholder identity
FAILEDName does not match⚠️ Possible identity mismatch — investigate
N/ANot 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.

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:

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: '[email protected]',
        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.

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 NumberNetworkDescription
4462 0300 0000 0000Visa DebitStandard ANI test card

Use the cardholder name AUTHORISED to simulate an approved result. See Test Data — Cards 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