Check Card Account (ANI)
La API Check Card Account valida una tarjeta sin procesar un pago. Realiza hasta tres verificaciones más un perfilado de capacidades de la tarjeta y devuelve los resultados:
- AVS — Address Verification Service (coincidencia de la dirección de facturación) — todas las redes de tarjetas
- CVC — Card Verification Code (coincidencia del código de seguridad) — todas las redes de tarjetas
- AAV Cardholder Name — Account Name Inquiry de Visa (coincidencia del nombre del tarjetahabiente contra los registros del emisor) — solo tarjetas Visa
Las verificaciones AVS y CVC son controles estándar realizados para cualquier tarjeta. La verificación del nombre del tarjetahabiente está impulsada por el producto Account Name Inquiry (ANI) de Visa, que consulta los registros del banco emisor para verificar que el nombre enviado coincida con el nombre legal en la cuenta. ANI solo está disponible para tarjetas Visa — en cualquier otra red verificationResults.aavCardholderName no trae veredicto.
La respuesta también reporta la capacidad OCT (push/payout) y AFT (fondeo/pull) de la tarjeta para que puedas decidir la elegibilidad de una tarjeta para un flujo determinado antes de iniciar una transacción.
¿Qué es Visa ANI?
Account Name Inquiry (ANI) es un producto de Visa que permite a los comercios verificar el nombre del tarjetahabiente directamente con el banco emisor antes de una transacción financiera o de forma independiente a ella. Cuando se envía una tarjeta, Visa reenvía el primer nombre, segundo nombre y apellido proporcionados al emisor, quien los compara contra el nombre legal en la cuenta y devuelve un resultado de coincidencia.
Detalles clave sobre Visa ANI:
- Solo Visa — ANI es un servicio de la red Visa. No está disponible para Mastercard, Amex, Discover u otras redes.
- Participación del emisor — ANI se volvió obligatorio para los emisores Visa de EE. UU. y Canadá en octubre de 2023, lo que significa que la mayoría de los emisores Visa en estos mercados lo soportan. Algunos emisores fuera de estos mercados pueden aún no soportar ANI, en cuyo caso el resultado no trae veredicto —
NOT_CHECKEDoNOT_SUPPORTED. - Coincidencia de nombres — Visa verifica los componentes de primer nombre, segundo nombre y apellido por separado contra los registros del emisor. Como mínimo, debe proporcionarse el apellido. El emisor devuelve la coincidencia más cercana cuando hay varios nombres registrados (p. ej., cuentas conjuntas).
- Independiente del pago — ANI opera de forma independiente a la transacción financiera. No se retienen ni se mueven fondos.
- Exclusiones — Las tarjetas empresariales/corporativas y las tarjetas prepagadas no recargables sin un nombre registrado no son soportadas por ANI.
Casos de Uso
- Onboarding — Valida la tarjeta de un cliente antes de almacenarla para cargos futuros
- Prevención de fraude — Confirma que la persona que envía la tarjeta es el tarjetahabiente real
- Mejora de KYC — Cruza el nombre en la tarjeta con el nombre proporcionado durante la verificación de identidad
- Elegibilidad de payout — Verifica
octStatusantes de enviar fondos a una tarjeta; verificaaftStatusantes de extraerlos (solo tarjetas Visa) - Verificación de tarjeta guardada — Comprueba que una tarjeta almacenada sigue siendo válida y pertenece a la persona esperada
Cómo Funciona
sequenceDiagram
participant B as Navegador<br/>inyo.js
participant S as Tu servidor
participant G as Inyo
participant I as Emisor
B->>G: Datos de la tarjeta +<br/>nombre del tarjetahabiente
G-->>B: cardTokenId
B->>S: cardTokenId
S->>G: POST<br/>/v2/check-card-account
G->>I: Autorización de monto cero:<br/>AVS + CVC
opt Tarjeta Visa
G->>I: Consulta de nombre<br/>ANI
end
I-->>G: Resultados
G-->>S: verificationResults +<br/>octStatus / aftStatus
Nota: Esta API no realiza cargos a la tarjeta — se ejecuta como una autorización de monto cero, así que no se retienen ni mueven fondos. No se requiere
amounten la solicitud.
Endpoint
POST https://{FQDN}/v2/check-card-account
Encabezados:
| Encabezado | Valor |
|---|---|
Authorization | Bearer {accessToken} |
Content-Type | application/json |
Cuerpo de la Solicitud
El payload es simplificado en comparación con las solicitudes de pago estándar — no se necesitan los campos amount, paymentType ni capture. Internamente el gateway ejecuta la verificación como una autorización CHECK de monto cero, por lo que la solicitud se valida contra el esquema del endpoint y contra el esquema compartido de pagos con tarjeta. Las tablas siguientes reflejan el resultado combinado.
Objeto Raíz
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
externalPaymentId | string | Sí | Tu identificador único para esta solicitud de validación |
ipAddress | string | Sí | Dirección IP del solicitante — debe ser un literal IPv4 o IPv6 válido |
sender | object | Sí | Datos del tarjetahabiente (ver abajo) |
Objeto sender
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
firstName | string | Sí | Primer nombre del tarjetahabiente, al menos 1 carácter (comparado contra los registros del emisor vía Visa ANI para tarjetas Visa) |
lastName | string | Sí | Apellido del tarjetahabiente, al menos 1 carácter (comparado contra los registros del emisor vía Visa ANI para tarjetas Visa) |
address | object | Sí | Dirección de facturación — lo que compara AVS (ver abajo) |
paymentMethod | object | Sí | Datos de la tarjeta tokenizada (ver abajo) |
email | string | No | Correo electrónico del tarjetahabiente — se almacena con el registro de la verificación |
phoneNumber | string | No | Número de teléfono del tarjetahabiente — se almacena con el registro de la verificación |
Objeto sender.address
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
countryCode | string | Sí | Código de país ISO Alpha-3 (p. ej., "USA" — no "US") |
stateCode | string | Sí | Abreviatura de estado/provincia (p. ej., "MA") |
city | string | Sí | Nombre de la ciudad |
line1 | string | Sí | Línea 1 de la dirección |
zipCode | string | Sí | Código postal/ZIP |
state | string | No | Estado/provincia tal como queda en el registro de dirección almacenado — envía el mismo valor que stateCode |
line2 | string | No | Línea 2 de la dirección — envía "" cuando no haya segunda línea |
Objeto sender.paymentMethod
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
type | string | Sí | "CARD" |
cardTokenId | string | Sí | UUID del token obtenido del tokenizador — debe ser un UUID bien formado |
Ejemplo de Solicitud
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"
}
}
}'
Respuesta
Tres resultados comparten el HTTP 200 y no comparten la forma del cuerpo. Ramifica según los campos presentes, nunca solo según el código de estado.
Verificada (200)
La autorización de monto cero fue aprobada. card, verificationResults, octStatus, aftStatus y redirectAcsUrl siempre están 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": ""
}
Las llamadas repetidas se responden con el resultado almacenado. Una vez que ANI se ejecutó para un
firstName+lastName+ token de tarjeta dados, una llamada idéntica devuelve el resultado registrado en lugar de volver a consultar al emisor. Cambiar cualquiera de los dos nombres genera una nueva consulta al emisor.
Desafío 3DS (200)
El banco emisor requiere autenticación del tarjetahabiente antes de que se conozcan los resultados. El cuerpo conserva la forma verificada, redirectAcsUrl viene poblado y todas las verificaciones devuelven NOT_SUPPORTED hasta que el desafío se complete:
{
"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-..."
}
Cuando redirectAcsUrl no está vacío, redirige al tarjetahabiente hacia esa URL — y no leas las verificaciones de este cuerpo, todavía no traen veredicto. Consulta Manejo de 3D Secure para el flujo completo.
Rechazada (200)
Cuando la autorización de monto cero subyacente no es aprobada, el endpoint responde con la forma de respuesta de pago. No hay objeto verificationResults, y los resultados de las verificaciones llegan 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": ""
}
Comprueba la existencia de verificationResults antes de leerlo. Nota que N/A puede aparecer en estos campos planos — nunca aparece dentro de verificationResults.
Error de Validación (400)
Se reportan a la vez todos los campos que fallaron la validación:
{
"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 de la Respuesta
Los campos nulos se omiten de la respuesta, así que un registro de tarjeta sin nombre de emisor simplemente no trae la clave issuerName.
card
| Campo | Tipo | Descripción |
|---|---|---|
created | string | Marca de tiempo de creación de la verificación |
issuerName | string | Nombre del banco emisor |
issuerCountry | string | País emisor |
bin | string | Bank Identification Number (primeros 6 dígitos) |
lastFour | string | Últimos 4 dígitos de la tarjeta |
verificationResults
| Campo | Tipo | Descripción |
|---|---|---|
avs | string | Resultado de verificación de dirección (ver abajo) |
cvc | string | Resultado de verificación del código de seguridad (ver abajo) |
aavCardholderName | string | Resultado de verificación del nombre del tarjetahabiente — Visa ANI, solo Visa (ver abajo) |
octStatus / aftStatus
Indicadores de capacidad de la tarjeta, poblados solo para tarjetas Visa. OCT (Original Credit Transaction) refleja la capacidad de la tarjeta de recibir envíos/payouts; AFT (Account Funding Transaction) refleja su capacidad de fondear cobros.
| Campo | Tipo | Descripción |
|---|---|---|
capable | boolean | Si la tarjeta soporta este tipo de transacción |
highPerforming | boolean | La tarjeta está en el nivel de alto desempeño para este tipo de transacción |
lowPerforming | boolean | La tarjeta está en el nivel de bajo desempeño para este tipo de transacción |
Para una tarjeta no Visa la consulta de readiness no se ejecuta, por lo que los tres indicadores vuelven en
false. Eso significa "no evaluado" — no "no capaz".
redirectAcsUrl
| Campo | Tipo | Descripción |
|---|---|---|
redirectAcsUrl | string | URL del desafío 3DS. Vacía ("") cuando no se requiere desafío; cuando viene poblada, redirige al tarjetahabiente para completar la autenticación. |
Interpretación de los Resultados de Verificación
Los tres valores son las descripciones de resultado del emisor/adquirente resueltas por el mapeo de códigos de proveedor del gateway, con una normalización adicional a nivel de gateway: un resultado ausente, vacío, NA o N/A se convierte en NOT_SUPPORTED. Por eso N/A nunca te llega dentro de verificationResults.
| Valor | Significado | Acción |
|---|---|---|
APPROVED | El emisor encontró coincidencia con el valor enviado | Trátalo como verificado |
NOT_CHECKED | El emisor o el adquirente no ejecutó esta verificación | Sin señal — apóyate en las otras verificaciones |
NOT_SUPPORTED | No volvió ningún resultado: no soportado para esta tarjeta, o hay un desafío 3DS pendiente | Sin señal |
| cualquier otro valor | Una descripción de resultado específica del emisor, como coincidencia parcial o fallida | No lo trates como verificado |
Solo
APPROVEDes una aprobación. El conjunto de valores depende del emisor y del adquirente, así que compara por igualdad conAPPROVEDen lugar de enumerar cadenas de falla.
Resultado AVS (verificationResults.avs)
Compara la dirección de facturación de sender.address con la dirección registrada en el emisor de la tarjeta. Los cinco campos de dirección requeridos alimentan la comparación.
Resultado CVC (verificationResults.cvc)
Valida el código de seguridad capturado durante la tokenización. La solicitud de Check Card Account no lleva código de seguridad — este viaja dentro del token de la tarjeta.
Resultado AAV Cardholder Name (verificationResults.aavCardholderName)
Solo tarjetas Visa. Verifica si sender.firstName y sender.lastName coinciden con el nombre legal registrado en el banco emisor, mediante el servicio Account Name Inquiry (ANI) de Visa.
Importante: ANI se ejecuta solo para tarjetas Visa. Para Mastercard, Amex, Discover y otras redes este campo no trae veredicto — apóyate en AVS y CVC.
Formato del nombre: la comparación la realiza el emisor Visa, que verifica por separado los componentes de primer nombre, segundo nombre y apellido. Envía el nombre exactamente como aparece en la tarjeta. Visa soporta hasta 35 caracteres por campo de nombre. Los sufijos (Jr., III) y prefijos (Dr.) no son soportados por ANI y deben omitirse.
Ejemplo de Integración
Paso 1 — Tokeniza la Tarjeta
Usa inyo.js para recopilar y tokenizar los datos de la tarjeta del lado del cliente. El nombre del tarjetahabiente ingresado en el campo data-field="cardholder" se incluye en el 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)
});
Paso 2 — Llama a Check Card Account
Envía el token a tu backend, que llama a la 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) {
// Manejar 3DS — redirigir o abrir un iframe
window.open(result.redirectAcsUrl, '_blank');
return;
}
// Evaluar las señales de verificación estructuradas
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);
}
Paso 3 — Evalúa los Resultados
Ramifica primero según la forma del cuerpo y después según las verificaciones. Solo APPROVED es una aprobación, y aavCardholderName trae veredicto únicamente para tarjetas Visa.
function evaluateCardCheck(result) {
// Rechazada: la forma de respuesta de pago, sin objeto verificationResults
if (!result.verificationResults) {
return { accept: false, reason: result.message || `Rechazada (${result.responseCode})` };
}
// Desafío 3DS pendiente — las verificaciones aún no traen veredicto
if (result.redirectAcsUrl) {
return { accept: false, reason: 'Se requiere desafío 3DS' };
}
const { avs, cvc, aavCardholderName } = result.verificationResults;
const passed = (v) => v === 'APPROVED';
const noSignal = (v) => v === 'NOT_CHECKED' || v === 'NOT_SUPPORTED';
// Todo lo que no sea APPROVED ni un valor sin señal es una discrepancia
if (!passed(cvc) && !noSignal(cvc)) {
return { accept: false, reason: `El CVC no coincidió (${cvc})` };
}
if (!passed(aavCardholderName) && !noSignal(aavCardholderName)) {
return { accept: false, reason: `El nombre no coincidió con los registros del emisor (${aavCardholderName})` };
}
if (!passed(avs) && !noSignal(avs)) {
return { accept: false, reason: `El AVS no coincidió (${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: 'Ninguna verificación devolvió resultado — aplica tu propia lógica de riesgo' };
}
Pruebas
Usa la siguiente tarjeta de prueba en sandbox para Check Card Account:
| Número de Tarjeta | Red | Descripción |
|---|---|---|
4462 0300 0000 0000 | Visa Debit | Tarjeta de prueba estándar para ANI |
Usa el nombre de tarjetahabiente AUTHORISED para simular un resultado aprobado. Consulta Datos de Prueba — Tarjetas para los valores de simulación de CVV y AVS.
Buenas Prácticas
Envía la dirección de facturación completa —
countryCode,stateCode,city,line1yzipCodeson todos requeridos, y son exactamente lo que compara AVS. Envíastatejunto constateCodepara que el registro de dirección almacenado también lo tenga.Haz coincidir el nombre del tokenizador con el de la API — El campo
cardholderdel formulario del tokenizador debe contener el mismo nombre que envías ensender.firstNameysender.lastName. Para Visa ANI, una discrepancia entre el nombre tokenizado y el de la API hace que el emisor devuelva un resultado sin coincidencia.Decide por
APPROVED, no por cadenas de falla — Los valores de resultado provienen del emisor y del adquirente, así que el vocabulario de falla no es fijo. Acepta soloAPPROVED; trata cualquier otro valor que no seaNOT_CHECKEDniNOT_SUPPORTEDcomo una discrepancia.Maneja
NOT_CHECKEDyNOT_SUPPORTEDcon cuidado — Ninguno es una falla. Ambos significan que la verificación no produjo resultado, ya sea porque la tarjeta no es Visa, porque el emisor no ejecuta la verificación, o porque hay un desafío 3DS pendiente. Apóyate en las verificaciones que sí devolvieron resultado.octStatus/aftStatusson solo para Visa — Para una tarjeta no Visa la consulta de readiness nunca se ejecuta y los tres indicadores vienen enfalse. No lo interpretes como "esta tarjeta no puede recibir un payout".Ramifica por la forma del cuerpo, no por el código de estado — Una verificación rechazada responde HTTP
200con la forma de respuesta de pago y sinverificationResults. Comprueba la existencia de ese objeto antes de leerlo.Envía
externalPaymentIdeipAddress— Ambos son requeridos, y la IP debe ser un literal IPv4 o IPv6 válido. Un valor ausente o mal formado falla la validación con HTTP400antes de que se contacte la tarjeta.Úsalo antes de almacenar tarjetas — Ejecuta una llamada de Check Card Account antes de guardar un token de tarjeta con
storeLaterUse: truepara confirmar que la tarjeta es válida y pertenece a la persona esperada.Usa el nombre legal de la tarjeta — Visa ANI compara contra el nombre legal que el emisor tiene registrado, no apodos ni nombres preferidos. Omite sufijos (Jr., III) y prefijos (Dr.), que ANI no soporta.
Qué Sigue
- Tokenización de Tarjetas — Configura la tokenización de tarjetas del lado del cliente
- Manejo de AVS / CVC — Análisis a fondo de la verificación de dirección y código de seguridad
- Manejo de 3D Secure — Maneja las respuestas CHALLENGE
- Autorización de un Pago con Tarjeta — Crea transacciones de pago reales después de la validación
