Ir al contenido

WebhooksVerificar firma

Verificar firma

Ver como Markdown

Cualquiera puede mandarle un POST a tu endpoint haciéndose pasar por NovaFE. La firma es cómo confirmas que una entrega es legítima antes de actuar sobre ella.

Header Contenido
X-NovaFE-Event El tipo de evento, por ejemplo ecf.accepted.
X-NovaFE-Delivery El id de esta entrega. Estable entre reintentos del mismo intento.
X-NovaFE-Timestamp Segundos Unix del envío.
X-NovaFE-Signature sha256=<hex>.
<hex> = HMAC_SHA256(tu secret, "{X-NovaFE-Timestamp}.{cuerpo crudo del request}")

El separador es un punto literal entre el timestamp y el cuerpo, tal cual llegó, sin volver a serializarlo tú.

  1. Lee X-NovaFE-Timestamp y rechaza la entrega si |ahora − timestamp| > 300 segundos. Esto evita que alguien reproduzca una entrega vieja capturada.
  2. Recalcula el HMAC sobre "{timestamp}.{cuerpo crudo}" con tu secret.
  3. Compara el resultado, en tiempo constante, contra el valor después de sha256= en X-NovaFE-Signature.
firma_esperada = "sha256=" + hex(HMAC_SHA256(secret, timestamp + "." + cuerpo))
si firma_esperada != X-NovaFE-Signature (en tiempo constante):
rechazar la entrega

La entrega es al menos una vez: un mismo evento puede llegarte más de una vez (ver Entrega y reintentos). Deduplica usando el id del sobre (el campo id del cuerpo, o el header X-NovaFE-Delivery) antes de aplicar el efecto del evento. Guardar los últimos ids procesados en tu base, aunque sea por un par de días, alcanza.

ecf.accepted puede llegarte antes que ecf.submitted para el mismo comprobante: cada evento sigue su propio camino de reintentos, así que uno que falló y quedó en backoff puede llegar después de otro más reciente que salió bien al primer intento. Determina el estado en tu sistema a partir de data.object.status (el estado que trae el propio payload), nunca a partir del orden en que llegaron las entregas.