Documentación
Webhooks
Registra un endpoint HTTPS en el dashboard y recibe un evento firmado cada vez que un pago o un enlace cambia. El registro y el secreto son del propietario; la API no los expone.
Eventos
| type | Se emite cuando | data.object |
|---|---|---|
payment.succeeded | La pasarela confirma el checkout como pagado. | Payment |
payment.failed | Un método asíncrono falla tras el checkout. | Payment |
payment.canceled | La sesión de checkout expira o se cancela. | Payment |
payment_link.paid | El enlace queda liquidado por un pago exitoso. | PaymentLink |
payment_link.disabled | El propietario, una clave o un agente desactiva el enlace. | PaymentLink |
payment.invoiced | CFDI Express timbró la factura (CFDI) de un pago. | PaymentInvoice |
payment.invoice_failed | CFDI Express o el SAT rechazaron la factura; ve failureReason. | PaymentInvoice |
payment.invoice_cancelled | El SAT confirmó la cancelación de la factura. | PaymentInvoice |
ping | Pulsas Probar en el dashboard. | { message } |
{
"id": "evt_5f0c…",
"object": "event",
"type": "payment.succeeded",
"livemode": false,
"createdAt": "2026-09-09T15:04:05.000Z",
"data": {
"object": {
"object": "payment",
"id": "pay_…",
"status": "succeeded",
"amountCentavos": 2500,
"currency": "MXN",
"linkId": "pl_…",
"metadata": { "order_id": "1042", "source": "shopify" }
}
}
}Tanto Payment como PaymentLink incluyen la metadata del enlace (los pares clave/valor que definiste al crearlo o editarlo), así relacionas el evento con tu pedido o registro sin otra consulta. Es {} si no definiste ninguna.
Cada entrega lleva los encabezados Pagos-Event-Id, Pagos-Event-Type, Pagos-Livemode y Pagos-Signature. Los endpoints de pruebas y en vivo son independientes: un evento solo llega a los endpoints registrados en su modo.
Verificar la firma
Pagos-Signature: t=<segundos unix>,v1=<hex>, donde v1 es HMAC-SHA256 con tu secreto whsec_… sobre "<t>.<cuerpo crudo>". Calcula sobre los bytes originales, compara en tiempo constante y rechaza marcas de tiempo de más de cinco minutos.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyPagosSignature(rawBody, header, secret, toleranceSeconds = 300) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=", 2)));
const t = Number(parts.t);
if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
const given = Buffer.from(parts.v1 ?? "", "hex");
return given.length === expected.length && timingSafeEqual(given, expected);
}Responde rápido, procesa después
id: una entrega puede repetirse tras un timeout aunque tu servidor la haya procesado. Solo payment.succeeded confirma fondos.Entrega y reintentos
- Los eventos se escriben en la misma transacción que el cambio de estado, así que una notificación nunca se pierde ni se emite por un cambio revertido.
- Éxito es cualquier 2xx. Las redirecciones no se siguen y cuentan como fallo.
- Escalera de reintentos: 1 min, 5 min, 30 min, 2 h, 6 h, 12 h, 24 h (ocho intentos). Después la entrega queda en
failedy puedes reenviarla desde el dashboard. - Cada fallo incrementa
consecutiveFailuresdel endpoint; a los 100 se desactiva automáticamente y el propietario debe reactivarlo.
Seguridad
- Los secretos son
whsec_más 43 caracteres, se muestran una vez y pueden rotarse al instante desde el dashboard. - Las URL deben ser HTTPS públicas: se rechazan credenciales en la URL,
localhost, rangos privados y hosts.internal/.local. - Hasta 10 endpoints por cuenta y modo. Timeout de 10 segundos por entrega.