PIN-RUT Verificación de Identidad
PIN-RUT Verificación de Identidad
Sección titulada «PIN-RUT Verificación de Identidad»El servicio PIN-RUT permite verificar la identidad de personas mediante un PIN numérico personal vinculado a su RUT chileno. La persona crea su PIN una sola vez y lo usa para autorizar operaciones solicitadas por tu sistema.
Casos de uso típicos:
- Firma de contratos o documentos
- Autorización de transacciones financieras
- Confirmación de identidad en procesos de onboarding
- Validación de operaciones sensibles
Requisitos Previos
Sección titulada «Requisitos Previos»Antes de usar la API necesitas:
- Una API Key con rol
FULL-API - El tenant debe tener el servicio PIN_RUT habilitado
- Una integración PIN-RUT configurada con las URLs permitidas
Configuración de Integraciones
Sección titulada «Configuración de Integraciones»Antes de crear transacciones, debes configurar una integración desde el panel de administración:
Configuración → PIN-RUT → Integraciones
Campos de la Integración
Sección titulada «Campos de la Integración»| Campo | Descripción |
|---|---|
| Slug | Identificador único inmutable (ej: mi_app_prod). Se usa en cada request. |
| Nombre | Nombre descriptivo que la persona verá en la pantalla de verificación |
| URIs de redirect | URLs HTTPS donde el browser redirige tras completar la verificación |
| URLs de callback | URLs HTTPS donde se envían webhooks con el resultado |
| Orígenes iframe | URLs HTTPS autorizadas para embeber la pantalla PIN en un iframe |
| URI de redirect default | Redirect por defecto si no se especifica en cada transacción |
Ejemplo de Integración
Sección titulada «Ejemplo de Integración»| Campo | Valor |
|---|---|
| Slug | mi_app_prod |
| Nombre | Mi Aplicación |
| Redirect URIs | https://miapp.cl/pin-callback |
| Callback URLs | https://miapp.cl/webhooks/pin |
| Redirect default | https://miapp.cl/pin-callback |
Flujo de Verificación
Sección titulada «Flujo de Verificación»Tu Sistema Redcumbre Persona │ │ │ │── POST /pin/transactions ──▶│ │ │ (Bearer token + body) │ │ │ │ │ │◀── authorize_url ──────────│ │ │ (+ transaction_id) │ │ │ │ │ │── Redirige browser ────────▶│ │ │ a authorize_url │ │ │ │── Pantalla de PIN ────────▶│ │ │ │ │ │◀── Persona ingresa PIN ───│ │ │ │ │◀── Webhook (callback_url) ─│ │ │ pin.transaction.authorized │ │ │ │ │ │── Redirect a redirect_uri ▶│ │ │ ?transaction_id=X │ │ │ &status=authorized │ │ │ &state=Y │ │ │ │ │── GET /result ─────────────▶│ │ │ (verificar estado final) │ │ │◀── { status: authorized } ─│ │Pasos:
- Tu sistema crea una transacción con los datos de la operación
- Rediriges al usuario a la
authorize_urlretornada - La persona ve los datos de la operación e ingresa su PIN
- Tu sistema recibe el resultado vía webhook y/o redirect
- Opcionalmente, consultas el resultado vía API
Crear Transacción
Sección titulada «Crear Transacción»Endpoint
Sección titulada «Endpoint»POST /{tenantSlug}/pin/transactionsHeaders
Sección titulada «Headers»Authorization: Bearer {api_key}Content-Type: application/json{ "integration_slug": "mi_app_prod", "rut": "12.345.678-9", "operation_type": "firma_contrato", "operation_label": "Firmar Contrato de Servicios N° 2026-042", "operation_detail": "Contrato por 12 meses", "redirect_uri": "https://miapp.cl/pin-callback", "callback_url": "https://miapp.cl/webhooks/pin", "state": "session-abc-123"}| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
integration_slug | string | Sí | Slug de la integración configurada |
rut | string | Sí | RUT chileno de la persona (ej: 12.345.678-9 o 12345678-9) |
operation_type | string | Sí | Tipo de operación en snake_case (máx. 50 chars) |
operation_label | string | Sí | Descripción visible para la persona (máx. 200 chars) |
operation_detail | string | No | Detalle adicional de la operación |
fullName | string | No | Nombre completo de la persona (si no existe en el sistema) |
redirect_uri | string | No | URL HTTPS de redirect. Debe estar en las URIs permitidas de la integración |
callback_url | string | No | URL HTTPS para webhook. Debe estar en las URLs permitidas de la integración |
state | string | No | Valor opaco devuelto sin modificar en redirect y webhook (máx. 2048 chars) |
Ejemplo con curl
Sección titulada «Ejemplo con curl»curl -X POST "https://api.redcumbre.cl/{tenantSlug}/pin/transactions" \ -H "Authorization: Bearer {api_key}" \ -H "Content-Type: application/json" \ -d '{ "integration_slug": "mi_app_prod", "rut": "12.345.678-9", "operation_type": "firma_contrato", "operation_label": "Firmar Contrato N° 2026-042", "redirect_uri": "https://miapp.cl/pin-callback", "callback_url": "https://miapp.cl/webhooks/pin", "state": "session-abc-123" }'Respuesta Exitosa (201)
Sección titulada «Respuesta Exitosa (201)»{ "success": true, "data": { "transaction_id": "cedd740a-e5a3-43a2-9896-5ac45dfdb4dc", "authorize_url": "/p/pin/authorize/cedd740a-e5a3-43a2-9896-5ac45dfdb4dc", "expires_at": "2026-05-09T23:35:04.594Z", "operation_hash": "06860b21052299ad...", "person_status": "has_pin" }}| Campo | Tipo | Descripción |
|---|---|---|
transaction_id | string (UUID) | Identificador único de la transacción |
authorize_url | string | Ruta relativa para redirigir a la persona. Prefijar con la URL base de la plataforma |
expires_at | string (ISO 8601) | Fecha de expiración de la transacción |
operation_hash | string | Hash SHA-256 de la operación (para verificación de integridad) |
person_status | string | "has_pin" si la persona ya tiene PIN, "needs_creation" si debe crear uno primero |
Redirect de la Persona
Sección titulada «Redirect de la Persona»Construye la URL completa y redirige al usuario:
https://app.redcumbre.cl{authorize_url}Por ejemplo:
https://app.redcumbre.cl/p/pin/authorize/cedd740a-e5a3-43a2-9896-5ac45dfdb4dcSi person_status es "needs_creation", la plataforma guiará a la persona a crear su PIN antes de la verificación. No requiere acción adicional de tu parte.
Consultar Resultado
Sección titulada «Consultar Resultado»Endpoint
Sección titulada «Endpoint»GET /{tenantSlug}/pin/transactions/{transaction_id}/resultHeaders
Sección titulada «Headers»Authorization: Bearer {api_key}Respuesta
Sección titulada «Respuesta»{ "success": true, "data": { "transaction_id": "cedd740a-e5a3-43a2-9896-5ac45dfdb4dc", "status": "authorized", "integration_slug": "mi_app_prod", "rut": "12.345.678-9", "operation_type": "firma_contrato", "operation_label": "Firmar Contrato N° 2026-042", "created_at": "2026-05-09T23:30:04.594Z", "authorized_at": "2026-05-09T23:33:01.538Z", "expires_at": "2026-05-09T23:35:04.594Z", "state": "session-abc-123" }}Cancelar Transacción
Sección titulada «Cancelar Transacción»Cancela una transacción pendiente antes de que la persona la complete:
Endpoint
Sección titulada «Endpoint»POST /{tenantSlug}/pin/transactions/{transaction_id}/cancelHeaders
Sección titulada «Headers»Authorization: Bearer {api_key}Respuesta
Sección titulada «Respuesta»{ "success": true, "data": { "success": true }}Solo transacciones en estado pending pueden cancelarse. Si la transacción ya está en un estado terminal, recibirás un error 409.
Estados de la Transacción
Sección titulada «Estados de la Transacción»| Estado | Terminal | Descripción |
|---|---|---|
pending | No | Persona aún no completó la verificación |
authorized | Sí | PIN ingresado correctamente — identidad verificada |
failed | Sí | PIN incorrecto reiterado o RUT bloqueado |
expired | Sí | La persona no completó antes del TTL |
cancelled | Sí | Cancelada por el integrador o por la persona |
Webhooks
Sección titulada «Webhooks»Si configuraste un callback_url, recibirás webhooks cuando la transacción cambie a un estado terminal.
Eventos
Sección titulada «Eventos»| Evento | Cuándo |
|---|---|
pin.transaction.authorized | Persona ingresó PIN correcto |
pin.transaction.failed | PIN incorrecto 5 veces o RUT bloqueado |
pin.transaction.expired | TTL cumplido sin completar |
pin.transaction.cancelled | Cancelada por integrador o persona |
Payload del Webhook
Sección titulada «Payload del Webhook»{ "event": "pin.transaction.authorized", "timestamp": "2026-05-09T23:38:01.577Z", "data": { "transaction_id": "cedd740a-e5a3-43a2-9896-5ac45dfdb4dc", "integration_id": "702191e3-e415-41dc-ac1b-0b66d2edccf9", "rut": "12.345.678-9", "operation_type": "firma_contrato", "operation_label": "Firmar Contrato N° 2026-042", "operation_hash": "06860b21052299ad...", "authorized_at": "2026-05-09T23:38:01.538Z", "status": "authorized", "state": "session-abc-123", "failure_reason": null }}Campos Específicos por Evento
Sección titulada «Campos Específicos por Evento»| Evento | Campos adicionales en data |
|---|---|
pin.transaction.authorized | authorized_at |
pin.transaction.failed | failure_reason ("max_attempts_reached", "rate_limit_exceeded") |
pin.transaction.expired | — |
pin.transaction.cancelled | — |
Resolución del Webhook URL
Sección titulada «Resolución del Webhook URL»El sistema determina dónde enviar el webhook con esta prioridad:
callback_urlenviado en la transacción (per-request)- URL global del webhook configurado en el tenant (fallback)
- Si ninguno existe → no se envía webhook (solo redirect)
Los headers personalizados configurados en el webhook global del tenant se incluyen siempre, independientemente de si el URL es per-request o global.
Redirect
Sección titulada «Redirect»Cuando la persona completa la verificación (o cancela), el browser redirige a la redirect_uri con query parameters:
https://miapp.cl/pin-callback?transaction_id=cedd740a-...&status=authorized&state=session-abc-123| Parámetro | Descripción |
|---|---|
transaction_id | UUID de la transacción |
status | Estado final: authorized, cancelled |
state | Valor opaco que enviaste al crear la transacción |
Códigos de Error
Sección titulada «Códigos de Error»| Código | Descripción | Causa |
|---|---|---|
| 400 | Validación fallida | RUT inválido, redirect_uri no en lista permitida, callback_url no permitida, máximo de pendientes alcanzado |
| 401 | No autorizado | API key inválida, expirada o revocada |
| 403 | Prohibido | Servicio PIN_RUT no habilitado o rol insuficiente |
| 404 | No encontrado | Integración no existe o está inactiva, transacción no encontrada |
| 409 | Conflicto | Transacción no está en estado pending (al cancelar) |
| 422 | No procesable | No hay redirect_uri y la integración no tiene default |
| 423 | Bloqueado | RUT bloqueado por demasiados intentos fallidos |
Ejemplo de Error 404 (Integración)
Sección titulada «Ejemplo de Error 404 (Integración)»{ "message": "Integración activa con slug \"mi_app_prod\" no encontrada", "error": "Not Found", "statusCode": 404}Ejemplo de Error 423 (RUT Bloqueado)
Sección titulada «Ejemplo de Error 423 (RUT Bloqueado)»{ "code": "pin_blocked", "message": "RUT is blocked due to too many failed attempts", "statusCode": 423}Protección Anti-Brute-Force
Sección titulada «Protección Anti-Brute-Force»El sistema implementa un rate limit global de intentos fallidos:
- Máximo 10 intentos fallidos por RUT en 1 hora (cross-tenant)
- Al superar el límite, el PIN del RUT se bloquea inmediatamente
- Transacciones nuevas para un RUT bloqueado retornan 423 Locked
- El bloqueo es global: protege contra ataques distribuidos desde múltiples integraciones
Límites
Sección titulada «Límites»| Concepto | Límite |
|---|---|
| Transacciones pendientes por RUT × integración | 3 |
| Intentos de PIN por transacción | 5 |
| Intentos fallidos globales por RUT/hora | 10 |
| TTL de transacción (persona con PIN) | 5 minutos |
| TTL de transacción (persona sin PIN) | 30 minutos |
Tamaño máximo de state | 2048 caracteres |
Tamaño máximo de operation_label | 200 caracteres |
Integración JavaScript
Sección titulada «Integración JavaScript»// 1. Crear transacciónconst response = await fetch( `https://api.redcumbre.cl/${tenantSlug}/pin/transactions`, { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ integration_slug: 'mi_app_prod', rut: '12.345.678-9', operation_type: 'firma_contrato', operation_label: 'Firmar Contrato N° 2026-042', redirect_uri: 'https://miapp.cl/pin-callback', callback_url: 'https://miapp.cl/webhooks/pin', state: sessionId, }), });
const { data } = await response.json();
// 2. Redirigir al usuariowindow.location.href = `https://app.redcumbre.cl${data.authorize_url}`;
// 3. En la página de callback, verificar resultadoconst params = new URLSearchParams(window.location.search);const txId = params.get('transaction_id');const status = params.get('status');
if (status === 'authorized') { // Verificar server-side antes de tomar acción const result = await fetch( `https://api.redcumbre.cl/${tenantSlug}/pin/transactions/${txId}/result`, { headers: { 'Authorization': `Bearer ${apiKey}` } } ); const { data: tx } = await result.json();
if (tx.status === 'authorized') { // Identidad verificada — proceder con la operación }}Receptor de Webhook (Node.js)
Sección titulada «Receptor de Webhook (Node.js)»app.post('/webhooks/pin', (req, res) => { const { event, data } = req.body;
switch (event) { case 'pin.transaction.authorized': console.log(`✓ Identidad verificada: RUT=${data.rut}, tx=${data.transaction_id}`); // Procesar autorización break;
case 'pin.transaction.failed': console.log(`✗ Verificación fallida: ${data.failure_reason}`); break;
case 'pin.transaction.expired': console.log(`⏰ Transacción expirada: ${data.transaction_id}`); break;
case 'pin.transaction.cancelled': console.log(`↩ Transacción cancelada: ${data.transaction_id}`); break; }
res.json({ received: true });});