Aller au contenu
Depuis le 17 octobre 2026, un nouveau compte nyole encaisse à travers un outil de l'écosystème : LinkAfr, Griotia ou Wapilot. Cette documentation sert aux comptes ouverts avant cette date. Voir les outils

Vérifier la signature

Chaque webhook est signé avec votre clé secrète. Vérifiez la signature avant de traiter quoi que ce soit : sans cela, n’importe qui connaissant votre URL pourrait vous faire croire à un paiement.

En-tête Contenu
X-Afriflow-Timestamp Horodatage Unix (secondes) de l’envoi
X-Afriflow-Signature t=<horodatage>,v1=<HMAC-SHA256 en hexadécimal>
  1. Récupérez le corps de la requête brut, exactement tel que reçu (pas le JSON reparsé puis re-sérialisé).

  2. Concaténez <horodatage>.<corps brut>.

  3. Calculez le HMAC-SHA256 de cette chaîne avec votre clé secrète af_live_sec_....

  4. Comparez en temps constant avec la valeur v1 de l’en-tête. Refusez si l’horodatage a plus de 5 minutes (protection contre le rejeu).

Express
import crypto from "node:crypto";
import express from "express";
const app = express();
function verifierSignature(corpsBrut, entetes, secret) {
const ts = entetes["x-afriflow-timestamp"];
const sig = (entetes["x-afriflow-signature"] || "")
.split(",").find((p) => p.startsWith("v1="))?.slice(3);
if (!ts || !sig) return false;
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // 5 minutes
const attendu = crypto.createHmac("sha256", secret).update(`${ts}.${corpsBrut}`).digest("hex");
return attendu.length === sig.length
&& crypto.timingSafeEqual(Buffer.from(attendu), Buffer.from(sig));
}
// Le corps doit rester BRUT : express.raw, pas express.json
app.post("/webhooks/nyole", express.raw({ type: "application/json" }), (req, res) => {
const brut = req.body.toString("utf8");
if (!verifierSignature(brut, req.headers, process.env.NYOLE_SECRET_KEY)) {
return res.status(400).send("signature invalide");
}
const evt = JSON.parse(brut);
if (evt.event === "payment.completed") {
// Marquez la commande evt.data.metadata.order_id comme payée.
// Rendez ce traitement idempotent : le même événement peut arriver deux fois.
}
res.sendStatus(200); // répondez vite, traitez le reste en tâche de fond
});