Cuando un webhook nunca llega

Resuélvelo en orden - el registro de entregas, el nombre del evento, el firewall, la firma. La pestaña Deliveries te dice si Didit lo envió, lo que divide el problema por la mitad inmediatamente.

Short answer

Empieza por la pestaña Deliveries del destino. Si Didit nunca intentó la entrega, es un problema de suscripción o de destino. Si lo intentó y falló, el código de respuesta te dice cuál: 404 significa que tu ruta no era accesible en esa URL, un desajuste de firma significa que hasheaste los bytes equivocados.

#Paso 1: ¿intentó Didit enviarlo?

Abre el destino en API & Webhooks y mira la pestaña Deliveries. Cada intento queda registrado individualmente, con la respuesta.

La página de webhooks en la consola de Didit mostrando el estado de entrega por destino
  1. Last sent te dice si Didit lo intentó siquiera.
  2. View stats muestra los intentos y los fallos de ese destino.
  3. Una entrega de prueba separa tu endpoint del evento en sí.
  4. Un destino que sigue fallando se puede desactivar mientras lo arreglas.
Todo lo necesario para distinguir un evento ausente de un endpoint que falla está en esta página.

Esa única comprobación divide el problema por la mitad:

  • No hay ningún intento registrado → el evento nunca se generó para ese destino. Ve al paso 2.
  • Intento registrado, fallido → Didit lo envió y tu lado lo rechazó o no lo recibió. Ve al paso 3.
  • Intento registrado, 2xx → se entregó correctamente. El problema está dentro de tu gestor, no en la entrega.

#Paso 2: no se registró ningún intento

En orden de probabilidad:

  1. El evento no está suscrito. No hay comodín: cada familia de eventos tiene que listarse explícitamente. Y un nombre que no existe (session.status.updated, kyc.completed) no recibe nada, en silencio. Compruébalo contra la lista de eventos.
  2. Aplicación equivocada. Los destinos pertenecen a una aplicación. Si tus sesiones se ejecutan bajo una aplicación distinta de la del destino, ningún evento llegará nunca a él. Esta es la causa más común cuando todo parece configurado correctamente.
  3. No cambió nada en realidad. Los webhooks se disparan al cambiar algo. Una sesión que no se ha movido, o un re-cribado de monitorización AML que no encontró nada por encima del umbral, correctamente no produce ningún evento.
  4. El estado que esperas todavía no ha ocurrido. Una sesión En curso no ha terminado. Consulta cuando una sesión nunca termina.

#Paso 3: la entrega se intentó y falló

Un 404 significa que la solicitud llegó a algo que no tenía tu ruta. Comprueba:

  • La ruta exacta, incluida una barra final. Un framework que redirige /hook a /hook/ puede convertir un endpoint que funciona en un 404 o un cuerpo perdido.
  • Si la URL es pública. Un host local o de staging que no es accesible desde internet falla de esta forma.
  • Si un proxy, un balanceador de carga, o un enrutador basado en rutas delante de tu aplicación está enviando esa ruta a otro sitio.

Un 5xx significa que tu gestor lanzó una excepción. Registra el cuerpo en bruto antes de analizarlo para poder ver qué recibió en realidad.

Un timeout significa que no respondiste lo bastante rápido. Devuelve un 2xx primero, procesa después.

Nada en absoluto / conexión rechazada significa que tu borde lo bloqueó. Didit entrega desde la IP estática 18.203.201.92 con un user agent DiditWebhook/2.0. Si estás detrás de Cloudflare o de un WAF con una postura de denegación por defecto, permite esa IP para el hostname receptor.

#El clásico: la entrega automática da 404 pero Resend funciona

Este aparece lo bastante a menudo como para tener nombre propio. La entrega automatizada falla con un 404, y luego pulsar Resend en el mismo evento funciona.

Esa combinación significa que tanto el payload como tu endpoint están bien, así que la diferencia está en el tiempo o en la ruta, no en el contenido. Comprueba:

  • Un despliegue o un reinicio en el momento de la entrega original. Resend funciona más tarde porque la aplicación ya está de nuevo activa.
  • Un arranque en frío que superó el timeout de tu plataforma: habitual en serverless con una primera invocación lenta.
  • Un enrutado basado en rutas que cambió entre los dos intentos, o una regla que solo coincide con algunas solicitudes.
  • Límite de frecuencia o protección antibots en tu borde que dejó pasar el reenvío manual porque llegó solo en lugar de en una ráfaga.

La pestaña Deliveries tiene ambos intentos con sus marcas de tiempo: compáralos con tus propios registros de despliegue y de errores de ese minuto.

#Fallo en la verificación de firma

Casi siempre es una de estas tres cosas:

  1. Hasheaste JSON re-serializado. Aplica HMAC a los bytes en bruto de la solicitud exactamente como se recibieron. Analizar y volver a convertir a cadena cambia los espacios en blanco y el orden de las claves, y la firma no coincidirá. La mayoría de los frameworks necesitan configuración explícita para darte el cuerpo en bruto.
  2. Secreto equivocado. El secreto de firma es por destino, y no es tu clave de API. Dos destinos tienen dos secretos distintos.
  3. Suposición de codificación equivocada. Si no estás seguro de si el secreto se usa como cadena literal o se decodifica primero, no lo adivines: sigue exactamente la referencia de verificación de firma, y registra el cuerpo en bruto mientras depuras para poder compararlo.
Important

Nunca "arregles" un desajuste de firma saltándote la verificación. Un endpoint de webhook sin verificar aceptará una aprobación falsificada de cualquiera que encuentre la URL, lo que convierte un atajo de depuración en una vía de toma de control de la cuenta.

#Dos reintentos no son una cola

Ante un 5xx, un 404, un timeout o un fallo de conexión, Didit reintenta dos veces: aproximadamente 1 minuto después y luego 4 minutos más tarde, y después descarta la entrega. Si tu endpoint estuvo caído más tiempo que eso, esos eventos se han perdido para siempre.

Construye una ruta de reconciliación: al arrancar, sondea el endpoint de decisión para cualquier sesión de la que no tengas un estado final. Trata los webhooks como la vía rápida y el sondeo como el respaldo.

#Probar sin ejecutar verificaciones

Try Webhook en la página del destino envía un evento completamente formado del tipo que elijas: aprobado, rechazado, en revisión, KYB, entidad, transacción. Úsalo para comprobar que tu endpoint, tu verificación de firma y tu gestor funcionan antes de que una sesión real dependa de ellos.

Sandbox es la otra mitad de esto: una sesión de sandbox emite webhooks reales con "environment": "sandbox", así que puedes ejercitar todo el camino de principio a fin gratis. Consulta probar en sandbox.