API request
VERIFY webhook-signature
Verify X-Mainmoney-Signature on incoming webhook payloads.
# Verify HMAC-SHA256 signature (pseudo)
# signature = HMAC_SHA256(webhook_secret, raw_request_body)Configure webhookUrl on your app in the Developer dashboard.
X-Mainmoney-EventX-Mainmoney-Signature — HMAC-SHA256 of raw JSON bodypayment_link.payment.completedpayment_link.payment.failed{
"event": "payment_link.payment.completed",
"id": "...",
"created": "2026-06-14T12:00:00.000Z",
"data": {
"reference": "order-123",
"paymentLinkId": "...",
"slug": "...",
"amount": 5000,
"currency": "CDF",
"status": "COMPLETED",
"environment": "SANDBOX"
}
}
terminal_payment.completedterminal_payment.failedterminal_payment.cancelledterminal_payment.expiredFull payload, headers, and signature details: Terminal payment webhooks.
{
"event": "terminal_payment.completed",
"id": "...",
"created": "2026-07-27T10:12:00.000Z",
"data": {
"id": "clx...",
"merchantReference": "crm-order-1001",
"metadata": { "table": "12" },
"terminalId": "POS-ABC123-001",
"businessId": "...",
"amount": 1.03,
"currencyCode": "USD",
"status": "COMPLETED",
"paymentMethod": "PHONE",
"paymentRequestId": "...",
"environment": "SANDBOX"
}
}
import crypto from "node:crypto";
function verify(rawBody, signatureHeader, webhookSecret) {
const expected = crypto
.createHmac("sha256", webhookSecret)
.update(rawBody)
.digest("hex");
return expected === signatureHeader;
}
Delivery attempts are logged in Event Logs → Webhooks in the dashboard (filter by payment link or terminal payment source).