Saltar al contenido principal

Autenticación 3D Secure

Integra 3D Secure en tu flujo de pago para reducir el fraude y cumplir con requisitos regulatorios.

¿Qué es 3D Secure?​

3D Secure (3DS) es un protocolo de autenticación que añade una capa adicional de seguridad a las transacciones con tarjeta. Cuando está activo, el banco emisor puede solicitar al titular de la tarjeta que se autentique durante el proceso de pago.

Beneficios:

  • ✅ Reducción de fraude
  • ✅ Cumplimiento regulatorio
  • ✅ Confianza del cliente

Flujo de Autenticación​

No todas las transacciones requieren 3DS

El sistema evalúa automáticamente cada transacción. Solo cuando es necesario, recibirás el estado AUTHENTICATION_REQUIRED.


Implementación​

Paso 1: Primera petición​

Siempre envía authenticationId: null en tu primera petición de pago o suscripción.

{
"customer": {
"id": "customer112",
"name": "Carlos Pérez",
"email": "[email protected]",
"phoneNumber": "+50370000000"
},
"order": {
"id": "EPAY001",
"amount": 15.9,
"description": "seguro",
"name": "auto"
},
"cardId": "69167196381d34f25eb22e9d",
"authenticationId": null,
"locationCode": "N1C0CD001"
}

Paso 2: Manejar respuesta​

Si recibes el estado AUTHENTICATION_REQUIRED, debes mostrar el iframe de autenticación:

{
"status": "AUTHENTICATION_REQUIRED",
"message": "El pago requiere autenticación 3DS",
"error": null,
"authentication": {
"url": "https://front-3ds-sandbox.n1co.com/authentication/b574cee2-1ce7-4aa7-b176-8a6390e91081",
"id": "b574cee2-1ce7-4aa7-b176-8a6390e91081"
},
"order": null,
"createdAt": "2023-09-28T18:53:51.1070240Z"
}

Paso 3: Renderizar iframe​

Crea un iframe para mostrar la interfaz de autenticación:

const iframe = document.createElement('iframe');
iframe.src = authentication.url;
iframe.width = 600;
iframe.height = 400;

document.getElementById('authentication-container').appendChild(iframe);

Ejemplos de implementación:

Paso 4: Escuchar PostMessage​

El iframe enviará un mensaje cuando la autenticación termine. Ten en cuenta dos detalles:

  • El mensaje llega como texto JSON: aplica JSON.parse(event.data) antes de leer sus campos.
  • El origen depende del ambiente. Tómalo de la authentication.url que te devolvió la API en lugar de fijarlo en el código:
AmbienteOrigen del iframe 3DS
Sandboxhttps://front-3ds-sandbox.n1co.com
Producciónhttps://front-3ds.n1co.com
// authentication.url es el valor recibido en la respuesta AUTHENTICATION_REQUIRED
const expectedOrigin = new URL(authentication.url).origin;

window.addEventListener('message', function(event) {
// Validar origen del mensaje
if (event.origin !== expectedOrigin) {
return;
}

let data;
try {
// El iframe envía el mensaje como texto JSON
data = JSON.parse(event.data);
} catch {
return;
}

// Manejar diferentes estados
handleAuthenticationResult(data);
});

function handleAuthenticationResult(data) {
const { MessageType, Status, AuthenticationId, ErrorDetail } = data;

if (MessageType === 'authentication.complete' && Status === 'SUCCESS') {
// Proceder con segunda petición
completePayment(AuthenticationId);
} else if (Status === 'EXPIRED') {
// Autenticación expiró
showError('La autenticación ha expirado. Por favor intenta nuevamente.');
} else {
// FAILED o ERROR: mostrar error al usuario
showError(ErrorDetail || 'La autenticación falló. Por favor intenta con otro método de pago.');
}
}

Estructura del PostMessage​

CampoTipoDescripción
MessageTypeStringauthentication.complete | authentication.failed
StatusStringPENDING | SUCCESS | FAILED | ERROR | EXPIRED
AuthenticationIdStringID único de autenticación para la segunda petición
OrderIdStringID de la orden
OrderAmountNumberMonto de la orden
ErrorTitleStringTítulo del error, cuando la autenticación no fue exitosa
ErrorDetailStringDetalle del error, cuando la autenticación no fue exitosa

Estados posibles:

StatusDescripciónAcción
SUCCESS✅ Autenticación exitosaProceder con segunda petición
FAILED❌ No se logró autenticar con el bancoSolicitar otro método de pago
ERROR❌ Error interno del procesadorReintentar o contactar soporte
EXPIRED⏱️ La sesión de autenticación expiróReiniciar el proceso
PENDING⏳ Aún procesandoContinuar esperando

Paso 5: Segunda petición​

Una vez recibido el mensaje con MessageType = "authentication.complete" y Status = "SUCCESS", realiza una nueva petición incluyendo el authenticationId:

Respuesta Exitosa

La respuesta de esta segunda petición será con el estado SUCCEEDED si la autenticación fue completada correctamente.


Mejores Prácticas​

✅ Hacer​

  • Siempre envía authenticationId: null en la primera petición
  • Valida el origen de los mensajes PostMessage contra el origen de authentication.url (cambia entre Sandbox y Producción)
  • Maneja todos los estados posibles (SUCCESS, FAILED, ERROR, EXPIRED, PENDING)
  • Proporciona mensajes claros al usuario durante el proceso
  • Registra los eventos: Para debugging y análisis
  • Diseña UI responsive: El iframe debe adaptarse a diferentes dispositivos

❌ Evitar​

  • ❌ No reutilices authenticationId de transacciones anteriores
  • ❌ No envíes authenticationId si no recibiste AUTHENTICATION_REQUIRED

Diagrama Completo del Flujo​


Recursos Adicionales​