Inyo

Check Card Account (ANI)

A API Check Card Account valida um cartão sem processar um pagamento. Ela executa até três verificações, além do perfil de capacidades do cartão, e retorna os resultados:

  • AVS — Address Verification Service (correspondência do endereço de cobrança) — todas as bandeiras
  • CVC — Card Verification Code (correspondência do código de segurança) — todas as bandeiras
  • AAV Cardholder NameAccount Name Inquiry da Visa (correspondência do nome do portador com os registros do emissor) — somente cartões Visa

As verificações de AVS e CVC são checagens padrão realizadas para qualquer cartão. A verificação do nome do portador é fornecida pelo produto Account Name Inquiry (ANI) da Visa, que consulta os registros do banco emissor para verificar se o nome enviado corresponde ao nome legal na conta. O ANI só está disponível para cartões Visa — em qualquer outra bandeira verificationResults.aavCardholderName não traz veredito.

A resposta também informa a capacidade OCT (push/payout) e AFT (funding/pull) do cartão, para que você possa decidir a elegibilidade de um cartão para um determinado fluxo antes de iniciar uma transação.

O que é o Visa ANI?

O Account Name Inquiry (ANI) é um produto da Visa que permite que estabelecimentos verifiquem o nome do portador diretamente com o banco emissor antes ou independentemente de uma transação financeira. Quando um cartão é enviado, a Visa encaminha o primeiro nome, o nome do meio e o sobrenome fornecidos ao emissor, que os compara com o nome legal na conta e retorna um resultado de correspondência.

Detalhes importantes sobre o Visa ANI:

  • Somente Visa — o ANI é um serviço da rede Visa. Não está disponível para Mastercard, Amex, Discover ou outras redes.
  • Participação dos emissores — o ANI tornou-se obrigatório para emissores Visa dos EUA e do Canadá em outubro de 2023, o que significa que a maioria dos emissores Visa nesses mercados o suporta. Alguns emissores fora desses mercados podem ainda não suportar o ANI; nesse caso, o resultado não traz veredito — NOT_CHECKED ou NOT_SUPPORTED.
  • Correspondência de nomes — a Visa verifica separadamente o primeiro nome, o nome do meio e o sobrenome contra os registros do emissor. No mínimo, o sobrenome deve ser fornecido. O emissor retorna a correspondência mais próxima quando há vários nomes registrados (ex.: contas conjuntas).
  • Independente do pagamento — o ANI opera independentemente da transação financeira. Nenhum valor é retido ou movimentado.
  • Exclusões — cartões corporativos/empresariais e cartões pré-pagos não recarregáveis sem nome registrado não são suportados pelo ANI.

Casos de Uso

  • Onboarding — Valide o cartão de um cliente antes de armazená-lo para cobranças futuras
  • Prevenção de fraude — Confirme que a pessoa que enviou o cartão é o portador real
  • Reforço de KYC — Cruze o nome no cartão com o nome fornecido durante a verificação de identidade
  • Elegibilidade para payout — Verifique octStatus antes de enviar fundos para um cartão; verifique aftStatus antes de captar (somente cartões Visa)
  • Verificação de cartão em arquivo — Confirme que um cartão armazenado ainda é válido e pertence à pessoa esperada

Como Funciona

sequenceDiagram
    participant B as Navegador<br/>inyo.js
    participant S as Seu servidor
    participant G as Inyo
    participant I as Emissor

    B->>G: Dados do cartão +<br/>nome do portador
    G-->>B: cardTokenId
    B->>S: cardTokenId
    S->>G: POST<br/>/v2/check-card-account
    G->>I: Autorização de valor zero:<br/>AVS + CVC
    opt Cartão Visa
        G->>I: Consulta de nome<br/>ANI
    end
    I-->>G: Resultados
    G-->>S: verificationResults +<br/>octStatus / aftStatus

Nota: Esta API não cobra o cartão — ela roda como uma autorização de valor zero, então nenhum recurso é retido ou movimentado. Nenhum amount é exigido na requisição.


Endpoint

POST https://{FQDN}/v2/check-card-account

Cabeçalhos:

CabeçalhoValor
AuthorizationBearer {accessToken}
Content-Typeapplication/json

Corpo da Requisição

O payload é simplificado em comparação com requisições de pagamento padrão — não são necessários os campos amount, paymentType ou capture. Internamente o gateway executa a verificação como uma autorização CHECK de valor zero, então a requisição é validada contra o schema do endpoint e contra o schema compartilhado de pagamentos com cartão. As tabelas abaixo refletem o resultado combinado.

Objeto Raiz

CampoTipoObrigatórioDescrição
externalPaymentIdstringSimSeu identificador único para esta requisição de validação
ipAddressstringSimEndereço IP do solicitante — precisa ser um literal IPv4 ou IPv6 válido
senderobjectSimDados do portador (veja abaixo)

Objeto sender

CampoTipoObrigatórioDescrição
firstNamestringSimPrimeiro nome do portador, no mínimo 1 caractere (comparado com os registros do emissor via Visa ANI para cartões Visa)
lastNamestringSimSobrenome do portador, no mínimo 1 caractere (comparado com os registros do emissor via Visa ANI para cartões Visa)
addressobjectSimEndereço de cobrança — é o que o AVS compara (veja abaixo)
paymentMethodobjectSimDados do cartão tokenizado (veja abaixo)
emailstringNãoE-mail do portador — armazenado junto ao registro da verificação
phoneNumberstringNãoTelefone do portador — armazenado junto ao registro da verificação

Objeto sender.address

CampoTipoObrigatórioDescrição
countryCodestringSimCódigo de país ISO Alpha-3 (ex.: "USA" — não "US")
stateCodestringSimAbreviação do estado/província (ex.: "MA")
citystringSimNome da cidade
line1stringSimLinha 1 do endereço
zipCodestringSimCódigo postal/ZIP
statestringNãoEstado/província como fica no registro de endereço armazenado — envie o mesmo valor de stateCode
line2stringNãoLinha 2 do endereço — envie "" quando não houver segunda linha

Objeto sender.paymentMethod

CampoTipoObrigatórioDescrição
typestringSim"CARD"
cardTokenIdstringSimUUID do token gerado pelo tokenizador — precisa ser um UUID bem formado

Exemplo de Requisição

curl -X POST https://{FQDN}/v2/check-card-account \
  -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...' \
  -H 'Content-Type: application/json' \
  -d '{
    "externalPaymentId": "ANI-0001",
    "ipAddress": "203.0.113.42",
    "sender": {
      "firstName": "John",
      "lastName": "Smith",
      "email": "[email protected]",
      "address": {
        "countryCode": "USA",
        "stateCode": "NY",
        "state": "NY",
        "city": "New York",
        "line1": "123 Main Street",
        "line2": "",
        "zipCode": "10001"
      },
      "paymentMethod": {
        "type": "CARD",
        "cardTokenId": "ab5fc589-8b48-4531-94c0-68b0629c13fe"
      }
    }
  }'

Resposta

Três desfechos compartilham o HTTP 200 e não compartilham a forma do corpo. Ramifique pelos campos presentes, nunca só pelo código de status.

Verificado (200)

A autorização de valor zero foi aprovada. card, verificationResults, octStatus, aftStatus e redirectAcsUrl estão sempre presentes:

{
  "card": {
    "created": "2026-05-16 16:37:40",
    "issuerName": "MODULR FS, LTD.",
    "issuerCountry": "UNITED KINGDOM",
    "bin": "446203",
    "lastFour": "0000"
  },
  "verificationResults": {
    "avs": "APPROVED",
    "cvc": "APPROVED",
    "aavCardholderName": "APPROVED"
  },
  "octStatus": {
    "capable": false,
    "highPerforming": false,
    "lowPerforming": false
  },
  "aftStatus": {
    "capable": true,
    "highPerforming": true,
    "lowPerforming": false
  },
  "redirectAcsUrl": ""
}

Chamadas repetidas são respondidas com o resultado armazenado. Depois que o ANI foi executado para um dado firstName + lastName + token do cartão, uma chamada idêntica devolve o resultado registrado em vez de consultar o emissor novamente. Alterar qualquer um dos nomes gera uma nova consulta ao emissor.

Desafio 3DS (200)

O banco emissor exige autenticação do portador antes de os resultados serem conhecidos. O corpo mantém a forma verificada, redirectAcsUrl vem preenchido e todas as verificações retornam NOT_SUPPORTED até o desafio ser concluído:

{
  "card": {
    "created": "2026-05-16 16:37:40",
    "issuerName": "MODULR FS, LTD.",
    "issuerCountry": "UNITED KINGDOM",
    "bin": "446203",
    "lastFour": "0000"
  },
  "verificationResults": {
    "avs": "NOT_SUPPORTED",
    "cvc": "NOT_SUPPORTED",
    "aavCardholderName": "NOT_SUPPORTED"
  },
  "octStatus": {
    "capable": false,
    "highPerforming": false,
    "lowPerforming": false
  },
  "aftStatus": {
    "capable": false,
    "highPerforming": false,
    "lowPerforming": false
  },
  "redirectAcsUrl": "https://{FQDN}/secure-code/start-challenge?token=dce568c6-..."
}

Quando redirectAcsUrl não está vazio, redirecione o portador para essa URL — e não leia as verificações deste corpo, elas ainda não trazem veredito. Veja Tratando o 3D Secure para o fluxo completo.

Recusado (200)

Quando a autorização de valor zero subjacente não é aprovada, o endpoint responde com a forma de resposta de pagamento. Não há objeto verificationResults, e os resultados das verificações chegam como campos planos:

{
  "paymentId": "870bf24b-885f-4b1f-a8de-3c3944d5e266",
  "parentPaymentId": "870bf24b-885f-4b1f-a8de-3c3944d5e266",
  "externalPaymentId": "ANI-GMT9433682",
  "created": "2026-01-26 16:25:50",
  "amount": 0.00,
  "approved": false,
  "status": "DECLINED",
  "responseCode": "PAY_022",
  "message": "Rejected by provider",
  "issuerName": "MASTERCARD EUROPE",
  "issuerCountry": "BELGIUM",
  "avsResult": "N/A",
  "cvcResult": "N/A",
  "aavCardholderNameResult": "N/A",
  "redirectAcsUrl": ""
}

Teste a existência de verificationResults antes de lê-lo. Note que N/A pode aparecer nesses campos planos — nunca aparece dentro de verificationResults.

Erro de Validação (400)

Todos os campos que falharam na validação são reportados de uma só vez:

{
  "code": "VE_001",
  "message": "Validation error",
  "errors": [
    {
      "field": "sender.address.city",
      "message": "sender.address.city can't be empty"
    },
    {
      "field": "sender.paymentMethod.cardTokenId",
      "message": "sender.paymentMethod.cardTokenId does not match the expected format uuid"
    }
  ]
}

Campos da Resposta

Campos nulos são omitidos da resposta, então um registro de cartão sem nome do emissor simplesmente não traz a chave issuerName.

card

CampoTipoDescrição
createdstringTimestamp de criação da verificação
issuerNamestringNome do banco emissor
issuerCountrystringPaís emissor
binstringBank Identification Number (primeiros 6 dígitos)
lastFourstringÚltimos 4 dígitos do cartão

verificationResults

CampoTipoDescrição
avsstringResultado da verificação de endereço (veja abaixo)
cvcstringResultado da verificação do código de segurança (veja abaixo)
aavCardholderNamestringResultado da verificação do nome do portador — Visa ANI, somente Visa (veja abaixo)

octStatus / aftStatus

Indicadores de capacidade do cartão, preenchidos somente para cartões Visa. OCT (Original Credit Transaction) reflete a capacidade do cartão de receber envios/payouts; AFT (Account Funding Transaction) reflete a capacidade de financiar cobranças.

CampoTipoDescrição
capablebooleanSe o cartão suporta esse tipo de transação
highPerformingbooleanO cartão está na faixa de alto desempenho para esse tipo de transação
lowPerformingbooleanO cartão está na faixa de baixo desempenho para esse tipo de transação

Para um cartão não Visa a consulta de readiness não é executada, então os três indicadores voltam como false. Isso significa "não avaliado" — não "incapaz".

redirectAcsUrl

CampoTipoDescrição
redirectAcsUrlstringURL do desafio 3DS. Vazia ("") quando não há desafio; quando preenchida, redirecione o portador para completar a autenticação.

Entendendo os Resultados da Verificação

Os três valores são as descrições de resultado do emissor/adquirente resolvidas pelo mapeamento de códigos de provedor do gateway, com uma normalização adicional no gateway: um resultado ausente, vazio, NA ou N/A se torna NOT_SUPPORTED. Por isso N/A nunca chega até você dentro de verificationResults.

ValorSignificadoAção
APPROVEDO emissor encontrou correspondência com o valor enviadoTrate como verificado
NOT_CHECKEDO emissor ou o adquirente não executou esta verificaçãoSem sinal — recorra às outras verificações
NOT_SUPPORTEDNenhum resultado voltou: não suportado para este cartão, ou há um desafio 3DS pendenteSem sinal
qualquer outro valorUma descrição de resultado específica do emissor, como correspondência parcial ou falhaNão trate como verificado

Somente APPROVED é aprovação. O conjunto de valores depende do emissor e do adquirente, então compare por igualdade com APPROVED em vez de enumerar strings de falha.

Resultado do AVS (verificationResults.avs)

Compara o endereço de cobrança de sender.address com o endereço registrado no emissor do cartão. Os cinco campos de endereço obrigatórios alimentam a comparação.

Resultado do CVC (verificationResults.cvc)

Valida o código de segurança capturado durante a tokenização. A requisição da Check Card Account não carrega código de segurança — ele viaja dentro do token do cartão.

Resultado do Nome do Portador AAV (verificationResults.aavCardholderName)

Somente cartões Visa. Verifica se sender.firstName e sender.lastName correspondem ao nome legal registrado no banco emissor, por meio do serviço Account Name Inquiry (ANI) da Visa.

Importante: o ANI é executado somente para cartões Visa. Para Mastercard, Amex, Discover e outras redes este campo não traz veredito — recorra ao AVS e ao CVC.

Formato do nome: a comparação é feita pelo emissor Visa, que verifica separadamente os componentes de primeiro nome, nome do meio e sobrenome. Envie o nome exatamente como aparece no cartão. A Visa suporta até 35 caracteres por campo de nome. Sufixos (Jr., III) e prefixos (Dr.) não são suportados pelo ANI e devem ser omitidos.

Exemplo de Integração

Etapa 1 — Tokenize o Cartão

Use o inyo.js para coletar e tokenizar os dados do cartão no lado do cliente. O nome do portador digitado no campo data-field="cardholder" é incluído no 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)
});

Etapa 2 — Chame a Check Card Account

Envie o token para o seu backend, que chama a API Check Card Account:

async function checkCardAccount(cardTokenId) {
  const response = await fetch('https://{FQDN}/v2/check-card-account', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      externalPaymentId: `ANI-${crypto.randomUUID()}`,
      ipAddress: customerIpAddress,
      sender: {
        firstName: 'John',
        lastName: 'Smith',
        email: '[email protected]',
        address: {
          countryCode: 'USA',
          stateCode: 'NY',
          state: 'NY',
          city: 'New York',
          line1: '123 Main Street',
          line2: '',
          zipCode: '10001'
        },
        paymentMethod: {
          type: 'CARD',
          cardTokenId: cardTokenId
        }
      }
    })
  });

  const result = await response.json();

  if (result.redirectAcsUrl) {
    // Trate o 3DS — redirecione ou abra um iframe
    window.open(result.redirectAcsUrl, '_blank');
    return;
  }

  // Avalie os sinais de verificação estruturados
  console.log('AVS:', result.verificationResults.avs);
  console.log('CVC:', result.verificationResults.cvc);
  console.log('ANI (Name):', result.verificationResults.aavCardholderName);
  console.log('Push (OCT) capable:', result.octStatus?.capable);
  console.log('Pull (AFT) capable:', result.aftStatus?.capable);
}

Etapa 3 — Avalie os Resultados

Ramifique primeiro pela forma do corpo e depois pelas verificações. Somente APPROVED é aprovação, e aavCardholderName traz veredito apenas para cartões Visa.

function evaluateCardCheck(result) {
  // Recusado: a forma de resposta de pagamento, sem o objeto verificationResults
  if (!result.verificationResults) {
    return { accept: false, reason: result.message || `Recusado (${result.responseCode})` };
  }

  // Desafio 3DS pendente — as verificações ainda não trazem veredito
  if (result.redirectAcsUrl) {
    return { accept: false, reason: 'Desafio 3DS necessário' };
  }

  const { avs, cvc, aavCardholderName } = result.verificationResults;
  const passed = (v) => v === 'APPROVED';
  const noSignal = (v) => v === 'NOT_CHECKED' || v === 'NOT_SUPPORTED';

  // Tudo que não é APPROVED nem um valor sem sinal é divergência
  if (!passed(cvc) && !noSignal(cvc)) {
    return { accept: false, reason: `O CVC não correspondeu (${cvc})` };
  }
  if (!passed(aavCardholderName) && !noSignal(aavCardholderName)) {
    return { accept: false, reason: `O nome não correspondeu aos registros do emissor (${aavCardholderName})` };
  }
  if (!passed(avs) && !noSignal(avs)) {
    return { accept: false, reason: `O AVS não correspondeu (${avs})` };
  }

  const verified = [['AVS', avs], ['CVC', cvc], ['ANI', aavCardholderName]]
    .filter(([, value]) => passed(value))
    .map(([name]) => name);

  return verified.length > 0
    ? { accept: true, reason: `Verificado por ${verified.join(' + ')}` }
    : { accept: true, reason: 'Nenhuma verificação retornou resultado — aplique sua própria lógica de risco' };
}

Testes

Use o seguinte cartão de teste no sandbox para a Check Card Account:

Número do CartãoRedeDescrição
4462 0300 0000 0000Visa DebitCartão de teste padrão para ANI

Use o nome de portador AUTHORISED para simular um resultado aprovado. Consulte Dados de Teste — Cartões para valores de simulação de CVV e AVS.

Boas Práticas

  1. Envie o endereço de cobrança completocountryCode, stateCode, city, line1 e zipCode são todos obrigatórios, e são exatamente o que o AVS compara. Envie state junto de stateCode para que o registro de endereço armazenado também o tenha.

  2. Faça o nome do tokenizador coincidir com o da API — O campo cardholder do formulário do tokenizador deve conter o mesmo nome enviado em sender.firstName e sender.lastName. Para o Visa ANI, divergência entre o nome tokenizado e o da API faz o emissor retornar um resultado sem correspondência.

  3. Decida por APPROVED, não por strings de falha — Os valores de resultado vêm do emissor e do adquirente, então o vocabulário de falha não é fixo. Aceite apenas APPROVED; trate qualquer outro valor que não seja NOT_CHECKED ou NOT_SUPPORTED como divergência.

  4. Trate NOT_CHECKED e NOT_SUPPORTED com cuidado — Nenhum dos dois é falha. Ambos significam que a verificação não produziu resultado, seja porque o cartão não é Visa, porque o emissor não executa a verificação, ou porque há um desafio 3DS pendente. Recorra às verificações que retornaram resultado.

  5. octStatus / aftStatus são exclusivos de Visa — Para um cartão não Visa a consulta de readiness nunca é executada e os três indicadores vêm como false. Não leia isso como "este cartão não pode receber um payout".

  6. Ramifique pela forma do corpo, não pelo código de status — Uma verificação recusada responde HTTP 200 com a forma de resposta de pagamento e sem verificationResults. Teste a existência desse objeto antes de lê-lo.

  7. Envie externalPaymentId e ipAddress — Ambos são obrigatórios, e o IP precisa ser um literal IPv4 ou IPv6 válido. Um valor ausente ou malformado falha na validação com HTTP 400 antes de qualquer contato com o cartão.

  8. Use antes de armazenar cartões — Rode uma chamada de Check Card Account antes de salvar um token de cartão com storeLaterUse: true para confirmar que o cartão é válido e pertence à pessoa esperada.

  9. Use o nome legal do cartão — O Visa ANI compara com o nome legal que o emissor tem registrado, não apelidos ou nomes preferidos. Omita sufixos (Jr., III) e prefixos (Dr.), que o ANI não suporta.

Próximos Passos