DolaPay
DolaPay Developers

Webhooks & Callbacks

Que vous utilisiez l'API de Paiement (avec redirection ou en direct sans redirection) ou l'API de Retrait (Décaissement), les transactions Mobile Money sont asynchrones. Pour être notifié instantanément du succès ou de l'échec d'une transaction, vous devez configurer et écouter nos Webhooks.

Événements d'Encaissement (Paiements)

transaction.success

Déclenché dès qu'un client valide son paiement (qu'il vienne d'une redirection Checkout Session ou d'une requête API Directe sans redirection). C'est le signal pour vous de valider la commande.

transaction.failed

Déclenché si le paiement échoue (fonds insuffisants, annulation par le client sur son téléphone, ou délai d'attente dépassé).

Événements de Décaissement (Retraits API)

payout.success

Déclenché lorsque votre requête de retrait via l'API (Décaissement B2C) est traitée et que les fonds sont effectivement arrivés sur le numéro de destination.

payout.failed

Déclenché si l'envoi des fonds au destinataire a échoué (numéro erroné, plafond atteint sur le compte de destination). Le montant est alors automatiquement re-crédité sur votre solde DolaPay.

Sécuriser vos endpoints (Vérification HMAC)

Comme votre URL de Webhook sera publiquement accessible sur Internet, vous devez vous assurer que seules les requêtes provenant de DolaPay sont traitées. Pour cela, nous signons chaque webhook envoyé avec un système HMAC SHA-256.

Où trouver ma clé secrète de Webhook ?

La clé de signature des Webhooks est différente de votre clé d'API secrète. Vous pouvez la trouver dans votre Tableau de bord > Développeurs > Webhooks.

Structure du Header de Signature

L'en-tête HTTP x-dolapay-signature contient le timestamp de l'événement et la signature calculée, séparés par une virgule.

x-dolapay-signature: t=1710000000,v1=ab23c4d5e6f7...
javascript
import crypto from "crypto";
import express from "express";

const app = express();
const WEBHOOK_SECRET = process.env.DOLAPAY_WEBHOOK_SECRET;

app.post("/webhooks/dolapay", express.raw({ type: "application/json" }), (req, res) => {
  const signatureHeader = req.headers["x-dolapay-signature"];
  const payload = req.body.toString();
  
  // 1. Extraire le timestamp et la signature du header
  const parts = signatureHeader.split(',');
  const timestamp = parts.find((p: string) => p.startsWith('t=')).split('=')[1];
  const signature = parts.find((p: string) => p.startsWith('v1=')).split('=')[1];
  
  // 2. Recréer la chaîne à signer : "timestamp.payload"
  const signedPayload = `${timestamp}.${payload}`;
  
  // 3. Calculer le HMAC SHA-256 avec votre Webhook Secret
  const expectedSignature = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(signedPayload)
    .digest('hex');
    
  // 4. Comparer les signatures de manière sécurisée
  if (crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
    const event = JSON.parse(payload);
    
    // Traiter les événements d'encaissement (Paiement)
    if (event.type === "transaction.success") {
      console.log("Paiement validé :", event.data.id);
      // Valider la commande du client...
    }
    
    // Traiter les événements de décaissement (Retrait API)
    if (event.type === "payout.success") {
      console.log("Retrait API effectué avec succès :", event.data.id);
      // Mettre à jour le statut du retrait côté serveur...
    }
    
    // Il est très important de répondre avec un 200 OK rapidement
    res.status(200).send("Webhook reçu");
  } else {
    res.status(401).send("Signature invalide");
  }
});

Politique de Retry

Si votre serveur ne répond pas avec un statut HTTP 200 OK ou s'il est indisponible, DolaPay tentera de renvoyer le webhook plusieurs fois avec un back-off exponentiel pour garantir la livraison.

Immédiat5 min30 min2 heures12 heures