Implementación de webhooks

Configura la entrega de webhooks y construye handlers robustos.

Ahora que entiendes el flujo de procesamiento y los eventos de webhook de cada entidad (Import, File, Document), aquí tienes cómo configurar la entrega de webhooks e implementar handlers robustos.

Configuración de webhooks

Para recibir eventos de cambio de estado necesitarás:

  • URL accesible públicamente - tu endpoint debe ser alcanzable por los sistemas de Invofox
  • Configuración de lista de IPs permitidas - consulta nuestros rangos de IP públicos para configurar el firewall
  • Firma HMAC opcional - configura una clave secreta que se usará para firmar las notificaciones de webhook con HMAC, para mayor seguridad y verificación de autenticidad

Contacta con el administrador de tu cuenta para la configuración de webhooks, la información de rangos de IP y la configuración de la firma HMAC.

Los webhooks se disparan en las transiciones de estado y en las actualizaciones de documentos, garantizando que recibas actualizaciones a tiempo sin notificaciones redundantes.

Estructura del evento de webhook

Todos los eventos de webhook siguen esta estructura consistente:

  • type - Identificador del tipo de evento (coincide con las transiciones de estado)
  • id - Identificador único del evento (úsalo para un procesamiento idempotente)
  • timestamp - Marca de tiempo de creación del evento en formato ISO 8601
  • data - Carga útil del evento con la instancia de la entidad (objeto Import, File o Document)
  • version - Versión del esquema del evento

Ejemplo de evento

1{
2 "type": "document.processed",
3 "id": "675e1a2b8f7d06899790871d",
4 "timestamp": "2024-12-15T14:30:00.000Z",
5 "data": { /* DATOS DEL DOCUMENTO */ },
6 "version": "1.0"
7}

Nota: La estructura de datos del documento se está refinando. Consulta la referencia de la API para ver la estructura completa y actual del documento.

Buenas prácticas de implementación de webhooks

Esta sección cubre las buenas prácticas para implementar handlers de webhook robustos que procesen los eventos de Invofox de forma fiable y eficiente.

Patrón de confirmación rápida

⚠️ Buena práctica: Tu endpoint de webhook debe responder con un código de estado 2xx en menos de 30 segundos para garantizar una entrega fiable.

Por qué importan las respuestas rápidas:

  • Evitan fallos por timeout y reintentos
  • Mantienen una entrega de eventos fiable
  • Te permiten gestionar el procesamiento de forma asíncrona

Patrón recomendado: Verificar firma → Encolar evento → Responder de inmediato

1import express from 'express';
2import crypto from 'crypto';
3
4const app = express();
5app.use(express.json());
6
7// Cola de mensajes (ejemplo: AWS SQS, RabbitMQ, Bull, etc.)
8import { messageQueue } from './queue';
9
10app.post('/webhook', async (req, res) => {
11 // Paso 1: Verificar la firma
12 if (!verifyWebhookSignature(req.body, req.headers['x-invofox-signature'], process.env.WEBHOOK_SECRET)) {
13 return res.status(401).json({ error: 'Invalid signature' });
14 }
15
16 // Paso 2: Encolar el evento para procesamiento asíncrono
17 await messageQueue.send({
18 type: 'invofox-webhook',
19 payload: req.body,
20 receivedAt: Date.now()
21 });
22
23 // Paso 3: Responder de inmediato
24 res.status(200).json({ received: true });
25});
26
27function verifyWebhookSignature(requestBody: any, signature: string | undefined, secret: string): boolean {
28 if (!signature || !secret) return false;
29
30 const splitIndex = signature.indexOf('=');
31 const algorithm = signature.slice(0, splitIndex);
32 const receivedHmac = signature.slice(splitIndex + 1);
33
34 const computedHmac = crypto
35 .createHmac(algorithm, secret)
36 .update(JSON.stringify(requestBody))
37 .digest('base64');
38
39 return computedHmac === receivedHmac;
40}

ID de evento e idempotencia

Cada evento de webhook incluye un campo id único. Úsalo para implementar un procesamiento idempotente y evitar el manejo duplicado.

Por qué importa la idempotencia:

  • Los problemas de red pueden hacer que Invofox reintente la entrega
  • Tu lógica de procesamiento podría dispararse varias veces
  • Los IDs de evento garantizan que cada evento se procese exactamente una vez

Manejo de errores y comportamiento de reintentos

Códigos de estado HTTP:

Tu endpoint de webhook debe devolver:

  • 200-299: Éxito - Invofox no reintentará
  • 4xx: Error de cliente - Invofox no reintentará (tu endpoint rechazó el evento)
  • 5xx: Error de servidor - Invofox reintentará hasta 3 veces
  • Timeout: La petición expira tras 30 segundos - Invofox reintentará hasta 3 veces

Estrategia de reintentos de Invofox:

Cuando tu endpoint devuelve un error o expira, Invofox reintentará automáticamente hasta 3 veces:

  • Los retrasos entre reintentos se basan en la cabecera de respuesta Retry-After de tu endpoint (por defecto: 300 ms si no se especifica)
  • Total de intentos: petición original + 3 reintentos = 4 intentos de entrega

Tras agotar los reintentos, las entregas de webhook fallidas se registran y pueden consultarse en tu dashboard de webhooks.

Buenas prácticas de seguridad

Verificación de la firma HMAC:

Verifica siempre la firma HMAC cuando configures un secreto de webhook. Esto garantiza que los eventos provienen de Invofox.

Puntos clave de seguridad:

  1. Almacenamiento del secreto: guarda los secretos de webhook en variables de entorno o sistemas de gestión de secretos
  2. Solo HTTPS: los endpoints de webhook deben usar HTTPS en producción
  3. Valida las firmas: verifica siempre las firmas HMAC cuando haya secretos configurados (consulta la Referencia de la API para la implementación)
  4. Lista de IPs permitidas: opcional - configura tu firewall para aceptar solo peticiones de los rangos de IP de Invofox (contacta con soporte)

Checklist resumen

  • Confirmación rápida: responde con 200 en menos de 30 segundos
  • Procesamiento asíncrono: encola los eventos y procésalos de forma asíncrona
  • Verificación HMAC: verifica siempre las firmas cuando haya un secreto configurado
  • Idempotencia: usa el id del evento para evitar el procesamiento duplicado
  • Manejo de errores: devuelve los códigos de estado HTTP adecuados según el tipo de error
  • Seguridad: usa HTTPS, almacenamiento seguro de secretos y, opcionalmente, lista de IPs permitidas