Referencia API
Webhooks
Cabeceras de entrega, payloads de eventos, reintentos y registros de entrega.
URL de callback
Configura la URL de callback del equipo en los ajustes de integración de desarrollador. MakePay revisa primero la configuración de producto MakePay y luego la configuración compartida de callback de desarrollador, para que los ajustes existentes de webhooks MakeSwap puedan recibir eventos de pago MakePay mientras se despliega la configuración específica del producto.
Cuando guardas una URL de callback MakePay, MakeCrypto genera un secreto de webhook. Guárdalo en el gestor de secretos de tu backend. Puedes regenerarlo en cualquier momento desde la misma pantalla de ajustes; después de regenerarlo, actualiza tu backend antes de exigir firmas con el nuevo secreto.
Comportamiento de entrega
MakePay envía webhooks de pago y suscripción como solicitudes POST con cuerpo JSON. Las entregas fallidas se reintentan hasta diez veces a intervalos de cinco minutos. El reenvío manual está disponible desde los registros de solicitudes de webhook de MakeCrypto.
Cabeceras
content-type: application/json
user-agent: MakePay-Webhooks/1.0
x-makepay-delivery-id: 9f1c6cf4-8514-4ee5-80fd-8e8fe2b5e313
x-makepay-delivery-group-id: 9f1c6cf4-8514-4ee5-80fd-8e8fe2b5e313
x-makepay-delivery-origin: event
x-makepay-event: status_changed
x-makepay-attempt: 1
x-makepay-signature: t=1776556800,v1=7d4b3f...
Verificar firmas
MakePay firma el cuerpo JSON bruto exacto con HMAC-SHA256. El payload de firma es:
{timestamp}.{raw_request_body}
La cabecera x-makepay-signature contiene el timestamp Unix y el digest versionado:
t=1776556800,v1=<hex_hmac_sha256>
Ejemplo de verificación en Node.js:
import crypto from "node:crypto";
const WEBHOOK_SECRET = process.env.MAKEPAY_WEBHOOK_SECRET!;
const TOLERANCE_SECONDS = 300;
export function verifyMakePayWebhook(input: {
rawBody: string;
signatureHeader: string | null;
}) {
if (!input.signatureHeader) {
return false;
}
const parts = Object.fromEntries(
input.signatureHeader.split(",").map((part) => {
const [key, value] = part.trim().split("=");
return [key, value];
}),
);
const timestamp = Number(parts.t);
const signature = parts.v1;
if (!Number.isFinite(timestamp) || !signature) {
return false;
}
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - timestamp) > TOLERANCE_SECONDS) {
return false;
}
const expected = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(`${timestamp}.${input.rawBody}`, "utf8")
.digest("hex");
const actualBuffer = Buffer.from(signature, "hex");
const expectedBuffer = Buffer.from(expected, "hex");
return (
actualBuffer.length === expectedBuffer.length &&
crypto.timingSafeEqual(actualBuffer, expectedBuffer)
);
}
Lee el cuerpo bruto antes de parsear JSON. Si tu framework parsea el cuerpo primero, configura la ruta de webhook para exponer los bytes brutos y verifica esos bytes antes de confiar en el payload.
Payload de pago
{
"deliveryId": "9f1c6cf4-8514-4ee5-80fd-8e8fe2b5e313",
"type": "makepay.payment.status_changed",
"createdAt": "2026-04-19T00:00:00.000Z",
"event": {
"type": "status_changed",
"trigger": "payment_status_reconcile"
},
"paymentLink": {
"id": "8d15bb78-d0f8-45ef-88d7-2a1f1f79644b",
"uid": "01hzy4k6p4w9y2x7e2z7n8a2xm",
"status": "active",
"publicUrl": "https://makepay.io/payment/01hzy4k6p4w9y2x7e2z7n8a2xm",
"expiresAt": "2026-04-19T12:00:00.000Z",
"amount": "129.99",
"currency": "USDT",
"asset": "ETH.USDT-0xdac17f958d2ee523a2206206994597c13d831ec7",
"label": "Website order #1042",
"description": "Checkout for order #1042",
"merchantOrderId": "order_1042",
"clientEmail": "buyer@example.com",
"clientId": null
},
"session": {
"id": "5b55f0bb-0ac4-4f7c-a1d1-0d9af19c3bbd",
"status": "complete",
"previousStatus": "pending",
"invoiceAsset": "USDT",
"invoiceAmount": "129.99",
"selectedSellAsset": "ETH",
"requiredSellAmount": "0.04",
"expectedBuyAmount": "129.99",
"destinationAddress": "0xmerchant...",
"depositAddress": "0xdeposit...",
"channelId": "channel_123",
"compositeChannelId": "ETH:channel_123",
"sourceChain": "ETH",
"expiresAt": "2026-04-19T00:30:00.000Z",
"settlement": {},
"errorMessage": null
}
}
Tipos de evento
status_changedpara cambios de estado de la sesión de pago.settlement_updatedcuando cambian datos de liquidación tras la conciliación de estado.payment_request_expired,quote_expiredypayment_cancelled_by_payerpara resultados terminales sin pago.channel_createdcuando el pagador acepta una cotización y MakePay crea el canal de depósito.subscription_status_changedcuando una suscripción MakePay se mueve entreactive,paused,overdueocancelled.
quote_created y quote_refreshed son eventos internos del timeline de pago y no se envían a URLs de callback.
Payload de estado de suscripción
MakePay también envía un callback cuando cambia el estado de una suscripción. El scheduler marca una suscripción como overdue cuando el ciclo de facturación impago más antiguo lleva al menos 24 horas pasado su dueAt; cuando ningún ciclo impago supera esas 24 horas, el scheduler vuelve a mover la suscripción a active. Los cambios de estado desde merchant y portal de cliente usan el mismo callback.
{
"deliveryId": "78c35c42-61fb-4dd3-94b7-2a7df998bb6f",
"type": "makepay.subscription.status_changed",
"createdAt": "2026-04-20T00:00:00.000Z",
"event": {
"type": "subscription_status_changed",
"trigger": "subscription_scheduler"
},
"subscription": {
"id": "f6b76460-a437-4a81-a59f-8fcbb18c0f0f",
"uid": "sub_premium_001",
"status": "overdue",
"previousStatus": "active",
"customerEmail": "buyer@example.com",
"label": "Premium plan",
"description": "Monthly subscription",
"amountUsd": "49.99",
"settlementAsset": "ETH.USDT-0xdac17f958d2ee523a2206206994597c13d831ec7",
"cadence": "monthly",
"billingIntervalUnit": "month",
"billingIntervalCount": 1,
"startAt": "2026-04-18T00:00:00.000Z",
"timezone": "Asia/Dubai",
"metadata": {
"clientId": "client_1042"
},
"createdAt": "2026-04-18T00:00:00.000Z",
"updatedAt": "2026-04-20T00:00:00.000Z"
},
"cycle": {
"id": "f303b3b3-26d8-42bc-8c10-91fa1445f507",
"subscriptionId": "f6b76460-a437-4a81-a59f-8fcbb18c0f0f",
"sequence": 0,
"dueAt": "2026-04-18T00:00:00.000Z",
"amountUsd": "49.99",
"paymentLinkId": "8d15bb78-d0f8-45ef-88d7-2a1f1f79644b",
"paymentLinkUid": "01hzy4k6p4w9y2x7e2z7n8a2xm",
"paymentUrl": "https://makepay.io/payment/01hzy4k6p4w9y2x7e2z7n8a2xm",
"status": "overdue"
},
"data": {
"previousStatus": "active",
"nextStatus": "overdue",
"reason": "cycle_one_day_overdue"
}
}
API de registros de entrega
Usa la ruta de solicitudes de webhook para inspeccionar entregas y reintentos.
GET /api/partner/v1/makepay/webhook-requests?limit=100
Los filtros opcionales incluyen paymentLinkUid, deliveryStatus y search.