S
SFE NAFA
SFE NAFA Docs

Webhooks

Recevoir des notifications en temps réel lors d'événements sur votre compte SFE NAFA.

Webhooks

Les webhooks permettent à SFE NAFA d'envoyer des notifications HTTP en temps réel vers votre serveur lorsque des événements surviennent.

Configurer un webhook

  1. Allez dans Paramètres → API → Webhooks
  2. Cliquez sur Nouveau webhook
  3. Entrez l'URL de votre endpoint (doit être HTTPS)
  4. Sélectionnez les événements à écouter
  5. Copiez le secret de signature

L'URL du webhook doit être accessible depuis Internet et répondre en moins de 5 secondes.

Événements disponibles

ÉvénementDéclencheur
invoice.createdNouvelle facture créée
invoice.validatedFacture validée
invoice.sentFacture envoyée par email
invoice.paidFacture entièrement payée
invoice.overdueFacture passée en retard
invoice.cancelledFacture annulée
payment.createdPaiement enregistré
client.createdNouveau client créé
stock.lowProduit sous le seuil d'alerte

Format du payload

{
  "id": "evt_01HX...",
  "type": "invoice.paid",
  "createdAt": "2026-05-15T14:32:00Z",
  "data": {
    "id": "clx1234abcd",
    "reference": "FAC-2026-0042",
    "totalTTC": 590000,
    "currency": "XOF",
    "client": {
      "id": "clx5678efgh",
      "name": "SARL MonClient"
    }
  }
}

Bonnes pratiques de traitement

  • Vérifiez systématiquement la signature avant tout traitement.
  • Traitez les événements de façon idempotente via event.id.
  • Répondez rapidement 200 OK, puis déléguez le traitement lourd à une file de tâches.

Vérifier la signature

Chaque requête webhook inclut un en-tête X-SFE-Signature contenant un HMAC-SHA256 du payload signé avec votre secret.

import crypto from "crypto";
import express from "express";

function verifyWebhookSignature(payload, signature, secret) {
  if (!signature) return false;

  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex");

  const expectedBuffer = Buffer.from(expected, "utf8");
  const signatureBuffer = Buffer.from(signature, "utf8");

  if (expectedBuffer.length !== signatureBuffer.length) {
    return false;
  }

  return crypto.timingSafeEqual(expectedBuffer, signatureBuffer);
}

// Dans votre handler
app.post(
  "/webhook/sfenafa",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const signature = req.headers["x-sfe-signature"];
    const payload = req.body;

    const isValid = verifyWebhookSignature(
      payload,
      Array.isArray(signature) ? signature[0] : signature,
      process.env.WEBHOOK_SECRET,
    );

    if (!isValid) {
      return res.status(401).send("Signature invalide");
    }

    const event = JSON.parse(payload.toString("utf8"));

    // Idempotence: ignorez l'événement s'il a déjà été traité
    // if (await hasEventBeenProcessed(event.id)) return res.status(200).send("OK");

    // Traitement de l'événement...
    // await markEventAsProcessed(event.id)

    res.status(200).send("OK");
  },
);

Utilisez toujours timingSafeEqual pour la comparaison afin d'éviter les attaques timing.

Politique de retry

Si votre endpoint retourne un code autre que 2xx, SFE NAFA réessaie automatiquement :

TentativeDélai
1èreImmédiat
2ème5 minutes
3ème30 minutes
4ème2 heures
5ème24 heures

Après 5 échecs, le webhook est désactivé automatiquement et vous recevez une notification email.

Checklist de mise en production

  • Endpoint HTTPS exposé publiquement avec certificat valide.
  • Signature vérifiée avant tout traitement métier.
  • Idempotence implémentée sur event.id.
  • Timeout applicatif inférieur à 5 secondes pour la réponse HTTP.
  • Traitements lourds asynchrones (queue/job) après accusé de réception.
  • Alerting configuré sur les taux d'échec et désactivations de webhook.

Gestion des incidents

Si des événements ne sont pas traités correctement :

  1. Vérifiez les logs de livraison côté webhook (codes HTTP, latence, payload).
  2. Identifiez la fenêtre temporelle impactée.
  3. Rejouez les événements manquants depuis votre journal interne des événements reçus.
  4. Contrôlez l'absence de doublons via la clé d'idempotence event.id.

Conservez une trace des événements reçus pendant au moins 30 jours pour faciliter les reprises.

Tester un webhook

Depuis Paramètres → API → Webhooks → [Votre webhook] → Tester, envoyez un événement de test vers votre endpoint.

Vous pouvez aussi consulter les Logs pour voir toutes les tentatives d'envoi et les réponses reçues.