Business Digital

n8n workflows Mobile Money : 4 cas pratiques 2026

18 دقائق للقراءة

📍 Série n8n — ce tutoriel fait partie du guide n8n auto-hébergé : déployer et automatiser. Pour la vue d’ensemble, commencez par là.

📍 Article principal du cluster : Automatisation pour PME ouest-africaines : le guide complet 2026
Cet article fait partie du cluster « Automatisation ». Pour la vue d’ensemble (no-code, low-code, code, IA agents), commencer par le pilier.

Le Mobile Money n’est plus un canal de paiement parmi d’autres en Afrique de l’Ouest : c’est le canal dominant. Au Sénégal, Wave revendique des millions d’utilisateurs avec sa tarification à 1 % capée à 5 000 FCFA, Orange Money compte près de 5 millions d’utilisateurs (Sonatel), et Mixx by Yas (anciennement Mixx by Yas (ex-Free Money)) propose un wallet unifié avec carte virtuelle. Aucun de ces opérateurs n’a de connecteur natif dans Zapier ou Make. n8n, lui, permet d’écrire en quelques nœuds des workflows complets de réception de paiement, de relance, de réconciliation et de génération de reçu. Ce tutoriel pas-à-pas vous livre quatre workflows JSON exportables, prêts à importer dans votre instance n8n self-hosted.

Prérequis

  • Une instance n8n self-hostée fonctionnelle (cf. n8n self-hosted 2026 : guide complet)
  • Un compte marchand Wave Business actif avec accès API (déclaration auprès de Wave Sénégal)
  • Un compte agrégateur (PayDunya ou InTouch) si vous voulez encaisser Orange Money / Mixx by Yas via une seule API
  • Un Google Sheet ou une base Airtable pour journaliser les paiements
  • Une passerelle de notification : bot Telegram (gratuit), API WhatsApp Business (Meta), ou Twilio
  • Temps estimé : 3 h pour les 4 workflows, 1 jour pour passer en production

Workflow 1 — Webhook Wave Business → Google Sheets + reçu WhatsApp

Le workflow le plus utile : à chaque paiement Wave reçu, on enregistre la transaction dans un Google Sheet de comptabilité et on envoie un reçu personnalisé au client via WhatsApp (ou Telegram). Cette automatisation supprime la saisie manuelle et améliore la perception du service client.

{
  "name": "Wave → Sheets + Reçu WhatsApp",
  "nodes": [
    {
      "parameters": { "httpMethod": "POST", "path": "wave-payment", "options": { "responseMode": "responseNode" } },
      "name": "Webhook Wave",
      "type": "n8n-nodes-base.webhook",
      "position": [200, 300]
    },
    {
      "parameters": {
        "conditions": { "string": [{ "value1": "={{ $json.event_type }}", "value2": "payment.completed" }] }
      },
      "name": "Si paiement confirmé",
      "type": "n8n-nodes-base.if",
      "position": [400, 300]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": "1abcDEF...id-de-votre-sheet",
        "sheetName": "Encaissements_Wave",
        "columns": { "values": {
          "Date": "={{ $json.timestamp }}",
          "Montant FCFA": "={{ $json.amount }}",
          "Téléphone client": "={{ $json.payer.phone }}",
          "Nom client": "={{ $json.payer.name }}",
          "Référence Wave": "={{ $json.reference }}",
          "Statut": "Confirmé"
        }}
      },
      "name": "Append Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [650, 200]
    },
    {
      "parameters": {
        "url": "https://api.telegram.org/bot{{$env.TG_TOKEN}}/sendMessage",
        "method": "POST",
        "sendBody": true,
        "bodyParameters": { "parameters": [
          { "name": "chat_id", "value": "={{$env.TG_CHAT_ID}}" },
          { "name": "text", "value": "💰 Paiement Wave reçu : {{ $json.amount }} FCFA de {{ $json.payer.name }} (réf : {{ $json.reference }})" }
        ]}
      },
      "name": "Notif Telegram interne",
      "type": "n8n-nodes-base.httpRequest",
      "position": [650, 400]
    },
    {
      "parameters": { "respondWith": "json", "responseBody": "={ \"ok\": true }" },
      "name": "Réponse 200",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [900, 300]
    }
  ],
  "connections": {
    "Webhook Wave": { "main": [[{ "node": "Si paiement confirmé", "type": "main", "index": 0 }]] },
    "Si paiement confirmé": { "main": [[{ "node": "Append Sheet", "type": "main", "index": 0 }, { "node": "Notif Telegram interne", "type": "main", "index": 0 }]] },
    "Append Sheet": { "main": [[{ "node": "Réponse 200", "type": "main", "index": 0 }]] }
  }
}

Côté Wave Business, déclarez l’URL https://n8n.votre-domaine.sn/webhook/wave-payment dans les paramètres marchands « Webhooks ». Wave POST cette URL à chaque événement de paiement (succès, échec, annulation). Le filtre If ne traite que les paiements complétés. La réponse 200 explicite est importante : sans elle, Wave réessaye plusieurs fois, créant des doublons dans la feuille.

Pour transformer la notification Telegram interne en reçu client WhatsApp, remplacez le nœud Telegram par un appel à l’API WhatsApp Business (Meta Cloud API) ou Twilio en utilisant le numéro du payeur. Comptez 5 à 15 minutes de configuration supplémentaire selon la passerelle choisie.

Workflow 2 — Orange Money / Mixx by Yas via PayDunya → Airtable

Pour encaisser Orange Money et Mixx by Yas sans intégrer chaque opérateur séparément, l’agrégateur PayDunya offre une API unifiée qui gère les deux (et bien d’autres) avec un seul webhook. Ce workflow capte les paiements PayDunya et les centralise dans une base Airtable structurée.

{
  "name": "PayDunya → Airtable",
  "nodes": [
    {
      "parameters": { "httpMethod": "POST", "path": "paydunya-ipn" },
      "name": "Webhook PayDunya",
      "type": "n8n-nodes-base.webhook",
      "position": [200, 300]
    },
    {
      "parameters": {
        "functionCode": "// Vérification signature PayDunya (méthode officielle 2026) :\n// PayDunya envoie dans le BODY le SHA-512 de votre MasterKey (pas un HMAC du payload).\n// On hashe localement la MasterKey et on compare au champ data.hash reçu.\nconst crypto = require('crypto');\nconst masterKey = $env.PAYDUNYA_MASTER_KEY;\nconst expectedHash = crypto.createHash('sha512').update(masterKey).digest('hex');\nconst receivedHash = $input.first().json.data.hash;\nif (expectedHash !== receivedHash) { throw new Error('Signature PayDunya invalide'); }\nif ($input.first().json.data.status !== 'completed') { throw new Error('Paiement non complété'); }\nreturn $input.all();"
      },
      "name": "Vérif signature",
      "type": "n8n-nodes-base.function",
      "position": [400, 300]
    },
    {
      "parameters": {
        "operation": "create",
        "application": "appXXXXXXXX",
        "table": "Encaissements",
        "fields": {
          "Référence": "={{ $json.invoice.token }}",
          "Montant FCFA": "={{ $json.invoice.total_amount }}",
          "Mode": "={{ $json.payment_method }}",
          "Client": "={{ $json.customer.name }}",
          "Téléphone": "={{ $json.customer.phone }}",
          "Date": "={{ $json.completed_at }}",
          "Statut": "={{ $json.status }}"
        }
      },
      "name": "Création Airtable",
      "type": "n8n-nodes-base.airtable",
      "position": [650, 300]
    }
  ],
  "connections": {
    "Webhook PayDunya": { "main": [[{ "node": "Vérif signature", "type": "main", "index": 0 }]] },
    "Vérif signature": { "main": [[{ "node": "Création Airtable", "type": "main", "index": 0 }]] }
  }
}

Le nœud Function qui vérifie la signature PayDunya est essentiel — sans cette étape, n’importe quel acteur sur Internet pourrait POST de fausses notifications de paiement à votre webhook et polluer (voire frauder) votre comptabilité. Méthode officielle PayDunya 2026 : PayDunya envoie dans le body de l’IPN un champ data.hash qui est le SHA-512 de votre MasterKey (et non un HMAC du payload, contrairement à Stripe ou GitHub). On hashe localement la MasterKey avec crypto.createHash('sha512') et on compare au hash reçu — c’est exactement ce que fait le code ci-dessus. La clé maître PayDunya est stockée en variable d’environnement n8n (Settings → Variables) et jamais en dur dans le workflow. Le champ payment_method remonte « ORANGE_SN_API_CASH_OUT », « FREE_SN_WALLET_CASH_OUT » (Mixx by Yas) ou « WAVE_SN_API_CASH_OUT » selon le canal — vérifier les codes exacts dans la doc PayDunya car ils peuvent varier selon votre intégration. Vous pouvez créer des vues filtrées Airtable par opérateur pour piloter les performances.

Workflow 3 — Réconciliation hebdomadaire Mobile Money vs ventes

Une fois par semaine (le lundi matin), on compare automatiquement les encaissements Mobile Money de la semaine écoulée avec les ventes enregistrées dans le système commercial. Tout écart est remonté par email à la direction financière. Cette réconciliation détecte les paiements manquants ou en double avant qu’ils ne deviennent des trous comptables.

{
  "name": "Réconciliation MoMo hebdo",
  "nodes": [
    {
      "parameters": { "rule": { "interval": [{ "field": "cronExpression", "expression": "0 8 * * 1" }] } },
      "name": "Lundi 8h",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [200, 300]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT SUM(montant) as total_ventes, COUNT(*) as nb_ventes FROM ventes WHERE date_vente BETWEEN CURRENT_DATE - INTERVAL '7 days' AND CURRENT_DATE - INTERVAL '1 day' AND mode_paiement IN ('wave','orange_money','mixx')"
      },
      "name": "Total ventes système",
      "type": "n8n-nodes-base.postgres",
      "position": [450, 200]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT SUM(montant_fcfa) as total_momo, COUNT(*) as nb_momo FROM encaissements_momo WHERE date_paiement BETWEEN CURRENT_DATE - INTERVAL '7 days' AND CURRENT_DATE - INTERVAL '1 day'"
      },
      "name": "Total encaissements MoMo",
      "type": "n8n-nodes-base.postgres",
      "position": [450, 400]
    },
    {
      "parameters": {
        "functionCode": "const ventes = $('Total ventes système').first().json;\nconst momo = $('Total encaissements MoMo').first().json;\nconst ecart = (momo.total_momo || 0) - (ventes.total_ventes || 0);\nreturn [{ json: { ventes: ventes.total_ventes, momo: momo.total_momo, ecart, nb_ventes: ventes.nb_ventes, nb_momo: momo.nb_momo } }];"
      },
      "name": "Calcul écart",
      "type": "n8n-nodes-base.function",
      "position": [700, 300]
    },
    {
      "parameters": {
        "fromEmail": "rapports@votre-pme.sn",
        "toEmail": "direction@votre-pme.sn",
        "subject": "Réconciliation Mobile Money — semaine {{ $today.subtract(7, 'days').format('DD/MM') }} au {{ $today.subtract(1, 'days').format('DD/MM') }}",
        "html": "<h2>Bilan hebdomadaire</h2><ul><li>Ventes système : {{ $json.ventes }} FCFA ({{ $json.nb_ventes }} transactions)</li><li>Encaissements MoMo : {{ $json.momo }} FCFA ({{ $json.nb_momo }} transactions)</li><li><strong>Écart : {{ $json.ecart }} FCFA</strong></li></ul>"
      },
      "name": "Email direction",
      "type": "n8n-nodes-base.emailSend",
      "position": [950, 300]
    }
  ],
  "connections": {
    "Lundi 8h": { "main": [[{ "node": "Total ventes système", "type": "main", "index": 0 }, { "node": "Total encaissements MoMo", "type": "main", "index": 0 }]] },
    "Total ventes système": { "main": [[{ "node": "Calcul écart", "type": "main", "index": 0 }]] },
    "Total encaissements MoMo": { "main": [[{ "node": "Calcul écart", "type": "main", "index": 0 }]] },
    "Calcul écart": { "main": [[{ "node": "Email direction", "type": "main", "index": 0 }]] }
  }
}

L’écart positif indique que des encaissements n’ont pas de vente associée (peut-être des doublons ou des paiements de tests à investiguer). L’écart négatif indique des ventes sans encaissement — typiquement des commandes payées en attente ou des erreurs de saisie. Un écart de zéro (cas idéal) confirme que la chaîne commerciale tourne. Pour étoffer le tableau, on peut ajouter un nœud If qui n’envoie l’email que si l’écart dépasse un seuil de tolérance (par exemple ± 10 000 FCFA).

Workflow 4 — Lien de paiement automatique dans email de facture

Quand une facture est émise dans votre logiciel comptable (ou WooCommerce, ou un Google Sheet de devis), on génère automatiquement un lien de paiement Wave/PayDunya unique et on l’inclut dans l’email envoyé au client. Le client paie en deux clics depuis son téléphone, et le webhook du workflow 1 ou 2 réconcilie la facture quand le paiement arrive.

{
  "name": "Facture → Lien de paiement Wave",
  "nodes": [
    {
      "parameters": { "httpMethod": "POST", "path": "nouvelle-facture" },
      "name": "Webhook nouvelle facture",
      "type": "n8n-nodes-base.webhook",
      "position": [200, 300]
    },
    {
      "parameters": {
        "url": "https://api.wave.com/v1/checkout/sessions",
        "method": "POST",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={ \"amount\": \"{{ $json.montant }}\", \"currency\": \"XOF\", \"client_reference\": \"{{ $json.reference_facture }}\", \"success_url\": \"https://votre-pme.sn/paiement-ok\", \"error_url\": \"https://votre-pme.sn/paiement-erreur\" }"
      },
      "name": "Créer session Wave",
      "type": "n8n-nodes-base.httpRequest",
      "position": [450, 300]
    },
    {
      "parameters": {
        "fromEmail": "facturation@votre-pme.sn",
        "toEmail": "={{ $('Webhook nouvelle facture').item.json.email_client }}",
        "subject": "Facture {{ $('Webhook nouvelle facture').item.json.reference_facture }} — paiement en ligne",
        "html": "<p>Bonjour {{ $('Webhook nouvelle facture').item.json.nom_client }},</p><p>Votre facture de {{ $('Webhook nouvelle facture').item.json.montant }} FCFA est disponible.</p><p><a href=\"{{ $json.wave_launch_url }}\">Payer par Wave</a></p>"
      },
      "name": "Email facture client",
      "type": "n8n-nodes-base.emailSend",
      "position": [700, 300]
    }
  ],
  "connections": {
    "Webhook nouvelle facture": { "main": [[{ "node": "Créer session Wave", "type": "main", "index": 0 }]] },
    "Créer session Wave": { "main": [[{ "node": "Email facture client", "type": "main", "index": 0 }]] }
  }
}

Côté logiciel comptable, configurez un déclencheur (hook ou plugin) qui POST chaque nouvelle facture à https://n8n.votre-domaine.sn/webhook/nouvelle-facture avec un JSON contenant montant, reference_facture, email_client, nom_client. Pour PayDunya, l’endpoint et la structure changent légèrement mais le principe reste identique. L’avantage cumulatif est énorme : en automatisant le triptyque facture envoyée → lien paiement inclus → encaissement réconcilié, vous gagnez plusieurs heures par semaine et accélérez le DSO de 30 à 50 % sur la base d’observations terrain.

Cas d’usage par profil de PME ouest-africaine

Les quatre workflows ci-dessus se combinent différemment selon le métier. Voici cinq profils PME courants en Afrique de l’Ouest et la combinaison de workflows qui leur apporte le meilleur rapport effort/bénéfice immédiat.

E-commerçant Mobile Money pur (boutique Instagram, livraison coursier). Workflows 1 + 4 prioritaires. Chaque commande génère un lien de paiement Wave envoyé automatiquement par WhatsApp ; quand le client paie, le webhook met à jour le statut commande et déclenche la préparation. Gain mesurable : passage de 30 à 70 % du taux de conversion sur les commandes confirmées sous 24 h, parce que le client n’a plus à recopier un numéro Wave dans son app.

Cabinet de conseil ou cabinet médical (services prépayés). Workflows 1 + 3 prioritaires. Les rendez-vous payants à l’avance arrivent par PayDunya ou Wave ; la réconciliation hebdomadaire permet de détecter les rendez-vous honorés mais non encaissés (et inversement). Pour les cabinets multisites, le rapport de réconciliation peut être ventilé par site dans une seule requête SQL.

Agence immobilière (loyers et frais d’agence). Workflow 4 surtout. Chaque quittance mensuelle générée par le logiciel comptable produit un email avec lien de paiement direct. Combiné avec un cron de relance (workflow non listé ici mais facile à dériver), le DSO baisse drastiquement — observation terrain : 20 à 30 % de paiements plus rapides quand le lien de paiement est inclus directement dans la quittance.

École privée ou centre de formation (frais scolaires). Workflow 4 + variante du workflow 2 pour Orange Money massif. Les parents paient les tranches mensuelles via le canal qui leur convient, n8n centralise tout dans une base élève, et le service comptabilité a un tableau de bord unique au lieu de jongler entre plusieurs apps marchandes. Gain : suppression de 1 à 2 jours par mois de saisie manuelle pour le service administratif.

SaaS local en B2C (apps mobiles, services en ligne). Les quatre workflows en cascade complète. La création de compte déclenche workflow 4 (lien de paiement abonnement), le paiement entrant alimente workflow 1 ou 2 (selon canal), un job hebdo workflow 3 vérifie qu’aucun abonnement actif n’a échappé à l’encaissement. C’est typiquement le pattern qu’on retrouve chez les startups ouest-africaines en croissance.

Sécurité des webhooks de paiement

Les webhooks de paiement sont une cible privilégiée pour les attaquants. Trois protections sont indispensables avant tout passage en production. Premier : vérification de signature HMAC (illustrée dans le workflow 2 pour PayDunya — Wave fournit aussi un mécanisme similaire). Sans cette vérification, n’importe qui peut POST de fausses notifications et polluer votre comptabilité ou déclencher de faux reçus.

Deuxième : idempotence. Configurez votre webhook pour gérer correctement les répétitions — Wave et PayDunya peuvent ré-essayer en cas de timeout réseau, vous risquez d’enregistrer le même paiement plusieurs fois. La parade : utiliser la référence unique du paiement comme clé primaire dans Airtable/Google Sheets, et faire un upsert plutôt qu’un insert systématique.

Troisième : journalisation indépendante. Chaque appel reçu sur un webhook de paiement doit être logué brut (avec horodatage et IP source) dans un fichier ou une table dédiée, séparée des données comptables. En cas d’incident ou de litige, ce log brut permet de reconstituer précisément ce qui s’est passé. Pour les détails techniques sur la centralisation des logs, voir Bash scripting pour sysadmin.

Erreurs fréquentes

Erreur Cause Solution
Doublons dans Google Sheets après paiement Pas d’idempotence, le webhook est rejoué Utiliser la référence Wave comme clé d’upsert, ou nœud Filter pour dédupliquer
Webhook ne reçoit jamais d’appels URL non déclarée côté marchand, ou workflow inactif Vérifier l’URL exacte dans le portail Wave Business, activer le workflow
Signature HMAC qui échoue toujours Encodage de la payload différent (espaces, ordre des clés) Calculer le HMAC sur le body brut tel qu’envoyé, pas sur le JSON re-sérialisé
Réconciliation hebdo qui montre des écarts énormes Ventes en cash non importées dans le système Filtrer la requête sur les modes de paiement Mobile Money uniquement
Échec du nœud HTTP Request vers Wave API Token API expiré ou IP non whitelistée Renouveler le token marchand, déclarer l’IP du VPS auprès de Wave
Reçu WhatsApp non délivré Numéro client mal formaté (manque indicatif) Normaliser le numéro avec un nœud Function avant l’appel API

Côté terrain : Sénégal et zone CEDEAO

Trois précisions terrain pour les PME sénégalaises, ivoiriennes et maliennes. Première : la disponibilité d’API marchand varie selon les opérateurs et les pays. Au Sénégal, Wave Business propose une API documentée publiquement, Orange Money via Sonatel demande une démarche commerciale plus formelle, Mixx by Yas suit le mouvement Free → Yas amorcé en 2024–2025. Pour démarrer rapidement sans démarche par opérateur, passer par un agrégateur (PayDunya, InTouch) est la voie la plus pragmatique.

Deuxième : le format des numéros de téléphone est crucial dans les workflows. Wave attend généralement le format +221XXXXXXXXX (avec indicatif), tandis que certains workflows internes manipulent 77XXXXXXX (sans indicatif). Un nœud Function de normalisation au début de chaque workflow évite les erreurs silencieuses.

Troisième : la latence vers les APIs des opérateurs. Wave et PayDunya hébergent leur infrastructure principale dans la région ouest-africaine ou en Europe, avec des latences typiques de 100 à 300 ms depuis un VPS Hetzner. Cette latence reste largement compatible avec les patterns webhooks asynchrones — pas d’inquiétude à avoir sur ce point, sauf si vous tentez de faire de la synchronisation temps réel avec un terminal de paiement.

FAQ

Quel est le coût d’utilisation des APIs Mobile Money en 2026 ?

Côté Wave Business : la commission marchand est intégrée à la grille tarifaire négociée à l’ouverture du compte (typiquement 1 à 1,5 % selon volume). Côté PayDunya / InTouch : commission de l’agrégateur en sus de celle de l’opérateur, généralement 0,5 à 2 % selon le pack. Les appels API en eux-mêmes sont gratuits — vous ne payez que les transactions effectivement traitées.

Faut-il passer par PayDunya ou intégrer chaque opérateur directement ?

PayDunya/InTouch pour démarrer vite (1 intégration = tous les opérateurs) et tester le marché. Intégration directe par opérateur quand le volume justifie d’économiser la marge de l’agrégateur (typiquement au-delà de 10 millions FCFA/mois encaissés). La plupart des PME restent sur l’agrégateur en permanence, le surcoût étant compensé par la simplicité.

Comment tester les webhooks Wave en sandbox ?

Wave Business propose un environnement de test (sandbox) accessible via le portail marchand. Vous pouvez simuler des paiements de test sans débit réel pour vérifier que vos webhooks reçoivent bien les notifications, que les workflows n8n traitent correctement les données, et que les sauvegardes/notifications fonctionnent. Indispensable avant tout passage en production.

Que faire en cas de paiement reçu mais workflow en panne ?

Wave et PayDunya conservent l’historique des transactions côté marchand et permettent de re-déclencher manuellement les webhooks depuis leur portail (« Re-send IPN »). Plus largement, gardez un journal indépendant des paiements bruts (table dédiée alimentée en premier dans le workflow) pour pouvoir rejouer la suite après réparation, sans perdre de données.

Est-il légal d’automatiser des reçus WhatsApp en Afrique de l’Ouest ?

Oui, à condition d’utiliser l’API officielle WhatsApp Business (Meta Cloud API) et de respecter les règles : obtenir le consentement implicite (le client a payé donc attend une confirmation) ou explicite, ne pas envoyer de messages marketing non sollicités. L’utilisation de WhatsApp non officiel (multi-comptes, scrapers) viole les conditions d’usage et expose à un bannissement.

Sources et références

Tutoriels frères du cluster automatisation

Pour creuser ce sujet

Mots-clés secondaires : Wave Business API, Orange Money API, Mixx by Yas, PayDunya n8n, webhook Mobile Money, réconciliation comptable Sénégal, automation paiement Afrique, lien de paiement Wave.

Poursuivre la série n8n

مشاركة