VentiPay te permite recibir notificaciones de eventos ocurridos en tu cuenta de comercio utilizando webhooks.
Los webhooks son particularmente útiles cuando necesitas tomar acciones asincrónicas en tu sistema en base a un evento, por ejemplo, cuando se renueva exitosamente una suscripción.
Eventos disponibles
Actualmente te podemos notificar cuando ocurren los siguientes eventos:
- Cuando se crea un checkout (checkout.created).
- Cuando se paga un checkout (checkout.paid).
- Cuando se cancela un checkout (checkout.canceled).
- Cuando se reembolsa un checkout (checkout.refunded).
- Cuando se crea una suscripción (subscription.created).
- Cuando comienza el periodo de trial de una suscripción (subscription.trialing).
- Cuando se activa o renueva una suscripción (subscription.activated).
- Cuando se atrasa una suscripción (subscription.past_due).
- Cuando se marca como impaga una suscripción (estado terminal) (subscription.unpaid).
- Cuando se cancela una suscripción (estado terminal) (subscription.canceled).
- Cuando se crea un invoice (invoice.created).
- Cuando un invoice pasa a estado draft (invoice.draft).
- Cuando un invoice pasa a estado open (invoice.open).
- Cuando un invoice se da por pagado (invoice.paid).
- Cuando un invoice se marca como incobrable (invoice.uncollectible).
- Cuando un invoice se encuentra en modo de reintento automático de cobro (invoice.retrying).
- Cuando un invoice se marca como anulada (invoice.void).
Cómo crear un webhook
El primer paso para agregar un webhook a tu integración con VentiPay, es crear un endpoint en tu sistema que reciba y procese la notificación.
Este endpoint es como cualquier ruta o página existente en tu sistema. Si utilizas, por ejemplo, Express debes crear una nueva ruta, si utilizas PHP debes crear un nuevo archivo .php, etc.
Por cada evento ocurrido, VentiPay realizará a tu nuevo endpoint una solicitud tipo POST en la que se incluirá data asociada al evento.
Qué data recibes
Al ser notificado del evento, recibirás un payload de tipo JSON (application/json) con los siguientes atributos:
- id: Representa un ID único del evento (string).
- type: Representa el tipo de evento recibido (string).
- live: Indica si el evento ocurrió en modo live o test (boolean).
- data: Objeto relacionado al evento, por ejemplo una suscripción o un pago (object).
Cómo responder a un webhook
Es importante que respondas de manera exitosa lo más rápido posible a la solicitud enviada por VentiPay.
Se considera una respuesta exitosa cualquiera con un código de estado HTTP del rango 2xx
, sin importar el contenido enviado. Todo otro estado, incluidas las redirecciones, serán consideradas como erroneas.
Si tu endpoint no responde exitosamente seguiremos intentando enviar la notificación de manera automática, sin embargo si no recibimos una respuesta exitosa al 3er día, la notificación se considerará fallida y no intentaremos nuevamente. Usualmente el espacio entre cada intento es de 1 hora.
Cómo validar un webhook
Opcionalmente podrás validar que el mensaje recibido haya sido enviado por VentiPay y no por terceros. Para esto, cada notificación incluye una firma que permite verificar la validez del mensaje.
La firma del mensaje la podrás encontrar en la cabecera venti-signature
dentro de la solicitud recibida en tu endpoint.
Antes de verificar la validez, primero deberás rescatar el secreto de firma del webhook desde el Dashboard.
Este secreto de firma se utiliza para recrear la firma y compararla con la firma recibida en tu endpoint. Debes considerar de que cada webhook tiene su propio secreto de firma.
La cabecera de firma es un string que contiene un timestamp y una firma, ambos separados por una coma (,
). El timestamp (UNIX epoch) se indica con el prefijo t=
y la firma con el prefijo v1=
. Este prefijo indica la versión del schema utilizado. Actualmente solo existe el schema v1, pero podrían existir otros en el futuro.
t=1608681600,
v1=ba6773cda175388cc23156970add41ac4bb1254629dfd465b540e839c8690696
Para facilitar la lectura en esta documentación, cada valor se ha separado con una línea nueva, sin embargo la firma real viene en una única línea.
VentiPay genera la firma utilizando un código de autentificación de mensajes en clave-hash (HMAC) con SHA-256.
Pasos para verificar la validez del mensaje
Paso 1: Primero debes separar la cabecera en ítems por coma (,
) y luego separar cada ítem por el signo igual (=
). Esto te entregará el timestamp en la llave t
y la firma en la llave v1
.
Paso 2: Luego debes construir un string de verificación concatenando los siguientes valores: el timestamp (como string), el carácter .
, y finalmente la representación como string del payload JSON recibido. El string resultante tendrá la forma <timestamp>.<payload>
.
Paso 3: Luego debes calcular el HMAC del string de verificación utilizando SHA-256 y el secreto de firma del webhook como secreto de tu función de hashing.
Paso 4: Finalmente debes comparar la igualdad de la firma recibida en la solicitud y la firma calculada. Si ambas son iguales, puedes considerar que el mensaje es válido.
Evitar ataques de replay
Un ataque de replay ocurre cuando un atacante intercepta el payload y firma de una solicitud para luego repetirla. Para mitigar este tipo de ataques es que se incluye el timestamp en la cabera de firma. Ya que el timestamp también es parte del mensaje firmado, cualquier cambio a este valor invalida el mensaje completo.
Cada vez que se realiza la llamada a tu endpoint se genera una nueva firma con el timestamp del momento en el que se creó la llamada, por lo tanto si un mensaje es válido pero el timestamp muy antiguo, tu sistema debiera ignorarlo. Te recomendamos considerar una tolerancia de 5 minutos.