L'intégration MonCash est simple, mais certaines erreurs reviennent systématiquement chez les développeurs qui commencent. Voici un diagnostic direct des 8 problèmes les plus fréquents et les corrections exactes.
Erreur 1 — Signature HMAC invalide
Symptôme : votre endpoint webhook renvoie 401 ou refuse les requêtes. Cause la plus fréquente : vous calculez le HMAC sur le JSON parsé (object JavaScript) plutôt que sur le raw body (Buffer ou string brut).
// ❌ Mauvais — req.body est déjà parsé
const hmac = crypto.createHmac("sha256", secret).update(JSON.stringify(req.body));
// ✅ Correct — utiliser le raw body avant tout parsing
app.use("/webhook", express.raw({ type: "application/json" }));
const hmac = crypto.createHmac("sha256", secret).update(req.body); // BufferErreur 2 — Webhook non reçu en production
Vérifiez dans cet ordre : (1) l'URL webhook dans votre dashboard est bien HTTPS, pas HTTP ; (2) votre certificat SSL est valide (pas auto-signé) ; (3) votre pare-feu autorise les connexions entrantes sur le port 443 ; (4) l'URL répond dans les 5 secondes.
Erreur 3 — orderId déjà existant
// ❌ orderId basé sur la date — collision possible avec les requêtes simultanées
const orderId = "order-" + Date.now();
// ✅ UUID v4 garanti unique
import { randomUUID } from "node:crypto";
const orderId = randomUUID(); // ex: "f47ac10b-58cc-4372-a567-0e02b2c3d479"Erreur 4 — Webhooks reçus en double
MonCashConnect retente les webhooks si votre serveur répond non-200 ou dépasse 5 secondes. La solution : répondre 200 immédiatement, puis traiter de manière asynchrone. Stockez les event.id traités pour dédupliquer.
app.post("/webhook/moncash", async (req, res) => {
// 1. Vérifier la signature
if (!verifySignature(req.body, req.headers["x-moncashconnect-signature"])) {
return res.status(401).end();
}
const event = JSON.parse(req.body);
// 2. Dédupliquer — vérifier si event.id déjà traité
const already = await db.processedEvents.findFirst({ where: { id: event.id } });
if (already) return res.sendStatus(200); // ignorer le retry
// 3. Répondre 200 immédiatement
res.sendStatus(200);
// 4. Traiter de manière asynchrone
await processPaymentEvent(event);
await db.processedEvents.create({ data: { id: event.id } });
});Erreur 5 — Clé API utilisée côté client
Si vous voyez votre clé sk_proj_… dans le code JavaScript de votre frontend (inspecter la source), elle est exposée publiquement. Toute personne peut l'utiliser pour créer des paiements en votre nom. Déplacez immédiatement l'appel API côté serveur.
Erreur 6 — Marquer la commande payée sur la returnUrl
La returnUrl (page de succès) peut être visitée par n'importe qui en ajoutant l'orderId dans l'URL. Ne jamais marquer une commande comme payée sur cette page — uniquement sur réception d'un webhook signé vérifié.
Erreur 7 — Timeout webhook en développement
En local, votre serveur n'est pas accessible depuis Internet — MonCashConnect ne peut pas envoyer les webhooks. Utilisez ngrok pour exposer votre localhost en HTTPS et configurez l'URL générée comme webhook temporaire dans votre dashboard.
Erreur 8 — Utiliser les clés de prod en sandbox
Les clés sk_test_… ne fonctionnent qu'avec les endpoints sandbox. Les clés sk_proj_… sont pour la production uniquement. Si votre environnement de dev utilise des clés de prod, chaque test crée de vraies transactions. Utilisez impérativement les bonnes clés dans chaque environnement.
Les Webhook Logs du dashboard MonCashConnect conservent les 100 derniers événements avec payload et statut. C'est l'outil de debug le plus efficace pour les problèmes d'intégration.
Consulter la documentation des webhooks →