Vas a lograr recibir un evento por webhook, verificar que lo mandó Mozart y responder correctamente para que no se reintente de más.

Cómo se da de alta

Los webhooks no se autogestionan: se dan de alta desde el panel de administración interno de Mozart, a pedido de tu organización. Pedile a tu contacto en Mozart que registre tu URL y los eventos que querés recibir — queda registrado bajo Organización → Webhooks del cliente correspondiente. La URL tiene que ser https:// y apuntar a un host público; Mozart no entrega eventos a endpoints http:// ni a direcciones privadas, y no sigue redirecciones: una respuesta 3xx cuenta como entrega fallida.
El secret de firma se muestra una sola vez, en el momento en que se da de alta la suscripción. Mozart no puede volver a mostrártelo después: si lo perdés, hay que dar de baja la suscripción y crear una nueva.
El secret tiene el formato whsec_<43 caracteres>. Lo vas a necesitar para verificar la firma de cada evento (ver abajo). Por defecto un webhook recibe los eventos de todas las carteras de tu organización. Si necesitás limitarlo a algunas, pedíselo a tu contacto en Mozart al registrarlo: la lista de carteras la configura Mozart. Las carteras demo y las organizaciones suspendidas no emiten eventos. Un webhook recién creado empieza a recibir eventos en menos de diez segundos.

Eventos disponibles

Los pagos que llegan dentro de un archivo de carga de cartera (por la plataforma o por el flujo de Carga de cartera de la API) no generan payment.registered: son una carga masiva de histórico, no un pago puntual. Sólo los pagos registrados individualmente —por POST /v1/payments, desde el panel, por un link de cobro, o al marcar una promesa de pago como cumplida— disparan el evento.

Forma del evento

Cada entrega es un POST a tu URL con este body:
data tiene exactamente la misma forma que el recurso equivalente en la API pública: un payment.registered trae el mismo objeto que devuelve GET /v1/payments/:id, un promise.created el mismo que lista GET /v1/promises, y un call.completed el mismo que GET /v1/calls (sin el bloque analysis, que sólo trae el detalle por id). id identifica la entrega — usalo para idempotencia (ver abajo) —, no la confundas con el id del recurso dentro de data. livemode es true para los eventos de carteras reales y false para los de carteras sandbox: si tu endpoint recibe los dos, usalo para no mezclar datos de prueba con los reales.

Verificar la firma

Cada entrega trae dos headers:
X-Mozart-Signature tiene dos partes separadas por coma: t es un timestamp Unix (segundos) y v1 es un HMAC-SHA256 en hexadecimal, calculado sobre el string "<t>.<body crudo>" con tu secret (whsec_...).
1

Recuperá el body crudo

Calculá la firma sobre los bytes exactos que llegaron, antes de parsear el JSON — cualquier framework que reformatee el body (indentación, orden de claves) invalida la comparación.
2

Recalculá el HMAC

Con tu secret, sobre "<t>." + body, y comparalo contra v1 en tiempo constante (nunca con ===/==, que corta apenas encuentra la primera diferencia y filtra información por temporización).
3

Chequeá la tolerancia de reloj

Rechazá la entrega si t está a más de ~5 minutos del momento actual — protege contra un replay de una entrega vieja capturada por un tercero.

Reintentos e idempotencia

Una entrega se considera exitosa con cualquier respuesta 2xx. Cualquier otra cosa —un error, un timeout— cuenta como fallo:
  • Cada intento tiene un timeout de 10 segundos.
  • Mozart intenta hasta 5 veces en total, con unos 90 segundos entre intentos: la ventana completa es de unos 6 minutos. Después del quinto intento fallido la entrega se marca como fallida y no se vuelve a reintentar. Hoy no hay un endpoint para reenviarla por tu cuenta.
  • Un reintento manda el mismo id de entrega. Usalo para no procesar dos veces el mismo evento si tu endpoint llega a recibirlo más de una vez.
Respondé 2xx apenas confirmes que recibiste el request, y procesá el evento aparte (una cola propia, un job en segundo plano). Si tu procesamiento tarda más de 10 segundos, Mozart lo va a contar como fallo y reintentar, aunque tu lado ya lo haya procesado.

Siguiente paso

Con webhooks cubiertos, revisá Paginación, errores y límites si todavía no lo hiciste, o volvé a Pagos y Carga de cartera para el resto de la escritura.