X-Waspy-Signature:
t= timestamp Unix en segundos cuando Waspy generó la firma para este intentov1= HMAC-SHA256 hex de<t>.<rawBody>usando tusecret(el que devolvióPOST /webhooksal crear la suscripción)
Importante —tvs. edad del payload:tse regenera en cada reintento. Su único propósito es la ventana anti-replay (5 min) sobre la firma. Si querés conocer la edad del payload original (útil para retries que pueden llegar hasta 12h después), leé el headerX-Waspy-First-Attempt-At(timestamp Unix en segundos del primer intento de esta delivery). Ese header se preserva a través de todos los reintentos.
Algoritmo
- Tomá el body raw (string, antes de parsear JSON).
- Parseá el header: extraé
tyv1. - Calculá
expected = HMAC_SHA256(secret, t + "." + rawBody). - Compará
expectedconv1usando una comparación constante (timing-safe). - Verificá que
tno sea más viejo de 5 minutos (protege contra replay del intento actual). - Opcional: si querés reglas de validez del payload (por ejemplo, ignorar
eventos de más de N horas), validá contra
X-Waspy-First-Attempt-Aten lugar det.
Node.js
Python
Recomendaciones
- Respondé
2xxlo antes posible (Waspy considera entregado cualquier 2xx; el body es ignorado). - Procesá el evento de forma asíncrona si toma más de unos segundos.
- Guardá
data.id+eventpara deduplicar entregas repetidas. - Si tu firma falla, devolvé
401para que Waspy registre el error enlastErrorMessage.