Qué vas a construir
Un receptor preparado para entregas repetidas, retrasos y fallos. Recibir un evento de pago registrado en Ruka no demuestra que el banco haya ejecutado una transferencia.
Antes de empezar
- Una clave permanente de la dueña o dueño de la cuenta, con administración y reportes autorizados.
- Una URL HTTPS pública en el puerto 443 que pueda responder a la comprobación HEAD con 2xx o 405.
- Almacenamiento durable para los eventos y un worker propio. El verificador descargable no reemplaza esos componentes.
1. Suscribe solo los cambios que necesitas.
POST /api/v1/webhooks registra tu URL. Hay 17 eventos disponibles y hasta 20 URLs activas por cuenta. Sin events se conserva invoice.created. Para compras listas para integrar, revisa invoice.accepted: se refiere a revisión interna, no al acuse del SII.
Guarda signing_secret cuando lo recibas: solo se muestra al crear. No lo subas a Git ni lo copies a un frontend. Puedes limitar por company_id. PATCH reemplaza la selección completa de events; agregar eventos no recupera el pasado. Cambiar URL, empresa o signing_secret exige eliminar y registrar nuevamente.
curl --fail-with-body \
'https://api.rukafactura.cl/api/v1/webhooks' \
--header "Authorization: Bearer $RUKA_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"webhook_url": "https://tu-dominio.example/ruka/events",
"events": ["invoice.accepted", "invoice.status_changed"],
"payload_format": "event_envelope"
}'2. Verifica los bytes antes de interpretar el JSON.
La firma HMAC-SHA256 usa tu signing_secret y la secuencia timestamp + punto + cuerpo crudo. Compara con X-Ruka-Signature, que empieza por sha256=. No serialices de nuevo el JSON antes de verificarlo: incluso un cambio de espacios altera la firma.
Rechaza timestamps fuera de una tolerancia de cinco minutos y usa comparación de tiempo constante. Mantén el reloj sincronizado y limita el tamaño del cuerpo según tu infraestructura. El archivo descargable incluye la verificación; lee el cuerpo como Buffer antes del middleware JSON.
import { verifyRukaWebhook } from './verify-ruka-webhook.mjs';
const valid = verifyRukaWebhook({
rawBody, // Buffer con los bytes exactos recibidos
timestamp: headers['x-ruka-timestamp'],
signature: headers['x-ruka-signature'],
secret: process.env.RUKA_SIGNING_SECRET,
});
// Si no es válido, rechaza sin procesar el evento.3. Guarda primero. Procesa después.
Usa X-Ruka-Event-Id como clave única junto a la identidad de tu suscripción o cuenta. Inserta el evento y el trabajo pendiente en una transacción durable; responde 2xx después de confirmar esa escritura. Si ya estaba guardado, reconoce el duplicado sin aplicar de nuevo sus efectos.
Si tu cola vive fuera de la base, usa un patrón outbox o equivalente: una respuesta 2xx antes de garantizar la persistencia puede perder el evento. El worker aplica cambios idempotentes. No prometas orden de llegada ni que un evento refleja el estado más reciente: contrasta versiones y reconcilia por API.
4. Diseña la recuperación antes de habilitarlo.
Ruka realiza hasta seis intentos. Tras el primero, los intervalos son 1 minuto, 5 minutos, 30 minutos, 2 horas y 8 horas. Un reintento conserva el ID y el cuerpo capturado en el primer intento, pero firma con un timestamp nuevo. Tu deduplicación no debe depender de la firma.
Revocar acceso o quitar un evento puede cancelar pendientes. No hay recuperación automática de todo el historial al crear la suscripción. Programa una conciliación periódica con el libro y prueba duplicados, firma incorrecta, caída de tu worker y caída de tu base antes de conectar una operación real.
Antes de conectar producción
- Cambiar un byte del cuerpo invalida la firma.
- Un timestamp vencido se rechaza.
- Dos entregas del mismo ID producen un solo efecto.
- Una caída antes de persistir no recibe 2xx.
- La recuperación consulta estado actual, no presupone orden de eventos.
Ejemplo para tu servidor
Archivo JavaScript legible, para Node.js 22 o superior. No incluye claves, no se ejecuta al descargarlo y no reemplaza la persistencia ni los controles de tu integración.
Descargar ejemplo .mjsContrato y mantenimiento
La guía acompaña el contrato publicado en la fecha indicada. Antes de integrar, revisa permisos, filtros y respuestas vigentes en la referencia. Trabaja primero con datos de prueba autorizados.
Ver referencia de esta operación