JAAK KYC Mosaic Web
1. Introducción
JAAK KYC Mosaic Web es una solución completa de verificación de identidad que permite integrar procesos de KYC (Know Your Customer) en aplicaciones web de manera rápida y segura. Esta guía está diseñada para ayudarle a elegir e implementar la modalidad de integración que mejor se adapte a sus necesidades.
¿Qué es JAAK KYC Mosaic?
JAAK KYC Mosaic es una plataforma de verificación de identidad que ofrece:
- Extracción automática de datos de documentos de identidad
- Verificación de autenticidad de documentos
- Verificación de identidad facial en vivo
- Comparación facial One-to-One (OTO)
- Verificación contra listas negras
Beneficios principales
- Integración flexible: 3 modalidades para diferentes casos de uso
- Implementación rápida: Desde minutos hasta horas según la modalidad
- Alta precisión: 99% de exactitud en verificaciones
- Seguridad robusta: Autenticación con API Keys y comunicación HTTPS
- Soporte completo: Documentación detallada y equipo de soporte técnico
2. Modalidades de Integración
JAAK KYC Mosaic ofrece tres modalidades de integración para adaptarse a diferentes necesidades y casos de uso. A continuación se presenta una comparación para ayudarle a elegir la mejor opción:
| Modalidad | Casos de Uso | Complejidad |
|---|---|---|
| Embed (iframe) | Integración rápida sin salir del sitio. Control total del layout. | ⭐⭐ Media |
| Direct (nueva pestaña) | Experiencia pantalla completa. Apps móviles nativas. | ⭐⭐ Media |
| Link (URLs) | Campañas email/SMS. Enlaces compartidos. Cero código. | ⭐ Baja |
2.1 Modalidad Embed (iframe)
La modalidad Embed integra el flujo KYC completo dentro de un iframe en su página web, manteniendo al usuario en su dominio durante todo el proceso.
Ventajas:
- Integración rápida (minutos a horas)
- Usuario permanece en su sitio web
- Comunicación bidireccional en tiempo real
- Control total del posicionamiento y diseño
Cuándo usar Embed:
- Necesita mantener al usuario en su dominio
- Requiere control del flujo de usuario
- Quiere personalizar el contenedor del iframe
2.2 Modalidad Direct (nueva pestaña)
La modalidad Direct abre el flujo KYC en una ventana separada o nueva pestaña, ofreciendo una experiencia de pantalla completa optimizada.
Ventajas:
- Máximo rendimiento (sin overhead de iframe)
- Experiencia de usuario fluida
- Perfecto para aplicaciones móviles (WebView)
- Soporte completo de todos los pasos KYC
Cuándo usar Direct:
- Necesita máximo rendimiento
- Integra en aplicaciones móviles nativas
- Prefiere flujo independiente sin embedding
2.3 Modalidad Link (URLs)
La modalidad Link permite generar URLs autocontenidas que incluyen toda la configuración necesaria. Es la opción más simple y no requiere código del lado del cliente.
Ventajas:
- Cero código del lado del cliente
- Perfecto para campañas de email/SMS
- URLs compartibles y autocontenidas
- Implementación inmediata
Cuándo usar Link:
- Campañas automatizadas de verificación
- Envío de enlaces por email, SMS o WhatsApp
- Códigos QR para verificación
- No tiene recursos de desarrollo
3. Prerrequisitos
3.1 Requisitos técnicos
| Requisito | Especificación |
|---|---|
| Navegador | Chrome 80+, Firefox 75+, Safari 13+, Edge 80+ |
| HTTPS | Obligatorio en producción (requerido para cámara) |
| JavaScript | ES6+ (para Embed y Direct) |
| API Key | Proporcionada por JAAK (requerida para crear sesiones) |
| Short Key | Generado automáticamente al crear sesión |
3.2 Obtener su API Key
La API Key es un token de autenticación único que permite a su aplicación crear sesiones de verificación en JAAK KYC.
Pasos para obtener su API Key:
-
Acceda a su Dashboard de JAAK
- Visite https://dashboard.jaak.ai
- Inicie sesión con sus credenciales
-
Navegue a la sección de API
- En el menú lateral, seleccione "API Keys" o "Configuración"
- Encontrará su API Key en la sección de credenciales
-
Copie su API Key
- Haga clic en "Copiar" o seleccione el token completo
- Guárdelo en un lugar seguro
⚠️ Importante sobre seguridad:
- Mantenga su API Key segura y nunca la exponga en código del lado del cliente
- No la comparta públicamente ni la incluya en repositorios de código abierto
- Use variables de entorno para almacenarla
- Rote sus claves periódicamente para mayor seguridad
- La API Key debe usarse únicamente en su backend
4. Autenticación
Todas las llamadas a la API de JAAK requieren autenticación mediante un Bearer Token que se incluye en el header Authorization.
Formato de autenticación
Authorization: Bearer YOUR_API_KEYEjemplo de header completo
POST /api/v1/kyc/flow HTTP/1.1
Host: sandbox.kyc.jaak.ai
Content-Type: application/json
Authorization: Bearer sk_test_abc123xyz456def789...Ambientes disponibles
| Ambiente | URL Base | Uso |
|---|---|---|
| Sandbox | https://sandbox.kyc.jaak.ai | Desarrollo y pruebas |
| Producción | https://kyc.jaak.ai | Aplicaciones en vivo |
⚠️ Importante: Siempre pruebe en ambiente Sandbox antes de migrar a producción.
5. Proceso para Crear una Sesión KYC
El flujo para iniciar una verificación KYC consta de los siguientes pasos:
Paso 1: Crear Sesión KYC
Inicializa una nueva sesión de verificación para un cliente desde su backend.
Endpoint
POST /api/v1/kyc/flow
Headers requeridos
Content-Type: application/json
Authorization: Bearer YOUR_API_KEYRequest Body
{
"name": "María González Pérez",
"flow": "Cliente-001-Onboarding",
"redirectUrl": "https://tu-empresa.com/kyc-completado",
"countryDocument": "MEX",
"flowType": "KYC",
"verificationType": "email",
"verification": {
"SMS": "",
"EMAIL": "[email protected]",
"WHATSAPP": ""
}
}Parámetros detallados
| Campo | Tipo | Requerido | Descripción | Ejemplo |
|---|---|---|---|---|
name | string | ✅ | Nombre completo del cliente | "María González Pérez" |
flow | string | ✅ | Identificador único de la sesión | "Cliente-001-Onboarding" |
redirectUrl | string | ❌ | URL donde redirigir al finalizar | "https://tu-empresa.com/success" |
countryDocument | string | ✅ | País del documento (código Alpha-3) | "MEX", "USA", "COL" |
flowType | string | ✅ | Tipo de verificación | "KYC" |
verificationType | string | ❌ | Método de notificación | "email", "whatsapp", "sms", "" |
verification | object | ❌ | Datos de contacto según método elegido | Ver opciones abajo |
Opciones de notificación
| Método | Campo requerido | Formato | Ejemplo |
|---|---|---|---|
verification.EMAIL | email válido | "[email protected]" | |
verification.WHATSAPP | +[código país][número] | "+525551234567" | |
| SMS | verification.SMS | +[código país][número] | "+525551234567" |
| Manual | Dejar verificationType vacío | - | - |
Response esperado
{
"sessionUrl": "https://sandbox.kyc.jaak.ai/session/ABC123X"
}💡 Nota: El shortKey se extrae de la URL de sesión: ABC123X (últimos 7 caracteres)
Ejemplo completo con cURL
curl -X POST https://sandbox.kyc.jaak.ai/api/v1/kyc/flow \
-H "Authorization: Bearer sk_test_abc123xyz456..." \
-H "Content-Type: application/json" \
-d '{
"name": "María González Pérez",
"flow": "Cliente-001-Onboarding",
"redirectUrl": "https://tu-empresa.com/kyc-completado",
"countryDocument": "MEX",
"flowType": "KYC",
"verificationType": "email",
"verification": {
"SMS": "",
"EMAIL": "[email protected]",
"WHATSAPP": ""
}
}'Ejemplo con JavaScript (Node.js)
async function createKYCSession(clientData) {
try {
const response = await fetch('https://sandbox.kyc.jaak.ai/api/v1/kyc/flow', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.JAAK_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: clientData.name,
flow: clientData.flow,
redirectUrl: clientData.redirectUrl,
countryDocument: 'MEX',
flowType: 'KYC',
verificationType: 'email',
verification: {
SMS: '',
EMAIL: clientData.email,
WHATSAPP: ''
}
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Error creating KYC session:', error);
throw error;
}
}
// Uso
const sessionData = await createKYCSession({
name: 'María González Pérez',
flow: 'Cliente-001-Onboarding',
email: '[email protected]',
redirectUrl: 'https://tu-empresa.com/kyc-completado'
});
console.log('Session URL:', sessionData.sessionUrl);Paso 2: Extraer el ShortKey
El shortKey es el identificador de 7 caracteres que se encuentra al final de la URL de sesión.
Ejemplo de extracción
URL de sesión: https://sandbox.kyc.jaak.ai/session/ABC123X
↑
ShortKey: ABC123X
Función de extracción en JavaScript
function extractShortKey(sessionUrl) {
// sessionUrl: "https://sandbox.kyc.jaak.ai/session/ABC123X"
const parts = sessionUrl.split('/');
return parts[parts.length - 1]; // "ABC123X"
}
// Uso
const sessionUrl = "https://sandbox.kyc.jaak.ai/session/ABC123X";
const shortKey = extractShortKey(sessionUrl);
console.log(shortKey); // "ABC123X"📌 Nota importante: El shortKey se genera automáticamente y no es personalizable.
Paso 3: Configurar el flujo KYC
Define qué pasos de verificación quieres incluir en tu flujo personalizado utilizando el shortKey obtenido.
Configuración para modalidades Embed y Direct
const config = {
steps: [
{ key: 'DOCUMENT_EXTRACT' },
{ key: 'DOCUMENT_VERIFY' },
{ key: 'IVERIFICATION' }
],
shortKey: 'ABC123X' // El shortKey obtenido en el paso 2
};Configuración para modalidad Link
Formato de URL con pasos:
https://mosaic.sandbox.jaak.ai/link?shortKey=ABC123X&steps=DOCUMENT_EXTRACT,DOCUMENT_VERIFY,IVERIFICATION
Parámetros de URL:
shortKey: Tu código de sesión (requerido)steps: Pasos separados por comas en orden de ejecuciónredirectUrl: URL donde redirigir al completar (opcional)
Ejemplo completo de URL
https://mosaic.sandbox.jaak.ai/link?shortKey=ABC123X&steps=DOCUMENT_EXTRACT,DOCUMENT_VERIFY,IVERIFICATION,OTO&redirectUrl=https://mi-app.com/success
Flujo completo de integración (ejemplo práctico)
// ====================================
// BACKEND: Crear sesión y obtener shortKey
// ====================================
async function initializeKYCSession(userData) {
// Paso 1: Crear sesión en el backend
const session = await fetch('https://sandbox.kyc.jaak.ai/api/v1/kyc/flow', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.JAAK_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: userData.name,
flow: `user-${userData.id}-${Date.now()}`,
redirectUrl: 'https://tu-empresa.com/kyc-success',
countryDocument: 'MEX',
flowType: 'KYC',
verificationType: 'email',
verification: {
SMS: '',
EMAIL: userData.email,
WHATSAPP: ''
}
})
});
const data = await session.json();
// Paso 2: Extraer shortKey de la URL
const shortKey = extractShortKey(data.sessionUrl);
return { shortKey, sessionUrl: data.sessionUrl };
}
function extractShortKey(sessionUrl) {
const parts = sessionUrl.split('/');
return parts[parts.length - 1];
}
// ====================================
// FRONTEND: Usar shortKey en tu integración
// ====================================
async function startKYCVerification(userId, userName, userEmail) {
try {
// Llamar a tu backend para crear sesión
const response = await fetch('/api/kyc/create-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: userId,
name: userName,
email: userEmail
})
});
const { shortKey } = await response.json();
// Opción A: Usar con Embed (iframe)
const embedConfig = {
steps: [
{ key: 'DOCUMENT_EXTRACT' },
{ key: 'DOCUMENT_VERIFY' },
{ key: 'IVERIFICATION' }
],
shortKey: shortKey
};
document.getElementById('kycMosaic').contentWindow.postMessage({
type: 'CONFIG',
data: embedConfig
}, '*');
// Opción B: Generar Link para campaña
const kycLink = `https://mosaic.sandbox.jaak.ai/link?shortKey=${shortKey}&steps=DOCUMENT_EXTRACT,DOCUMENT_VERIFY,IVERIFICATION`;
console.log('Link de verificación:', kycLink);
// Opción C: Abrir en Direct mode
const directUrl = `https://mosaic.sandbox.jaak.ai/direct`;
const directWindow = window.open(directUrl, 'kyc', 'width=800,height=600');
// Esperar señal READY y enviar config
window.addEventListener('message', function(event) {
if (event.data.type === 'READY' && directWindow) {
directWindow.postMessage({
type: 'CONFIG',
data: embedConfig
}, '*');
}
});
} catch (error) {
console.error('Error al iniciar KYC:', error);
alert('No se pudo iniciar la verificación. Intente nuevamente.');
}
}6. Pasos del Flujo KYC
JAAK KYC Mosaic ofrece diferentes pasos que puede configurar según sus necesidades. Los pasos se ejecutan en el orden que usted especifique.
| Paso | Descripción |
|---|---|
WELCOME | Pantalla de bienvenida con instrucciones |
DOCUMENT_EXTRACT | Captura y extracción de datos del documento de identidad |
DOCUMENT_VERIFY | Verificación de autenticidad del documento |
BLACKLIST | Verificación contra listas negras de seguridad |
IVERIFICATION | Verificación de identidad facial en vivo (liveness) |
LOCATION_PERMISSIONS | Solicitud de permisos de geolocalización |
OTO | Comparación facial One-to-One (documento vs. rostro en vivo) |
FINISH | Pantalla de finalización exitosa |
⚠️ Importante: El paso OTO requiere que se hayan ejecutado previamente DOCUMENT_EXTRACT (para la foto del documento) e IVERIFICATION (para la foto en vivo). Si estos pasos se ejecutaron en sesiones anteriores, Mosaic obtiene las imágenes automáticamente.
Ejemplo de configuración de pasos
const config = {
steps: [
{ key: 'WELCOME' },
{ key: 'DOCUMENT_EXTRACT' },
{ key: 'DOCUMENT_VERIFY' },
{ key: 'IVERIFICATION' },
{ key: 'OTO' },
{ key: 'FINISH' }
],
shortKey: 'ABC123X'
};7. Guías de Implementación
7.1 Implementación Embed (iframe)
Paso 1: Agregar el iframe a su página
<iframe
id="kycMosaic"
src="https://mosaic.sandbox.jaak.ai/"
width="100%"
height="600"
allow="camera; geolocation">
</iframe>Paso 2: Configurar y enviar configuración
const config = {
steps: [
{ key: 'DOCUMENT_EXTRACT' },
{ key: 'DOCUMENT_VERIFY' },
{ key: 'IVERIFICATION' }
],
shortKey: 'ABC123X' // shortKey obtenido de la API
};
document.getElementById('kycMosaic')
.contentWindow.postMessage({
type: 'CONFIG',
data: config
}, '*');Paso 3: Escuchar eventos
window.addEventListener('message', function(event) {
switch(event.data.type) {
case 'FLOW_COMPLETE':
console.log('KYC completado', event.data);
// Procesar resultados
break;
case 'ERROR':
console.error('Error', event.data);
// Manejar error
break;
}
});7.2 Implementación Direct (nueva pestaña)
Paso 1: Abrir ventana Direct
let directWindow = null;
function openDirectKYC() {
const url = 'https://mosaic.sandbox.jaak.ai/direct';
const features = 'width=800,height=600';
directWindow = window.open(url, 'kyc', features);
}Paso 2: Esperar señal READY y enviar configuración
window.addEventListener('message', function(event) {
if (event.data.type === 'READY') {
const config = {
steps: [
{ key: 'DOCUMENT_EXTRACT' },
{ key: 'IVERIFICATION' }
],
shortKey: 'ABC123X' // shortKey obtenido de la API
};
directWindow.postMessage({
type: 'CONFIG',
data: config
}, '*');
}
});Paso 3: Manejar eventos
window.addEventListener('message', function(event) {
switch(event.data.type) {
case 'FLOW_COMPLETE':
console.log('KYC completado en Direct', event.data);
break;
case 'ERROR':
console.error('Error en Direct', event.data);
break;
}
});7.3 Implementación Link (URLs)
La modalidad Link es la más simple: solo necesita generar una URL con los parámetros adecuados.
Formato de URL
https://mosaic.sandbox.jaak.ai/link?shortKey=ABC123X&steps=DOCUMENT_EXTRACT,IVERIFICATION
Parámetros disponibles
| Parámetro | Descripción |
|---|---|
shortKey | Su código de sesión (requerido) |
steps | Pasos separados por comas en orden de ejecución |
redirectUrl | URL donde redirigir al completar (opcional) |
Ejemplo completo
https://mosaic.sandbox.jaak.ai/link?shortKey=ABC123X&steps=DOCUMENT_EXTRACT,DOCUMENT_VERIFY,IVERIFICATION,OTO&redirectUrl=https://mi-app.com/success
Generación programática
function generateKYCLink(shortKey, steps, redirectUrl) {
const baseUrl = 'https://mosaic.sandbox.jaak.ai/link';
const params = new URLSearchParams({
shortKey: shortKey,
steps: steps.join(',')
});
if (redirectUrl) {
params.append('redirectUrl', redirectUrl);
}
return `${baseUrl}?${params.toString()}`;
}
// Uso
const link = generateKYCLink(
'ABC123X',
['DOCUMENT_EXTRACT', 'IVERIFICATION', 'OTO'],
'https://mi-app.com/success'
);
console.log(link);8. Eventos y Respuestas
Las modalidades Embed y Direct envían eventos mediante postMessage para informar sobre el progreso del flujo KYC.
8.1 Eventos principales
| Evento | Descripción |
|---|---|
READY | Mosaic está listo para recibir configuración |
STEP_COMPLETE | Un paso individual fue completado exitosamente |
FLOW_COMPLETE | El flujo KYC completo fue finalizado exitosamente |
ERROR | Ocurrió un error durante el proceso |
SESSION_EXPIRED | La sesión expiró por inactividad (14 minutos) |
8.2 Ejemplo de manejo de eventos
window.addEventListener('message', function(event) {
const message = event.data;
switch(message.type) {
case 'READY':
console.log('Mosaic listo');
// Enviar configuración
break;
case 'STEP_COMPLETE':
console.log('Paso completado:', message.data.stepKey);
console.log('Datos del paso:', message.data.data);
// Guardar datos del paso si es necesario
break;
case 'FLOW_COMPLETE':
console.log('KYC completado exitosamente');
console.log('Datos finales:', message.data);
// Procesar resultados finales
break;
case 'ERROR':
console.error('Error en KYC:', message.data.error);
console.error('Mensaje:', message.data.message);
// Mostrar mensaje de error al usuario
break;
case 'SESSION_EXPIRED':
console.warn('Sesión expirada');
// Reiniciar flujo o mostrar mensaje
break;
}
});Estructura de datos en eventos
STEP_COMPLETE
{
type: 'STEP_COMPLETE',
data: {
stepKey: 'DOCUMENT_EXTRACT',
data: {
face: 'data:image/jpeg;base64,...'
// Datos específicos del paso
}
}
}FLOW_COMPLETE
{
type: 'FLOW_COMPLETE',
data: {
completedSteps: ['DOCUMENT_EXTRACT', 'IVERIFICATION', 'OTO'],
allData: {
DOCUMENT_EXTRACT: { /* datos */ },
IVERIFICATION: { /* datos */ },
OTO: { /* datos */ }
}
}
}ERROR
{
type: 'ERROR',
data: {
error: 'AUTHENTICATION_FAILED',
message: 'Invalid shortKey provided'
}
}9. Solución de Problemas
9.1 Problemas comunes
El iframe no carga
Soluciones:
- Verifique que el atributo
allowincluyacameraygeolocation - Confirme que está usando HTTPS en producción
- Revise la consola del navegador para errores CORS
<!-- Configuración correcta del iframe -->
<iframe
id="kycMosaic"
src="https://mosaic.sandbox.jaak.ai/"
allow="camera; geolocation"
width="100%"
height="600">
</iframe>Error de autenticación
Posibles causas y soluciones:
- API Key incorrecta: Verifique que su API Key sea correcta y esté actualizada
- API Key expirada: Contacte a soporte si su API Key ha expirado
- ShortKey inválido: Asegúrese de extraer correctamente el shortKey de la URL de sesión
- Ambiente incorrecto: Verifique que esté usando las URLs correctas (sandbox vs producción)
// Verificar que la API Key esté correctamente configurada
const API_KEY = process.env.JAAK_API_KEY;
if (!API_KEY || API_KEY.trim() === '') {
console.error('API Key no configurada');
}OTO falla por imágenes faltantes
Soluciones:
- Asegúrese de ejecutar
DOCUMENT_EXTRACTantes deOTO - Asegúrese de ejecutar
IVERIFICATIONantes deOTO - Alternativamente, proporcione las imágenes manualmente:
const config = {
steps: [
{
key: 'OTO',
data: {
face: 'data:image/jpeg;base64,...', // Imagen del documento
bestFrame: 'data:image/jpeg;base64,...' // Imagen de liveness
}
}
],
shortKey: 'ABC123X'
};Ventana Direct bloqueada
Soluciones:
- Asegúrese de que la apertura ocurra por interacción del usuario (click)
- Verifique la configuración del bloqueador de popups
- Agregue instrucciones al usuario para permitir popups
// Buena práctica: abrir desde un evento de click
button.addEventListener('click', function() {
openDirectKYC();
});PostMessage no funciona
Soluciones:
- Verifique que está escuchando eventos en la ventana correcta
- Confirme que el origen del mensaje es el esperado
- Revise la consola para mensajes de error
window.addEventListener('message', function(event) {
// Validar origen en producción
// if (event.origin !== 'https://mosaic.jaak.ai') return;
console.log('Mensaje recibido:', event.data);
});9.2 Sesión expirada
Las sesiones de JAAK KYC Mosaic expiran después de 14 minutos de inactividad. Cuando esto ocurre:
- Se envía un evento
SESSION_EXPIRED - Se muestra un mensaje al usuario en la interfaz
- Puede reiniciar el flujo enviando una nueva configuración
Manejo recomendado
window.addEventListener('message', function(event) {
if (event.data.type === 'SESSION_EXPIRED') {
console.warn('Sesión expirada');
// Opción 1: Reiniciar automáticamente
setTimeout(() => {
sendConfiguration();
}, 2000);
// Opción 2: Mostrar mensaje y esperar acción del usuario
// showModal('Su sesión ha expirado. ¿Desea reiniciar?');
}
});💡 Recomendación: Implemente un reinicio automático del flujo al recibir SESSION_EXPIRED para mejorar la experiencia del usuario.
10. Mejores Prácticas
10.1 Seguridad
Proteja su API Key
- ❌ NUNCA la incluya en código del lado del cliente
- ✅ Use variables de entorno o servicios de backend
- ✅ Rote las claves periódicamente
- ✅ Almacénela en gestores de secretos (AWS Secrets Manager, Azure Key Vault, etc.)
// ❌ MAL - API Key expuesta en frontend
const apiKey = 'sk_live_abc123xyz456...';
// ✅ BIEN - API Key en backend con variable de entorno
const apiKey = process.env.JAAK_API_KEY;Valide el origen de mensajes (producción)
window.addEventListener('message', function(event) {
// Validar origen en producción
if (event.origin !== 'https://mosaic.jaak.ai') {
console.warn('Mensaje de origen no confiable');
return;
}
// Procesar mensaje
});Use HTTPS siempre
- Obligatorio para acceso a cámara
- Protege la transmisión de datos sensibles
- Requerido por navegadores modernos
10.2 Experiencia de Usuario
Proporcione instrucciones claras
- Explique qué documentos se necesitan
- Indique los pasos del proceso
- Muestre tiempo estimado de completación
Manejo de errores amigable
function handleKYCError(error) {
const friendlyMessages = {
'AUTHENTICATION_FAILED': 'No pudimos verificar su sesión. Por favor intente nuevamente.',
'CAMERA_ACCESS_DENIED': 'Necesitamos acceso a su cámara para continuar.',
'DOCUMENT_NOT_DETECTED': 'No pudimos detectar el documento. Por favor intente de nuevo.',
'SESSION_EXPIRED': 'Su sesión ha expirado. Por favor reinicie el proceso.'
};
const message = friendlyMessages[error.error] || 'Ocurrió un error. Por favor intente nuevamente.';
showUserMessage(message);
}Indicadores de progreso
window.addEventListener('message', function(event) {
if (event.data.type === 'STEP_COMPLETE') {
updateProgressBar(event.data.stepKey);
}
});10.3 Rendimiento
Precargue el iframe (Embed)
<!-- Precargar en el head -->
<link rel="preconnect" href="https://mosaic.sandbox.jaak.ai">Maneje timeout de carga
let iframeLoaded = false;
setTimeout(() => {
if (!iframeLoaded) {
showError('El servicio está tardando más de lo usual. Por favor recargue la página.');
}
}, 10000); // 10 segundos10.4 Testing
Ambiente de pruebas
- Use
https://mosaic.sandbox.jaak.ai/para pruebas - Solicite API Keys de prueba separadas
- Pruebe todos los flujos antes de producción
Casos de prueba recomendados
- ✅ Flujo completo exitoso
- ✅ Cancelación por usuario
- ✅ Pérdida de conexión
- ✅ Timeout de sesión
- ✅ Diferentes navegadores y dispositivos
- ✅ Errores de validación de documentos
11. Migración a Producción
11.1 Checklist pre-producción
- API Key de producción obtenida
- URL actualizada a
https://mosaic.jaak.ai/ - HTTPS configurado en su dominio
- Validación de origen implementada
- Manejo de errores completo
- Testing en navegadores principales
- Testing en dispositivos móviles
- Documentación de integración revisada
- Plan de rollback preparado
- Monitoreo y logs configurados
11.2 Configuración de producción
// Configuración de producción recomendada
const PRODUCTION_CONFIG = {
mosaicUrl: 'https://mosaic.jaak.ai/',
apiUrl: 'https://kyc.jaak.ai/api/v1',
apiKey: process.env.JAAK_API_KEY_PROD,
allowedOrigins: ['https://mosaic.jaak.ai'],
timeout: 900000, // 15 minutos
retryAttempts: 3
};
// Uso seguro en producción
function initKYC() {
if (!PRODUCTION_CONFIG.apiKey) {
console.error('API Key no configurada');
return;
}
// Continuar con inicialización...
}12. Ejemplos de Casos de Uso
Caso 1: Onboarding de clientes (Embed)
<!DOCTYPE html>
<html>
<head>
<title>Onboarding - Mi App</title>
<style>
#kycContainer {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
</style>
</head>
<body>
<div id="kycContainer">
<h1>Verificación de Identidad</h1>
<p>Complete el proceso de verificación para activar su cuenta</p>
<iframe
id="kycMosaic"
src="https://mosaic.sandbox.jaak.ai/"
width="100%"
height="600"
allow="camera; geolocation">
</iframe>
</div>
<script>
// Obtener shortKey desde el backend
async function getShortKey() {
const response = await fetch('/api/kyc/create-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: 'user123',
name: 'Juan Pérez',
email: '[email protected]'
})
});
const data = await response.json();
return data.shortKey;
}
// Configurar KYC
async function initializeKYC() {
const shortKey = await getShortKey();
const config = {
steps: [
{ key: 'WELCOME' },
{ key: 'DOCUMENT_EXTRACT' },
{ key: 'DOCUMENT_VERIFY' },
{ key: 'IVERIFICATION' },
{ key: 'OTO' }
],
shortKey: shortKey
};
setTimeout(() => {
document.getElementById('kycMosaic')
.contentWindow.postMessage({
type: 'CONFIG',
data: config
}, '*');
}, 1000);
}
// Manejar eventos
window.addEventListener('message', function(event) {
if (event.data.type === 'FLOW_COMPLETE') {
window.location.href = '/dashboard?verified=true';
}
});
// Iniciar cuando cargue la página
window.addEventListener('load', initializeKYC);
</script>
</body>
</html>Caso 2: Verificación móvil (Direct)
class KYCVerification {
constructor(apiEndpoint) {
this.apiEndpoint = apiEndpoint;
this.directWindow = null;
this.setupMessageListener();
}
setupMessageListener() {
window.addEventListener('message', (event) => {
this.handleMessage(event.data);
});
}
async open(userId, userName, userEmail) {
try {
// Obtener shortKey del backend
const shortKey = await this.getShortKey(userId, userName, userEmail);
const url = 'https://mosaic.sandbox.jaak.ai/direct';
const features = 'width=800,height=600,scrollbars=yes,resizable=yes';
this.directWindow = window.open(url, 'kycVerification', features);
if (!this.directWindow) {
alert('Por favor permita ventanas emergentes para continuar');
return false;
}
this.shortKey = shortKey;
return true;
} catch (error) {
console.error('Error al abrir KYC:', error);
return false;
}
}
async getShortKey(userId, userName, userEmail) {
const response = await fetch(`${this.apiEndpoint}/create-session`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: userId,
name: userName,
email: userEmail
})
});
const data = await response.json();
return data.shortKey;
}
handleMessage(message) {
switch(message.type) {
case 'READY':
this.sendConfiguration();
break;
case 'FLOW_COMPLETE':
this.onComplete(message.data);
break;
case 'ERROR':
this.onError(message.data);
break;
}
}
sendConfiguration() {
if (this.directWindow && !this.directWindow.closed) {
this.directWindow.postMessage({
type: 'CONFIG',
data: {
steps: [
{ key: 'DOCUMENT_EXTRACT' },
{ key: 'IVERIFICATION' },
{ key: 'OTO' }
],
shortKey: this.shortKey
}
}, '*');
}
}
onComplete(data) {
console.log('Verificación completada', data);
this.saveResults(data);
}
onError(error) {
console.error('Error en verificación', error);
alert('Hubo un error en la verificación. Por favor intente nuevamente.');
}
async saveResults(data) {
try {
const response = await fetch(`${this.apiEndpoint}/save-results`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (response.ok) {
window.location.href = '/verification-success';
}
} catch (error) {
console.error('Error guardando resultados', error);
}
}
}
// Uso
const kycBtn = document.getElementById('startKYC');
kycBtn.addEventListener('click', async function() {
const kyc = new KYCVerification('/api/kyc');
await kyc.open('user456', 'María González', '[email protected]');
});Caso 3: Campaña de email (Link)
// Script backend para generar enlaces de campaña
async function generateCampaignLinks(campaign, recipients) {
const baseUrl = 'https://mosaic.sandbox.jaak.ai/link';
const links = await Promise.all(
recipients.map(async (recipient) => {
// Crear sesión para cada destinatario
const session = await fetch('https://sandbox.kyc.jaak.ai/api/v1/kyc/flow', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.JAAK_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: recipient.name,
flow: `${campaign.id}-${recipient.id}`,
redirectUrl: `https://mi-app.com/campaign-complete?user=${recipient.id}&campaign=${campaign.id}`,
countryDocument: 'MEX',
flowType: 'KYC',
verificationType: 'email',
verification: {
SMS: '',
EMAIL: recipient.email,
WHATSAPP: ''
}
})
});
const data = await session.json();
const shortKey = extractShortKey(data.sessionUrl);
const params = new URLSearchParams({
shortKey: shortKey,
steps: 'DOCUMENT_EXTRACT,DOCUMENT_VERIFY,IVERIFICATION',
redirectUrl: `https://mi-app.com/campaign-complete?user=${recipient.id}&campaign=${campaign.id}`
});
return {
recipient: recipient.email,
name: recipient.name,
link: `${baseUrl}?${params.toString()}`
};
})
);
return links;
}
function extractShortKey(sessionUrl) {
const parts = sessionUrl.split('/');
return parts[parts.length - 1];
}
// Generar enlaces para campaña
const campaign = {
id: 'onboarding-q1-2025',
name: 'Onboarding Q1 2025'
};
const recipients = [
{ id: 'user123', name: 'Juan Pérez', email: '[email protected]' },
{ id: 'user456', name: 'María González', email: '[email protected]' }
];
const campaignLinks = await generateCampaignLinks(campaign, recipients);
// Enviar emails
campaignLinks.forEach(item => {
sendEmail({
to: item.recipient,
subject: 'Complete su verificación de identidad',
html: `
<h2>Hola ${item.name},</h2>
<p>Para completar su registro, por favor complete el proceso de verificación
haciendo clic en el siguiente botón:</p>
<a href="${item.link}" style="background: #0066cc; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">
Verificar mi identidad
</a>
<p>Este enlace es válido por 30 días.</p>
<p>Saludos,<br>Equipo de Mi App</p>
`
});
});
console.log('Enlaces de campaña generados:', campaignLinks);13. FAQ - Preguntas Frecuentes
¿Cuánto tiempo dura una sesión de KYC? Las sesiones tienen una duración de 14 minutos de inactividad. Después de este tiempo, la sesión expira y debe reiniciarse.
¿Puedo personalizar la apariencia de Mosaic? La modalidad Embed permite controlar el contenedor del iframe. El contenido interno de Mosaic no es personalizable para mantener consistencia y seguridad.
¿Qué documentos son soportados? JAAK KYC Mosaic soporta INE, pasaportes mexicanos, y otros documentos de identidad oficiales. Contacte a soporte para la lista completa.
¿Funciona en todos los navegadores? Sí, funciona en navegadores modernos (Chrome 80+, Firefox 75+, Safari 13+, Edge 80+) que soporten acceso a cámara.
¿Puedo usar Mosaic sin internet? No, Mosaic requiere conexión a internet activa para funcionar correctamente.
¿Los datos están seguros? Sí, todas las comunicaciones utilizan HTTPS y los datos son procesados siguiendo estándares de seguridad internacionales.
¿Puedo ejecutar pasos de forma independiente? Sí, puede configurar cualquier combinación de pasos. Algunos pasos como OTO requieren datos de pasos anteriores.
¿Qué pasa si el usuario cierra el navegador? Si el usuario cierra el navegador antes de completar, puede reiniciar el proceso. Los pasos completados se guardan durante la duración de la sesión (14 minutos).
¿Dónde obtengo mi API Key? Acceda a su Dashboard de JAAK en https://dashboard.jaak.ai, navegue a la sección de API Keys y copie su token de autenticación.
¿Puedo usar la misma API Key en sandbox y producción? No, debe usar API Keys diferentes para cada ambiente. Solicite ambas al equipo de JAAK.
¿Cómo manejo múltiples verificaciones simultáneas? Cree una sesión separada (shortKey único) para cada usuario/verificación. Cada sesión es independiente.
14. Soporte y Recursos
Contacto
| Contacto | Información |
|---|---|
| Email de soporte | [email protected] |
| Sitio web | www.jaak.ai |
| Horario de atención | Lunes a Viernes, 9:00 - 18:00 (Hora de México) |
Información requerida para soporte
Al contactar soporte, incluya la siguiente información:
- Modalidad de integración utilizada (Embed, Direct, o Link)
- Navegador y versión utilizada
- Logs de la consola del navegador
- Pasos para reproducir el problema
- Mensajes de error específicos
- Ambiente utilizado (Sandbox o Producción)
Recursos adicionales
- Documentación técnica detallada disponible bajo petición
- Ejemplos de código y casos de uso en nuestro repositorio
- Webinars y sesiones de capacitación disponibles
- Dashboard de JAAK: https://dashboard.jaak.ai
Para más información, visite www.jaak.ai o contacte a [email protected]
Updated about 1 month ago
