Authenticate
El Authenticate Request es el paso central del flujo 3DS. Solicita la autenticación de la transacción al emisor de la tarjeta.
Endpoint
POST https://api.akua.la/v1/3ds/authenticate
Request DTO Completo
{
"merchant_id": "string (requerido)",
"customer_id": "string (opcional)",
"transaction_id": "string (opcional)",
"data": {
"device_channel": "string (requerido: 01, 02, 03)",
"message_version": "string (opcional, ej: 2.2.0)",
"threeds_server_trans_id": "string (opcional, del Version Response)",
"message_category": "string (requerido: 01, 02)",
"notification_url": "string (requerido, URL de webhook)",
"purchase_amount": "string (opcional, ej: 10000 para $100.00)",
"purchase_currency": "string (opcional, código numérico ISO 4217)",
"purchase_exponent": "string (opcional, ej: 2 para centavos)",
"purchase_date": "string (opcional, formato YYYYMMDDHHmmss)",
"recurring_expiry": "string (opcional, formato YYYYMMDD)",
"recurring_frequency": "string (opcional, días entre cargos)",
"purchase_instal_data": "string (opcional, número máximo de cuotas)",
"trans_type": "string (opcional: 01, 03, 10, 11, 28)",
"threeds_requestor_url": "string (requerido, URL de su sitio)",
"threeds_requestor_dec_max_time": "string (opcional, minutos)",
"threeds_requestor_dec_req_ind": "string (opcional: Y, N)",
"threeds_requestor_authentication_ind": "string (requerido: 01-07)",
"threeds_requestor_authentication_info": {
"threeds_req_auth_method": "string (opcional: 01-08)",
"threeds_req_auth_timestamp": "string (opcional, formato YYYYMMDDHHmmss)",
"threeds_req_auth_data": "string (opcional)"
},
"threeds_requestor_prior_authentication_info": {
"threeds_req_prior_auth_method": "string (opcional: 01-04)",
"threeds_req_prior_auth_timestamp": "string (opcional, formato YYYYMMDDHHmm)",
"threeds_req_prior_ref": "string (opcional)",
"threeds_req_prior_auth_data": "string (opcional)"
},
"threeds_requestor_challenge_ind": "string (opcional: 01-09, 90)",
"threeds_comp_ind": "string (opcional: Y, N)",
"threeri_ind": "string (opcional)",
"merchant_risk_indicator": {
"delivery_email_address": "string (opcional)",
"delivery_time_frame": "string (opcional: 01-04)",
"gift_card_amount": "string (opcional)",
"gift_card_count": "string (opcional)",
"gift_card_curr": "string (opcional)",
"pre_order_purchase_ind": "string (opcional: 01, 02)",
"pre_order_date": "string (opcional, formato YYYYMMDD)",
"reorder_items_ind": "string (opcional: 01, 02)",
"ship_indicator": "string (opcional: 01-07)"
},
"card_data": {
"instrument_id": "string (opcional)",
"card_number": "string (opcional)",
"card_expiry_date": "string (opcional, formato MMYY)"
},
"cardholder": {
"cardholder_name": "string (opcional)",
"acct_type": "string (opcional: 01, 02, 03)",
"acct_id": "string (opcional)",
"acct_info": {},
"email": "string (opcional)",
"home_phone": {
"cc": "string (opcional, código de país)",
"subscriber": "string (opcional, número sin código)"
},
"mobile_phone": {
"cc": "string (opcional)",
"subscriber": "string (opcional)"
},
"work_phone": {
"cc": "string (opcional)",
"subscriber": "string (opcional)"
},
"addr_match": "string (opcional: Y, N)",
"bill_addr_line1": "string (opcional)",
"bill_addr_line2": "string (opcional)",
"bill_addr_line3": "string (opcional)",
"bill_addr_city": "string (opcional)",
"bill_addr_state": "string (opcional)",
"bill_addr_zip_code": "string (opcional)",
"bill_addr_country": "string (opcional, código numérico ISO 3166)",
"ship_addr_line1": "string (opcional)",
"ship_addr_line2": "string (opcional)",
"ship_addr_line3": "string (opcional)",
"ship_addr_city": "string (opcional)",
"ship_addr_state": "string (opcional)",
"ship_addr_zip_code": "string (opcional)",
"ship_addr_country": "string (opcional, código numérico ISO 3166)"
},
"browser_data": {
"accept_header": "string (opcional)",
"ip_address": "string (opcional)",
"javascript_enabled": true,
"java_enabled": false,
"language": "string (opcional)",
"color_depth": "string (opcional)",
"screen_height": "string (opcional)",
"screen_width": "string (opcional)",
"tz": "string (opcional)",
"user_agent": "string (opcional)"
},
"message_extension": [],
"broad_info": {}
}
}
⚠️ Resumen de Validaciones Importantes
Antes de construir su request, tenga en cuenta estas reglas de validación:
Para Flujos Browser (device_channel = "02"):
- ✅
browser_data.accept_header- REQUERIDO - ✅
browser_data.javascript_enabled- REQUERIDO - ✅
browser_data.language- REQUERIDO - ✅
browser_data.user_agent- REQUERIDO - ✅
threeds_comp_ind- REQUERIDO (use"Y"o"N")
Para Pagos (message_category = "01"):
- ✅
purchase_amount- REQUERIDO - ✅
purchase_currency- REQUERIDO - ✅
purchase_exponent- REQUERIDO - ✅
purchase_date- REQUERIDO
Para Transacciones Recurrentes o con Cuotas (threeds_requestor_authentication_ind = "02" o "03"):
- ✅
purchase_amount- REQUERIDO - ✅
purchase_currency- REQUERIDO - ✅
purchase_exponent- REQUERIDO - ✅
purchase_date- REQUERIDO - Si además
message_category = "01":- ✅
recurring_expiry- REQUERIDO - ✅
recurring_frequency- REQUERIDO
- ✅
Validaciones Importantes
Identificador de Tarjeta (Requerido uno de los dos):
Debe proporcionar exactamente uno de estos grupos:
Opción 1: Tarjeta tokenizada
card_data.instrument_id: String alfanumérico, puede incluir guiones y guiones bajos
Opción 2: Tarjeta sin tokenizar
card_data.card_number: Solo dígitos, sin espacios ni guionescard_data.card_expiry_date: Exactamente 4 dígitos en formatoMMYY
⚠️ Si proporciona ambos, se usará instrument_id y se ignorará el card_number.
Campos Condicionales según device_channel:
Si device_channel = "02" (Browser) - TODOS LOS SIGUIENTES CAMPOS SON REQUERIDOS:
browser_data.accept_header- Requeridobrowser_data.javascript_enabled- Requeridobrowser_data.language- Requeridobrowser_data.user_agent- Requeridothreeds_comp_ind- Requerido (debe ser"Y"o"N")
Campos Condicionales según message_category:
Si message_category = "01" (Payment Authentication) - TODOS LOS SIGUIENTES CAMPOS SON REQUERIDOS:
purchase_amount- Requerido (ej:"10000"para $100.00)purchase_currency- Requerido (código numérico ISO 4217, 3 dígitos)purchase_exponent- Requerido (ej:"2"para centavos)purchase_date- Requerido (formatoYYYYMMDDHHmmss)
Campos Condicionales según threeds_requestor_authentication_ind:
Si threeds_requestor_authentication_ind = "02" (Recurring) o "03" (Installment):
purchase_amount- Requeridopurchase_currency- Requerido (código numérico ISO 4217, 3 dígitos)purchase_exponent- Requeridopurchase_date- Requerido (formatoYYYYMMDDHHmmss)- Si
message_category="01", también se requieren:recurring_expiry- Requerido (formatoYYYYMMDD)recurring_frequency- Requerido (días entre cargos)
Formatos Estrictos:
card_number: Solo dígitos (ej:"4532015112830366")card_expiry_date: Exactamente 4 dígitos (ej:"1226")purchase_currency: Exactamente 3 dígitos (ej:"858")purchase_date: Exactamente 14 dígitosYYYYMMDDHHmmss(ej:"20260129153045")recurring_expiry: Exactamente 8 dígitosYYYYMMDD(ej:"20261231")bill_addr_country/ship_addr_country: Código numérico ISO 3166, 3 dígitos (ej:"858")
Campos Principales del Request
Nivel Superior
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
merchant_id | string | Sí | ID del comercio en Akua |
customer_id | string | No | ID del cliente en su sistema |
transaction_id | string | No | ID de la transacción en su sistema |
data.device_channel
| Valor | Descripción |
|---|---|
"01" | App-based (SDK) |
"02" | Browser |
"03" | 3DS Requestor Initiated (3RI) |
Para flujo browser, siempre use "02".
data.message_category
| Valor | Descripción |
|---|---|
"01" | Payment Authentication (PA) |
"02" | Non-Payment Authentication (NPA) |
Para pagos, use "01".
data.threeds_requestor_authentication_ind
Indica por qué se solicita la autenticación:
| Valor | Descripción |
|---|---|
"01" | Pago - transacción de bienes o servicios |
"02" | Pago - sin pago (enrollment, validación de cuenta) |
"03" | Pago - transacción recurrente |
"04" | Pago - transacción con cuotas |
"05" | Agregar tarjeta (sin pago) |
"06" | Mantener tarjeta (verificación) |
"07" | Verificación de cuenta de tarjeta |
data.cardholder.acct_type
| Valor | Descripción |
|---|---|
"01" | Sin cuenta (invitado) |
"02" | Cuenta creada durante la transacción |
"03" | Cuenta existente |
data.browser_data
⚠️ Campos Requeridos para device_channel = "02" (Browser):
Cuando device_channel es "02", los siguientes campos de browser_data son OBLIGATORIOS:
accept_header- Header Accept HTTP del navegadorjavascript_enabled- Debe sertrue(booleano, no string)language- Idioma del navegador (ej:"es-UY")user_agent- User agent del navegador
⚠️ Campo importante adicional: ip_address debe contener la dirección IP real del cliente, obtenida del lado del servidor.
⚠️ Tipo de datos: Los campos booleanos javascript_enabled y java_enabled deben ser booleanos (true/false), no strings.
Campos del Response
| Campo | Tipo | Descripción |
|---|---|---|
timestamp | integer | Timestamp Unix en milisegundos |
status | integer | Código de estado HTTP |
card_scheme | string | Esquema de la tarjeta |
transaction_id | string | ID de transacción de Akua |
data.message_version | string | Versión del protocolo 3DS usado |
data.threeds_server_trans_id | string | ID de transacción 3DS |
data.acs_trans_id | string | ID de transacción del ACS |
data.trans_status | string | Estado de la autenticación (ver tabla) |
data.authentication_value | string | CAVV - valor de autenticación para autorización |
data.eci | string | Electronic Commerce Indicator |
data.acs_url | string | URL del ACS para challenge (si aplica) |
data.acs_challenge_mandated | string | Si el challenge es mandatorio |
data.authentication_type | string | Tipo de autenticación realizada |
data.trans_status_reason | string | Razón del estado de transacción |
data.instrument_id | string | ID del instrumento tokenizado |
Tabla de trans_status
| Código | Estado | Descripción | Próxima Acción |
|---|---|---|---|
Y | Authenticated Successfully | Autenticación exitosa - transacción frictionless | ✅ Proceder a autorización con CAVV |
N | Not Authenticated | Autenticación fallida - transacción rechazada | ❌ No autorizar la transacción |
U | Authentication Could Not Be Performed | No se pudo realizar autenticación (problemas técnicos) | ⚠️ Decisión de negocio: autorizar bajo su riesgo o rechazar |
A | Attempts Processing Performed | Se intentó autenticar pero no se completó | ⚠️ Proceder a autorización con ECI (riesgo de merchant) |
C | Challenge Required | Se requiere challenge (autenticación con interacción) | 🔐 Iniciar Challenge Request |
D | Decoupled Authentication Confirmed | Autenticación desacoplada confirmada | ⏳ Esperar resultado |
R | Authentication Rejected | Autenticación rechazada por el emisor | ❌ No autorizar la transacción |
I | Information Only | Solo información, sin autenticación | ℹ️ Decisión de negocio |
Flujos Según trans_status
Flujo Frictionless (trans_status = "Y" o "A")
Cuando la autenticación es exitosa sin requerir interacción del usuario:
- El response incluirá
authentication_value(CAVV) yeci - NO habrá
acs_urlen el response - Proceder directamente a autorizar el pago usando el CAVV
if (authResponse.data.trans_status === 'Y' || authResponse.data.trans_status === 'A') {
// Frictionless - proceder a autorización
await authorizePayment({
cavv: authResponse.data.authentication_value,
eci: authResponse.data.eci,
threeDSServerTransID: authResponse.data.threeds_server_trans_id
});
}Flujo con Challenge (trans_status = "C")
Cuando se requiere interacción del usuario para completar la autenticación:
- El response incluirá
acs_url - NO habrá
authentication_valueen este punto - Debe iniciar un Challenge Request
- Después del challenge, obtener el resultado con Result Request
if (authResponse.data.trans_status === 'C') {
// Challenge requerido
const challengeRequest = {
messageType: 'CReq',
messageVersion: authResponse.data.message_version,
threeDSServerTransID: authResponse.data.threeds_server_trans_id,
acsTransID: authResponse.data.acs_trans_id,
challengeWindowSize: '05'
};
SendChallengeRequest(
authResponse.data.acs_url,
challengeRequest,
{ transactionId: authResponse.transaction_id }
);
}Flujos de Rechazo (trans_status = "N", "R")
No autorizar la transacción. Informar al usuario que la autenticación falló.
Flujos de Incertidumbre (trans_status = "U", "D", "I")
Estos estados requieren decisiones de negocio según su política de riesgo.
Updated about 10 hours ago