Webhook JAAK KYC
Manual Completo para Configuración y Uso de Webhooks
⏱️ Tiempo estimado: 45-60 minutos para configuración completa
¿Qué aprenderás en este manual?
Este manual te enseñará a configurar y usar el sistema de webhooks para recibir automáticamente los resultados de las verificaciones KYC. No necesitas conocimientos técnicos avanzados - solo sigue los pasos.
Antes de Empezar - Lista de Verificación
Asegúrate de tener estos elementos listos:
- Servidor web con URL pública accesible (HTTPS obligatorio)
- Capacidad para recibir peticiones HTTP POST
- Conocimiento básico de APIs REST
- Acceso a tu plataforma JAAK configurada
- Editor de código o sistema para manejar peticiones HTTP
Índice de Contenidos
Sección | Qué harás | Tiempo |
---|---|---|
Paso 1 | Entender qué son los webhooks | 5 min |
Paso 2 | Configurar webhook en JAAK | 15 min |
Paso 3 | Preparar endpoint para recibir datos | 20 min |
Paso 4 | Probar funcionamiento | 10 min |
Paso 5 | Interpretar respuestas | 15 min |
PASO 1: ¿Qué es un Webhook?
Concepto Básico
Un webhook es como un "mensajero automático" que JAAK envía a tu sistema cada vez que una verificación KYC se completa.
1.1 ¿Cómo funciona?
1. Cliente completa KYC en JAAK →
2. JAAK procesa la información →
3. JAAK envía resultado a tu URL →
4. Tu sistema recibe y procesa datos
1.2 Beneficios del Webhook
✅ Con Webhook | ❌ Sin Webhook |
---|---|
Recibes resultados automáticamente | Debes consultar manualmente cada resultado |
Procesamiento en tiempo real | Demoras en obtener información |
Actualizaciones inmediatas | Riesgo de perder notificaciones |
Menor carga en tu sistema | Más llamadas API necesarias |
1.3 Información que Recibirás
- Estado de la verificación: APROBADO/RECHAZADO/PENDIENTE
- Datos extraídos: Nombre, fecha de nacimiento, número de documento
- Puntuaciones de confianza: Qué tan seguro lo determinó el sistema
- Metadatos: Timestamps, identificadores únicos
- Detalles de validación: Razones específicas de aprobación/rechazo
PASO 2: Configurar Webhook en JAAK
Objetivo
Configurar la URL donde JAAK enviará los resultados de las verificaciones.
Ruta de navegación
Dashboard Principal → Ajustes → Mi Compañía → Editar
2.1 Acceder a Configuración de Empresa
Paso 1: En el menú lateral ve hasta el botón de "Ajustes"

Paso 2: Haz clic en "Mi Compañía"

Paso 3: Presiona el botón "Editar" (ícono de lápiz)

2.2 Configurar Webhook en KYC Tradicional
En la sección "Configuración de Productos KYC" encontrarás:

📊 Campos de Webhook
Campo | Descripción | Ejemplo | ¿Es obligatorio? |
---|---|---|---|
URL Webhook | Dirección donde JAAK enviará resultados | https://tu-servidor.com/webhook/kyc | Recomendado |
Auth Key | Clave de seguridad para autenticar llamadas | mi-clave-secreta-123 | Recomendado |
2.3 Configurar URL Webhook
Formato Correcto de URL
✅ URLs Válidas:
https://mi-empresa.com/api/webhook/kyc
https://api.mi-empresa.com/kyc/results
https://servidor.mi-empresa.com:8080/webhook
❌ URLs Inválidas:
http://mi-empresa.com/webhook (no HTTPS)
mi-empresa.com/webhook (sin protocolo)
localhost:3000/webhook (no accesible públicamente)
Configurar Auth Key
La Auth Key es una clave secreta que JAAK incluirá en cada petición para que puedas verificar que el webhook realmente viene de JAAK.
Recomendaciones:
- Usa una combinación de letras, números y símbolos
- Mínimo 16 caracteres
- No uses información personal o predecible
- Guárdala en un lugar seguro
Ejemplo de Auth Key segura: JK2024-webhook-Auth-789XYZ
2.4 Guardar Configuración
- Completa los campos URL Webhook y Auth Key
- Haz clic en "Guardar Cambios"
- Verás un mensaje de confirmación
- La configuración estará activa inmediatamente
PASO 3: Preparar Endpoint para Recibir Datos
Objetivo
Configurar tu servidor para recibir y procesar las peticiones HTTP POST de JAAK.
3.1 Especificaciones Técnicas
📡 Método HTTP y Headers
POST /tu-endpoint-webhook
Content-Type: application/json
Authorization: Bearer [TU-AUTH-KEY]
User-Agent: JAAK-Webhook/1.0
Estructura de Datos que Recibirás
{
"event": "kyc.session.completed",
"timestamp": "2024-01-15T10:30:00Z",
"sessionId": "ABC123X",
"data": {
"status": "APPROVED",
"confidence": 95.5,
"user": {
"name": "María González Pérez",
"documentNumber": "ABCD123456789",
"dateOfBirth": "1990-05-15",
"nationality": "MEX"
},
"document": {
"type": "INE",
"country": "MEX",
"isValid": true,
"expirationDate": "2029-05-15"
},
"validation": {
"documentAuthenticity": "PASS",
"faceMatch": "PASS",
"liveness": "PASS"
}
}
}
3.2 Implementación del Endpoint
Ejemplo en Python (Flask)
from flask import Flask, request, jsonify
import json
app = Flask(__name__)
# Tu Auth Key configurada en JAAK
AUTH_KEY = "JK2024-webhook-Auth-789XYZ"
@app.route('/webhook/kyc', methods=['POST'])
def webhook_kyc():
# Verificar autenticación
auth_header = request.headers.get('Authorization', '')
if not auth_header.startswith('Bearer '):
return jsonify({"error": "Missing authorization"}), 401
received_key = auth_header.replace('Bearer ', '')
if received_key != AUTH_KEY:
return jsonify({"error": "Invalid auth key"}), 401
# Procesar datos
try:
data = request.get_json()
# Extraer información importante
session_id = data.get('sessionId')
status = data['data']['status']
user_name = data['data']['user']['name']
print(f"KYC Completado - Sesión: {session_id}")
print(f"Usuario: {user_name}")
print(f"Estado: {status}")
# Aquí añades tu lógica de negocio
process_kyc_result(data)
return jsonify({"received": True}), 200
except Exception as e:
print(f"Error procesando webhook: {e}")
return jsonify({"error": "Processing failed"}), 500
def process_kyc_result(data):
"""Tu lógica personalizada aquí"""
status = data['data']['status']
if status == "APPROVED":
# Cliente aprobado - activar cuenta, enviar bienvenida, etc.
activate_user_account(data['data']['user'])
elif status == "REJECTED":
# Cliente rechazado - enviar instrucciones, solicitar documentos, etc.
handle_rejection(data['sessionId'])
elif status == "PENDING":
# Revisión manual requerida - notificar equipo de compliance
notify_manual_review(data['sessionId'])
if __name__ == '__main__':
app.run(host='0.0.0.0', port=443, ssl_context='adhoc')
Ejemplo en Node.js (Express)
const express = require('express');
const app = express();
// Tu Auth Key configurada en JAAK
const AUTH_KEY = "JK2024-webhook-Auth-789XYZ";
app.use(express.json());
app.post('/webhook/kyc', (req, res) => {
// Verificar autenticación
const authHeader = req.headers.authorization || '';
if (!authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Missing authorization' });
}
const receivedKey = authHeader.replace('Bearer ', '');
if (receivedKey !== AUTH_KEY) {
return res.status(401).json({ error: 'Invalid auth key' });
}
try {
const data = req.body;
// Extraer información importante
const sessionId = data.sessionId;
const status = data.data.status;
const userName = data.data.user.name;
console.log(`KYC Completado - Sesión: ${sessionId}`);
console.log(`Usuario: ${userName}`);
console.log(`Estado: ${status}`);
// Tu lógica de negocio aquí
processKycResult(data);
res.status(200).json({ received: true });
} catch (error) {
console.error('Error procesando webhook:', error);
res.status(500).json({ error: 'Processing failed' });
}
});
function processKycResult(data) {
const status = data.data.status;
switch(status) {
case 'APPROVED':
// Cliente aprobado
activateUserAccount(data.data.user);
break;
case 'REJECTED':
// Cliente rechazado
handleRejection(data.sessionId);
break;
case 'PENDING':
// Revisión manual
notifyManualReview(data.sessionId);
break;
}
}
app.listen(443, () => {
console.log('Webhook server running on port 443');
});
Ejemplo en PHP
<?php
header('Content-Type: application/json');
// Tu Auth Key configurada en JAAK
$AUTH_KEY = "JK2024-webhook-Auth-789XYZ";
// Verificar método HTTP
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
exit;
}
// Verificar autenticación
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (!str_starts_with($authHeader, 'Bearer ')) {
http_response_code(401);
echo json_encode(['error' => 'Missing authorization']);
exit;
}
$receivedKey = str_replace('Bearer ', '', $authHeader);
if ($receivedKey !== $AUTH_KEY) {
http_response_code(401);
echo json_encode(['error' => 'Invalid auth key']);
exit;
}
// Procesar datos
try {
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if (!$data) {
throw new Exception('Invalid JSON');
}
// Extraer información importante
$sessionId = $data['sessionId'];
$status = $data['data']['status'];
$userName = $data['data']['user']['name'];
error_log("KYC Completado - Sesión: $sessionId");
error_log("Usuario: $userName");
error_log("Estado: $status");
// Tu lógica de negocio aquí
processKycResult($data);
http_response_code(200);
echo json_encode(['received' => true]);
} catch (Exception $e) {
error_log('Error procesando webhook: ' . $e->getMessage());
http_response_code(500);
echo json_encode(['error' => 'Processing failed']);
}
function processKycResult($data) {
$status = $data['data']['status'];
switch($status) {
case 'APPROVED':
// Cliente aprobado
activateUserAccount($data['data']['user']);
break;
case 'REJECTED':
// Cliente rechazado
handleRejection($data['sessionId']);
break;
case 'PENDING':
// Revisión manual
notifyManualReview($data['sessionId']);
break;
}
}
?>
3.3 Requisitos de Respuesta
Respuesta Exitosa
Tu endpoint debe responder con:
HTTP/1.1 200 OK
Content-Type: application/json
{
"received": true
}
Timeout y Reintentos
- Timeout: JAAK esperará máximo 30 segundos por tu respuesta
- Reintentos: Si no respondes con 200 OK, JAAK reintentará:
- 1° reintento: después de 1 minuto
- 2° reintento: después de 5 minutos
- 3° reintento: después de 15 minutos
- Máximo 3 reintentos totales
PASO 4: Probar Funcionamiento
Objetivo
Verificar que tu webhook está funcionando correctamente con una sesión KYC de prueba.
4.1 Preparar Prueba
Checklist Pre-Prueba
- URL webhook configurada en JAAK
- Auth Key configurada en JAAK
- Endpoint implementado y funcionando
- Servidor accesible desde internet (HTTPS)
- Logs habilitados para monitoreo
4.2 Crear Sesión de Prueba
-
Ir a JAAK Dashboard:
KYC → Sesiones → Crear nueva sesión
-
Completar formulario:
- Nombre del contacto: "Test Webhook"
- Nombre del flujo: "Prueba-Webhook-001"
- URL redirección: Tu página de confirmación
- País de documentación: Tu país configurado
- Tipo de flujo: "KYC Tradicional"
-
Guardar y copiar URL: Se generará una URL como
https://sandbox.kyc.jaak.ai/session/ABC123X
4.3 Completar Verificación
- Abrir URL de sesión en navegador
- Seguir proceso KYC:
- Permitir acceso a cámara
- Capturar documento (frente y reverso)
- Capturar selfie/biometría
- Esperar procesamiento
- Monitorear logs de tu servidor durante el proceso
4.4 Verificar Recepción del Webhook
Qué Buscar en tus Logs
Si todo funciona correctamente, deberías ver:
[INFO] POST /webhook/kyc - Autenticación exitosa
[INFO] KYC Completado - Sesión: ABC123X
[INFO] Usuario: Test Webhook
[INFO] Estado: APPROVED
[INFO] Respuesta 200 enviada a JAAK
Si hay problemas, podrías ver:
[ERROR] POST /webhook/kyc - Auth Key inválida
[ERROR] JSON malformado en webhook
[ERROR] Timeout procesando webhook
4.5 Validar en JAAK Dashboard
- Ir a:
KYC → Sesiones
- Buscar tu sesión: "Prueba-Webhook-001"
- Verificar estado: Debe aparecer como completada
- Revisar logs: Si hay errores de webhook, aparecerán aquí
PASO 5: Interpretar Respuestas del Webhook
Objetivo
Entender completamente los datos que recibes en el webhook para implementar la lógica de negocio adecuada.
5.1 Estados Principales
Status de Verificación
Estado | Significado | Acción Recomendada |
---|---|---|
APPROVED | ✅ Verificación exitosa | Activar cuenta, proceder con onboarding |
REJECTED | ❌ Verificación falló | Solicitar reintentar o documentos adicionales |
PENDING | ⏳ Requiere revisión manual | Notificar equipo de compliance |
ERROR | ⚠️ Error técnico durante proceso | Reintentar verificación |
5.2 Campos Importantes del Webhook
Estructura Completa
{
"event": "kyc.session.completed",
"timestamp": "2024-07-14T15:30:45Z",
"sessionId": "ABC123X",
"data": {
"status": "APPROVED",
"confidence": 95.5,
"processingTime": "45.2",
"user": {
"name": "María González Pérez",
"documentNumber": "GONZ900515MDFRNR08",
"dateOfBirth": "1990-05-15",
"nationality": "MEX",
"gender": "F"
},
"document": {
"type": "INE",
"country": "MEX",
"isValid": true,
"expirationDate": "2029-05-15",
"issueDate": "2019-05-15"
},
"validation": {
"documentAuthenticity": "PASS",
"faceMatch": "PASS",
"liveness": "PASS",
"blacklistCheck": "PASS"
},
"scores": {
"documentQuality": 98.2,
"faceMatchScore": 94.7,
"livenessScore": 96.1,
"overallConfidence": 95.5
},
"metadata": {
"ipAddress": "192.168.1.100",
"userAgent": "Mozilla/5.0...",
"deviceType": "mobile",
"location": {
"country": "MX",
"region": "CDMX",
"city": "Mexico City"
}
}
}
}
Explicación de Campos
Información del Usuario:
user.name
: Nombre extraído del documentouser.documentNumber
: Número de identificación oficialuser.dateOfBirth
: Fecha de nacimientouser.nationality
: Nacionalidad (código ISO)user.gender
: Género (M/F)
Información del Documento:
document.type
: Tipo de documento (INE, passport, etc.)document.country
: País emisordocument.isValid
: Si el documento es válido/vigentedocument.expirationDate
: Fecha de vencimiento
Resultados de Validación:
validation.documentAuthenticity
: Autenticidad del documentovalidation.faceMatch
: Coincidencia facial con foto del documentovalidation.liveness
: Prueba de vida (no es foto/video)validation.blacklistCheck
: Verificación en listas restrictivas
Puntuaciones de Confianza:
scores.documentQuality
: Calidad de imagen del documento (0-100)scores.faceMatchScore
: Precisión de coincidencia facial (0-100)scores.livenessScore
: Confianza en prueba de vida (0-100)scores.overallConfidence
: Confianza general del sistema (0-100)
5.3 Lógica de Negocio Recomendada
Flujo de Decisión
def process_kyc_webhook(data):
status = data['data']['status']
confidence = data['data']['confidence']
validations = data['data']['validation']
if status == "APPROVED":
if confidence >= 90:
# Alta confianza - aprobación automática
auto_approve_user(data)
elif confidence >= 70:
# Confianza media - aprobación con monitoreo
approve_with_monitoring(data)
else:
# Baja confianza - revisión manual
queue_for_manual_review(data)
elif status == "REJECTED":
# Analizar razones específicas
if validations['liveness'] == "FAIL":
request_retry_with_instructions(data, "liveness")
elif validations['documentAuthenticity'] == "FAIL":
request_different_document(data)
else:
manual_review_required(data)
elif status == "PENDING":
# Siempre requiere revisión manual
notify_compliance_team(data)
elif status == "ERROR":
# Error técnico - permitir reintento
send_retry_notification(data)
5.4 Casos Especiales
Situaciones a Considerar
Alta Confianza pero Validación Fallida:
{
"confidence": 95.0,
"validation": {
"documentAuthenticity": "PASS",
"faceMatch": "FAIL",
"liveness": "PASS"
}
}
Acción: Revisar manualmente - posible documento legítimo pero persona diferente.
Baja Confianza pero Validaciones Exitosas:
{
"confidence": 65.0,
"validation": {
"documentAuthenticity": "PASS",
"faceMatch": "PASS",
"liveness": "PASS"
}
}
Acción: Aprobar con monitoreo adicional - posible problema de calidad de imagen.
Metadatos Sospechosos:
{
"metadata": {
"ipAddress": "192.168.1.100",
"location": {
"country": "RU" // País diferente al esperado
}
}
}
Acción: Activar verificaciones adicionales por ubicación geográfica inusual.
Solución de Problemas Comunes
Problemas Frecuentes
Webhook no se recibe
Problema | Causa Probable | Solución |
---|---|---|
No llegan peticiones | URL incorrecta en JAAK | Verificar configuración en "Mi Compañía" |
Error 404/502 | Endpoint no existe o servidor caído | Verificar que tu servidor está funcionando |
Error SSL/TLS | Certificado inválido | Usar HTTPS válido o renovar certificado |
Timeout | Respuesta lenta del servidor | Optimizar procesamiento, responder rápido |
Errores de autenticación
Error | Descripción | Solución |
---|---|---|
"Missing authorization" | No se envía header Authorization | Verificar implementación del endpoint |
"Invalid auth key" | Auth Key no coincide | Revisar Auth Key en configuración JAAK |
Constante error 401 | Auth Key mal configurada | Regenerar Auth Key en JAAK |
Problemas de procesamiento
Síntoma | Causa | Fix |
---|---|---|
JSON malformado | Error al parsear datos | Añadir manejo de errores robusto |
Datos faltantes | Cambios en estructura | Verificar campos antes de usar |
Timeout al procesar | Lógica muy lenta | Mover procesamiento pesado a background |
Debugging Avanzado
Logs Detallados
import logging
import json
logging.basicConfig(level=logging.DEBUG)
@app.route('/webhook/kyc', methods=['POST'])
def webhook_kyc():
logger = logging.getLogger(__name__)
# Log headers completos
logger.debug(f"Headers recibidos: {dict(request.headers)}")
# Log body raw
raw_data = request.get_data()
logger.debug(f"Body raw: {raw_data}")
# Log IP origen
logger.debug(f"IP origen: {request.remote_addr}")
try:
data = request.get_json()
logger.info(f"Webhook procesado: {data.get('sessionId')}")
# Log estructura de datos
logger.debug(f"Estructura completa: {json.dumps(data, indent=2)}")
return jsonify({"received": True}), 200
except Exception as e:
logger.error(f"Error procesando webhook: {str(e)}", exc_info=True)
return jsonify({"error": str(e)}), 500
Webhook de Prueba
Para probar tu endpoint sin hacer una sesión KYC completa:
curl -X POST https://tu-servidor.com/webhook/kyc \
-H "Content-Type: application/json" \
-H "Authorization: Bearer JK2024-webhook-Auth-789XYZ" \
-d '{
"event": "kyc.session.completed",
"timestamp": "2024-07-14T15:30:45Z",
"sessionId": "TEST123",
"data": {
"status": "APPROVED",
"confidence": 95.5,
"user": {
"name": "Test User",
"documentNumber": "TEST123456789",
"dateOfBirth": "1990-01-01",
"nationality": "MEX"
}
}
}'
¿Necesitas Ayuda Adicional?
Cuándo contactar soporte técnico
- Errores de configuración que no puedes resolver
- Problemas de conectividad persistentes
- Cambios en la estructura de datos del webhook
- Preguntas sobre integración con sistemas específicos
Información a tener lista al contactar soporte
- URL de tu webhook configurada
- Logs de errores específicos con timestamps
- Ejemplo de petición que está fallando
- Configuración de ambiente (desarrollo/producción)
- ShortKey de sesión problemática (si aplica)
Recursos Adicionales
- Documentación API JAAK: Para integraciones más avanzadas
- Postman Collection: Para probar endpoints manualmente
- SDK/Libraries: Si están disponibles para tu lenguaje
- Status Page: Para verificar el estado del servicio JAAK
Resumen Final
Has Aprendido A:
- Configurar URL webhook y Auth Key en JAAK
- Implementar endpoint para recibir datos
- Procesar y validar información del webhook
- Manejar diferentes estados de verificación
- Solucionar problemas comunes
- Implementar lógica de negocio basada en resultados
Próximos Pasos Recomendados
- Configurar monitoreo: Logs, alertas, métricas
- Implementar retry logic: Para el procesamiento de webhooks
- Añadir validaciones adicionales: Según tus reglas de negocio
- Documentar proceso: Para tu equipo y futuras referencias
- Probar en producción: Con volúmenes reales de transacciones
¡Felicidades! Ya tienes un sistema completo de webhooks para KYC funcionando. Tu sistema ahora puede recibir y procesar automáticamente los resultados de todas las verificaciones de identidad realizadas en JAAK.
Updated 2 days ago