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
}
CampoTipoDescripción
urlstringEndpoint HTTPS para recibir payloads de webhook
eventsstring[]Tipos de evento a los que suscribirse
secretstringSecreto compartido para verificación de firma HMAC
activebooleanHabilitar 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

EventoDisparador
event.createdCualquier evento creado en el sistema
transport_unit.createdNueva unidad de transporte registrada
transport_unit.stage_changedUnidad avanzó a la siguiente etapa del flujo
transport_unit.completedUnidad completó todas las etapas del flujo

Eventos WHMS

EventoDisparador
whms.placementActivo colocado en un slot
whms.removalActivo retirado de un slot
whms.verificationColocación verificada por supervisor
whms.disputeColocación disputada por supervisor

Eventos de Cumplimiento

EventoDisparador
incident.createdNuevo incidente reportado
incident.resolvedIncidente marcado como resuelto
audit.report_generatedReporte de cumplimiento generado

Eventos IoT

EventoDisparador
motion.detectedMovimiento detectado en una cámara
scale.readingNueva 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

HeaderDescripción
X-Certexi-EventTipo de evento (ej., transport_unit.stage_changed)
X-Certexi-DeliveryID de entrega único para deduplicación
X-Certexi-TimestampMarca de tiempo ISO 8601 del evento
X-Certexi-SignatureFirma HMAC-SHA256

Política de Reintentos

Las entregas fallidas se reintentan con retroceso exponencial:

IntentoDemora
1Inmediato
21 minuto
35 minutos
430 minutos
52 horas
612 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.

Relacionado