Webhooks
Get notified of events in real time, server to server.
Events
| Event | Emitted when |
|---|---|
payment.confirmed | Payment confirmed on-chain. |
payment.failed | Payment failed (amount, network, timeout). |
conversion.settled | USDT → FCFA conversion locked. |
payout.settled | Mobile Money payout sent. |
Verify the signature
Verify the signature (Node.js)
js
import { createHmac, timingSafeEqual } from "node:crypto";
export function signatureValide(corpsBrut, entete, secret) {
const attendu = createHmac("sha256", secret).update(corpsBrut).digest("hex");
const a = Buffer.from(attendu);
const b = Buffer.from(entete ?? "");
// Longueurs différentes : timingSafeEqual lève au lieu de rendre false.
if (a.length !== b.length) return false;
// Comparaison à temps CONSTANT : un === fuite la position du premier octet
// faux, ce qui suffit à reconstituer la signature par essais successifs.
return timingSafeEqual(a, b);
}Signature required
ALWAYS verify the signature before processing a webhook, and reject anything outside the timestamp window. The signature is an HMAC-SHA256 of "timestamp.body" — the RAW body, before any parsing — sent in X-Coinnective-Signature, with the timestamp in X-Coinnective-Timestamp. Without the check, anyone guessing the URL could forge an event; without the window, an intercepted webhook would stay replayable forever.
