Saltar al contenido principal

Webhooks — conceptos

Los webhooks son el mecanismo por el cual Max Pay notifica eventos al ERP del integrador en tiempo casi real. Sin webhooks, la única alternativa sería hacer polling, lo cual es ineficiente y latente.

Esta página cubre el modelo conceptual. Para implementar (crear endpoint, verificar firma HMAC, hacer test delivery), ver Empezar con webhooks. Para la referencia operativa (endpoints, pausar/reanudar, rotar secret), ver Webhooks → Configuración. Para el catálogo de eventos, ver Eventos.

Modelo

Si el endpoint del integrador no responde 2xx dentro de 10 segundos, Max Pay reintenta con backoff exponencial.

Entrega

Cada evento se envía como POST al URL configurado con:

Headers

HeaderDescripción
X-MaxPay-SignatureFirma HMAC. Ver verificación
X-MaxPay-EventTipo del evento. Ej: receivable.created
X-MaxPay-Delivery-IdUUID de esta entrega (cambia entre retries del mismo evento)

Body

{
"id": "evt_b3f8a1c2d4e5f6789012345678901234",
"type": "receivable.created",
"createdAt": "2026-05-15T14:30:05-03:00",
"data": {
"receivable": { "id": 1234, "amount": 45000, "..." : "..." }
}
}

Los eventos son inmutables. Si la data subyacente cambia (ej. el comprobante se actualiza), se emite un evento nuevo (receivable.updated), no se modifica el original.

Verificación de firma

Toda entrega lleva la firma X-MaxPay-Signature:

X-MaxPay-Signature: t=1715812800,v1=5257a869e7ecebeda...

Donde:

  • t: Unix timestamp del momento de firma (mismo valor que X-MaxPay-Timestamp).
  • v1: HMAC-SHA256 calculado sobre <timestamp>.<body> con el secret del webhook como clave.

El integrador debe recalcular el HMAC con su secret y compararlo en tiempo constante. Además, conviene rechazar entregas con timestamp viejo (típicamente > 5 minutos) para evitar replay attacks.

Para una implementación completa con código de ejemplo, ver Empezar con webhooks.

Verificá siempre la firma

Sin verificar, cualquier atacante con tu URL pública puede inyectar eventos falsos en tu ERP. La verificación es la diferencia entre una integración robusta y un vector de ataque.

Reintentos

Si el endpoint responde algo distinto de 2xx, Max Pay reintenta con el siguiente cronograma:

IntentoDemora desde el anterior
1(inmediato)
21 minuto
35 minutos
430 minutos
52 horas
612 horas

Total: ~14 horas desde el evento original. Pasado ese plazo, la entrega se descarta y el webhook queda como FAILED. Para diagnosticar y reenviar entregas fallidas, ver Diagnóstico de entregas.

Deduplicación de eventos

Por el modelo "at-least-once" del retry, el integrador puede recibir el mismo evento más de una vez. El event.id es único e inmutable para cada evento, y se mantiene constante entre reintentos del mismo evento. La estrategia estándar es persistir los event.id ya procesados y descartar (respondiendo 200 OK) los que ya estén en la lista.

Para el patrón de implementación, ver Empezar con webhooks.

Orden y concurrencia

Los eventos cercanos en el tiempo pueden llegar fuera de orden por concurrencia interna. El integrador no debe asumir secuencia entre eventos distintos (ej. receivable.created puede llegar después de receivable.paid si los reintentos del primero se atrasaron).

Para handling de rollbacks: una transacción revertida se notifica como un movement.created con operationType: ROLLBACK que referencia al movement original. La lógica de conciliación del integrador debe contemplar este caso.