Webhooks
Configura endpoints de webhook para notificaciones de eventos en tiempo real incluyendo formato de payload, tipos de evento, firmas de seguridad y política de reintentos.
Última actualización: 2025-02-18
Webhooks
Certexi puede enviar notificaciones HTTP en tiempo real a tus sistemas cuando ocurren eventos. Los webhooks permiten la integración con sistemas ERP externos, servicios de notificación y automatización personalizada.
Configuración
Registra endpoints de webhook a través del panel de administración o la API:
POST /api/webhooks
Content-Type: application/json
{
"url": "https://your-system.com/webhooks/certexi",
"events": ["event.created", "transport_unit.stage_changed", "incident.created"],
"secret": "your-webhook-secret",
"active": true
}
| Campo | Tipo | Descripción |
|---|---|---|
url | string | Endpoint HTTPS para recibir payloads de webhook |
events | string[] | Tipos de evento a los que suscribirse |
secret | string | Secreto compartido para verificación de firma HMAC |
active | boolean | Habilitar o deshabilitar el webhook |
HTTPS Requerido
Las URLs de webhook deben usar HTTPS. Los endpoints HTTP son rechazados para prevenir exposición de credenciales en tránsito.
Tipos de Evento
Eventos de Flujo de Trabajo
| Evento | Disparador |
|---|---|
event.created | Cualquier evento creado en el sistema |
transport_unit.created | Nueva unidad de transporte registrada |
transport_unit.stage_changed | Unidad avanzó a la siguiente etapa del flujo |
transport_unit.completed | Unidad completó todas las etapas del flujo |
Eventos WHMS
| Evento | Disparador |
|---|---|
whms.placement | Activo colocado en un slot |
whms.removal | Activo retirado de un slot |
whms.verification | Colocación verificada por supervisor |
whms.dispute | Colocación disputada por supervisor |
Eventos de Cumplimiento
| Evento | Disparador |
|---|---|
incident.created | Nuevo incidente reportado |
incident.resolved | Incidente marcado como resuelto |
audit.report_generated | Reporte de cumplimiento generado |
Eventos IoT
| Evento | Disparador |
|---|---|
motion.detected | Movimiento detectado en una cámara |
scale.reading | Nueva lectura de báscula registrada |
Formato del Payload
Todos los payloads de webhook siguen una estructura consistente:
{
"id": "evt_abc123",
"type": "transport_unit.stage_changed",
"timestamp": "2025-01-15T14:30:00Z",
"data": {
"transportUnitId": "TU-2024-00042",
"fromStage": "bascula",
"toStage": "supervisor",
"operator": "op-123",
"evidence": {
"photos": 2,
"scaleReading": 24500
}
},
"metadata": {
"warehouseId": 1,
"siteId": "site-main",
"version": "2.0.0"
}
}
Seguridad
Verificación de Firma HMAC
Cada solicitud de webhook incluye un header de firma para verificación del payload:
X-Certexi-Signature: sha256=<hmac_hex>
Verifica la firma en tu endpoint:
import crypto from 'crypto';
function verifyWebhook(
payload: string,
signature: string,
secret: string
): boolean {
const expected =
'sha256=' +
crypto.createHmac('sha256', secret).update(payload, 'utf8').digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
Siempre Verifica las Firmas
Nunca proceses payloads de webhook sin verificar la firma HMAC. Esto previene ataques de repetición y manipulación del payload.
Headers Adicionales
| Header | Descripción |
|---|---|
X-Certexi-Event | Tipo de evento (ej., transport_unit.stage_changed) |
X-Certexi-Delivery | ID de entrega único para deduplicación |
X-Certexi-Timestamp | Marca de tiempo ISO 8601 del evento |
X-Certexi-Signature | Firma HMAC-SHA256 |
Política de Reintentos
Las entregas fallidas se reintentan con retroceso exponencial:
| Intento | Demora |
|---|---|
| 1 | Inmediato |
| 2 | 1 minuto |
| 3 | 5 minutos |
| 4 | 30 minutos |
| 5 | 2 horas |
| 6 | 12 horas |
Una entrega se considera fallida si:
- El endpoint retorna un código de estado no-2xx
- La conexión expira (timeout de 30 segundos)
- El endpoint es inalcanzable
Después de 6 intentos fallidos, el webhook se marca como fallando y se envía una alerta al panel de administración. Los webhooks se deshabilitan automáticamente después de 100 fallos consecutivos.
Tarjeta de Payload de Webhook
<Card className="w-full"> <CardHeader className="pb-2"> <div className="flex items-center justify-between"> <CardTitle className="text-sm font-mono">transport_unit.stage_changed</CardTitle> <Badge className="bg-green-500 text-white text-[10px]">200 OK</Badge> </div> <CardDescription>Delivered 2.3s ago — Attempt 1/6</CardDescription> </CardHeader> <CardContent className="space-y-2"> <div className="bg-muted/50 rounded p-2 font-mono text-[11px] leading-relaxed"> <div>{"{"}</div> <div className="pl-3">"type": "transport_unit.stage_changed",</div> <div className="pl-3">"data": {"{"}</div> <div className="pl-6">"transportUnitId": "TU-2025-00042",</div> <div className="pl-6">"fromStage": "bascula",</div> <div className="pl-6">"toStage": "supervisor"</div> <div className="pl-3">{"}"}</div> <div>{"}"}</div> </div> <div className="flex items-center gap-2 text-[10px] text-muted-foreground"> <span>X-Certexi-Signature: sha256:a4f2e8...</span> </div> </CardContent> </Card>
Pruebas
Usa el endpoint de prueba de webhook para enviar un payload de ejemplo:
POST /api/webhooks/:id/test
Esto envía un evento webhook.test a la URL registrada sin afectar datos de producción.