📍 Article principal : Dolibarr 23 ERP/CRM pour TPE-PME francophone. Ce tutoriel construit un module Mobile Money custom qui transforme Dolibarr en encaisseur Wave, Orange Money et MTN MoMo automatique.
L’écart entre l’émission d’une facture et son encaissement est l’ennemi numéro un de la trésorerie d’une TPE. Quand le client paie en Mobile Money, l’agent comptable doit aujourd’hui ouvrir l’application opérateur, vérifier la transaction, retrouver la facture correspondante dans Dolibarr et marquer manuellement le paiement. Cinq à dix minutes par règlement, autant d’erreurs et d’oublis. Le module custom décrit dans ce tutoriel automatise toute la chaîne : la facture porte un identifiant unique, le client paie en flashant un QR code, l’agrégateur Paydunya transmet la confirmation par webhook, Dolibarr marque la facture réglée et génère l’écriture comptable. Zéro intervention humaine, zéro erreur.
Prérequis
- Instance Dolibarr 23 fonctionnelle (voir tutoriel installation Coolify) avec module API REST activé
- Compte agrégateur Paydunya, CinetPay ou HUB2 (gratuit, validation KYC entreprise nécessaire)
- Domaine HTTPS public pour recevoir les webhooks (déjà en place via Coolify)
- Notions de PHP procédural et de webhooks HTTP
- Niveau : avancé
- Temps estimé : 4 à 6 heures pour un développeur PHP autonome
Étape 1 — Choisir et configurer l’agrégateur
Trois agrégateurs dominent le marché en 2026. Paydunya, basé à Dakar, couvre toute la zone UEMOA avec Wave, Orange Money, Free Money, MTN MoMo, Moov Money et Visa/Mastercard, à 1,5 % à 2 % par transaction. CinetPay, basé à Abidjan, propose des tarifs équivalents avec une expertise spécifique sur la Côte d’Ivoire. HUB2, plus jeune mais bien intégré chez les développeurs, propose une API REST très propre avec une couverture similaire.
Le choix dépend du pays principal d’activité. Pour ce tutoriel, on prend Paydunya car son écosystème est le mieux documenté et sa communauté de développeurs francophones est la plus active. Créer un compte sur app.paydunya.com, valider l’entreprise (KYC : RCCM, NINEA ou pièce du gérant, justificatif d’adresse), récupérer dans Intégration → API Keys les quatre tokens nécessaires : master-key, private-key, public-key, token. Toujours utiliser les clés live en production et les clés test en développement.
Étape 2 — Créer la structure du module Dolibarr
Dolibarr autorise les modules custom dans htdocs/custom/. Créer la structure standard avec un sous-dossier par fonction. Cette arborescence respecte les conventions Dolibarr et permettra une éventuelle publication sur DoliStore.
cd /var/www/dolibarr/htdocs/custom
mkdir -p mobilemoney/{core/modules,scripts,webhook,sql,langs/fr_FR}
touch mobilemoney/core/modules/modMobileMoney.class.php
touch mobilemoney/scripts/genqrcode.php
touch mobilemoney/webhook/paydunya.php
touch mobilemoney/sql/llx_mobilemoney_log.sql
chown -R www-data:www-data mobilemoney
Le fichier modMobileMoney.class.php hérite de DolibarrModules et déclare la définition du module : nom, description, version, droits d’accès, dictionnaires, hooks. Une fois ce fichier en place, le module apparaît dans Configuration → Modules → Modules custom. L’activer crée la table SQL llx_mobilemoney_log qui journalise tous les webhooks reçus.
Étape 3 — Générer un QR code de paiement par facture
Quand un commercial valide une facture dans Dolibarr, le module appelle l’API Paydunya pour créer une demande de paiement et reçoit en retour un token unique et une URL hébergée. Le token sert à générer un QR code que le client scanne pour payer en deux clics depuis son application Wave ou Orange Money.
// scripts/genqrcode.php (fragment)
require_once '../../main.inc.php';
$facture = new Facture($db);
$facture->fetch($id);
$payload = [
'invoice' => [
'total_amount' => (int)($facture->total_ttc),
'description' => 'Règlement facture '.$facture->ref,
'taxes' => [],
],
'store' => ['name' => 'MaSociété SARL'],
'custom_data' => ['facture_id' => $facture->id],
'actions' => [
'callback_url' => 'https://erp.masociete.sn/custom/mobilemoney/webhook/paydunya.php',
'cancel_url' => 'https://erp.masociete.sn/compta/facture/card.php?id='.$facture->id,
'return_url' => 'https://erp.masociete.sn/compta/facture/card.php?id='.$facture->id,
],
];
$ch = curl_init('https://app.paydunya.com/api/v1/checkout-invoice/create');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'PAYDUNYA-MASTER-KEY: '.PAYDUNYA_MASTER_KEY,
'PAYDUNYA-PRIVATE-KEY: '.PAYDUNYA_PRIVATE_KEY,
'PAYDUNYA-TOKEN: '.PAYDUNYA_TOKEN,
],
]);
$response = json_decode(curl_exec($ch), true);
$facture->array_options['options_paydunya_token'] = $response['token'];
$facture->array_options['options_paydunya_url'] = $response['response_text'];
$facture->update($user);
Cette logique est attachée à un hook doActions de Dolibarr qui se déclenche à la validation d’une facture. La facture stocke ainsi le token Paydunya dans un champ extra. Modifier ensuite le template PDF de facture pour intégrer le QR code généré à partir de l’URL retournée — la librairie qrcode.php incluse dans Dolibarr suffit. Le client reçoit la facture PDF par e-mail, scanne le QR code avec son téléphone, et paie en quelques secondes.
Étape 4 — Recevoir le webhook et marquer la facture
Une fois le paiement validé côté opérateur, Paydunya appelle l’URL callback_url renseignée précédemment avec un POST JSON contenant le statut et le custom_data. Le script webhook/paydunya.php vérifie l’authenticité du webhook (signature SHA-512), retrouve la facture concernée et enregistre le paiement.
// webhook/paydunya.php (fragment)
require_once '../../main.inc.php';
$payload = json_decode(file_get_contents('php://input'), true);
$signature = $_SERVER['HTTP_PAYDUNYA_HASH'] ?? '';
$expected = hash('sha512', PAYDUNYA_MASTER_KEY);
if (!hash_equals($expected, $signature)) { http_response_code(401); exit; }
if ($payload['status'] !== 'completed') { http_response_code(200); exit; }
$factureId = (int)$payload['custom_data']['facture_id'];
$montant = (float)$payload['invoice']['total_amount'];
$operateur = $payload['customer']['payment_method'] ?? 'inconnu';
$facture = new Facture($db);
$facture->fetch($factureId);
// Créer le paiement Dolibarr
$paiement = new Paiement($db);
$paiement->datepaye = dol_now();
$paiement->amounts = [$factureId => $montant];
$paiement->paiementid = 4; // Virement
$paiement->num_payment = $payload['token'];
$paiement->note_private = 'Mobile Money '.$operateur.' via Paydunya';
$idPaiement = $paiement->create($user);
$paiement->addPaymentToBank($user, 'payment', $payload['token'], BANK_ACCOUNT_MM, '', '');
// Journaliser
$db->query("INSERT INTO ".MAIN_DB_PREFIX."mobilemoney_log SET facture_id=$factureId, montant=$montant, operateur='".$db->escape($operateur)."', token='".$db->escape($payload['token'])."', date_creation=NOW()");
http_response_code(200);
La constante BANK_ACCOUNT_MM pointe vers un compte bancaire Dolibarr créé pour chaque opérateur (compte 521-Wave, 521-OrangeMoney, 521-MTN). Le rapprochement bancaire devient ainsi automatique, et l’expert-comptable retrouve les flux par opérateur en un clic à la fin du mois.
Étape 5 — Tester en bac à sable puis basculer en live
Toujours développer et tester en mode sandbox Paydunya avant la bascule production. Paydunya fournit un dashboard avec un simulateur qui déclenche manuellement les webhooks de test. Vérifier : la facture Dolibarr passe bien en statut Réglée, le paiement apparaît dans la table Paiements, l’écriture comptable est générée, le webhook est journalisé. Quand le scénario complet fonctionne en sandbox, basculer les clés API en live et faire un test réel à 100 XOF avec un téléphone personnel.
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| Webhook reçu mais facture non marquée | Mauvais champ custom_data ou erreur SQL silencieuse | Activer error_log PHP, journaliser systématiquement chaque webhook reçu |
| Double paiement enregistré | Paydunya retente le webhook après timeout | Implémenter une idempotency key sur le token Paydunya, ignorer si déjà traité |
| Signature SHA-512 invalide | Mauvaise master-key ou en-tête modifié par proxy | Vérifier la clé, désactiver les modules de manipulation d’en-tête côté Caddy |
| QR code illisible sur le PDF | Résolution trop faible ou contraste insuffisant | Générer en 300 dpi minimum, fond blanc strict, marge de quiet-zone respectée |
Adaptation au contexte ouest-africain
Pour les TPE qui facturent à l’international, garder une option de paiement par carte bancaire en parallèle du Mobile Money — Paydunya gère Visa/Mastercard à 2,5 %. Pour les pays hors UEMOA (Cameroun, Gabon, Nigeria), passer par un agrégateur multi-pays comme Flutterwave ou MFS Africa qui couvre 30+ opérateurs Mobile Money africains. Côté UX client, prévoir un fallback : si le QR code ne fonctionne pas (téléphone d’ancienne génération), proposer un numéro court à composer pour déclencher le paiement.
Tableau de bord des paiements Mobile Money
Une fois le module en production, l’équipe a besoin d’un tableau de bord temps réel qui affiche les transactions par opérateur, le ticket moyen, le taux d’échec, les délais de réversement. Créer une nouvelle entrée de menu Dolibarr Mobile Money → Tableau de bord qui interroge la table llx_mobilemoney_log et présente cinq blocs visuels : graphique en colonnes des paiements quotidiens du mois, camembert par opérateur (Wave/Orange/MTN/Free), liste des derniers paiements reçus avec lien direct vers la facture, liste des paiements en erreur ou en attente, indicateur de retard moyen entre paiement client et confirmation webhook.
L’implémentation utilise Chart.js (déjà inclus dans Dolibarr) pour les graphiques et un fichier dashboard.php dans le module qui regroupe les requêtes SQL agrégées. Les performances tiennent sans souci jusqu’à 100 000 transactions enregistrées avec un index sur (date_creation, operateur). Au-delà, ajouter un cache Redis ou MariaDB Memcached qui rafraîchit les agrégats toutes les cinq minutes — le tableau de bord reste réactif même en haute charge.
Réversement bancaire et rapprochement comptable
L’agrégateur Paydunya ne crédite pas instantanément le compte bancaire de la PME. Il accumule les paiements pendant un cycle (généralement 24 à 48 heures), prélève sa commission, puis vire le solde sur le compte SGBCI ou Ecobank de l’entreprise. Cette logique introduit deux étapes comptables distinctes : l’encaissement initial vers un compte 521-Paydunya (intermédiaire) au moment du webhook, et le réversement périodique en virement du compte 521-Paydunya vers 521-SGBCI quand le virement effectif est reçu.
Pour automatiser cette deuxième étape, deux approches. La première : importer chaque matin le relevé bancaire au format CIB (norme bancaire UEMOA) ou OFX et laisser Dolibarr rapprocher automatiquement les virements Paydunya entrants avec les soldes en attente. La seconde, plus puissante : récupérer les rapports Paydunya en API et générer automatiquement les écritures de réversement avec ventilation des commissions au compte 622-Services bancaires. Cette approche garantit un rapprochement comptable parfait et facilite l’audit en fin d’exercice.
Gérer les cas limites et les remboursements
Trois cas limites doivent être traités explicitement dans le module. Premier cas : le client paie deux fois la même facture. Cela arrive plus souvent qu’on ne le pense, par exemple si l’application Wave bug et que le client retape le montant. Le webhook Paydunya inclut un identifiant unique de transaction, à stocker en clé unique dans llx_mobilemoney_log. Quand un deuxième webhook arrive avec le même identifiant, le module détecte le doublon et déclenche automatiquement un remboursement par appel à /api/v1/disbursement.
Deuxième cas : le client demande un remboursement après réception d’une facture qu’il conteste. Le module expose un bouton Rembourser sur la fiche facture qui appelle l’API Paydunya, génère un avoir Dolibarr et marque la facture initiale en Remboursée. L’écriture comptable inverse l’écriture initiale : débit 411-Client, crédit 521-Paydunya. Pour rester conforme SYSCOHADA, ne jamais supprimer la facture originale — toujours créer un avoir.
Troisième cas : paiement reçu mais facture introuvable côté Dolibarr (le client a payé sans référence, ou la référence saisie est invalide). Le module met le paiement dans une zone Paiements en attente d’affectation où l’agent comptable peut associer manuellement la transaction à une facture après échange avec le client. Sans cette zone tampon, des paiements légitimes seraient automatiquement remboursés par erreur, ce qui détériore l’expérience client.
Audit de sécurité du module
Un module qui manipule des paiements doit être audité régulièrement. Cinq points à vérifier annuellement. Vérification de l’isolation des credentials Paydunya (jamais en clair dans Git, toujours en variables d’environnement chiffrées Coolify). Vérification de l’authenticité des webhooks (validation de la signature SHA-512 systématique, rejet automatique sans signature). Vérification du journal d’audit (chaque appel API et chaque webhook reçu doit être tracé avec horodatage). Vérification des permissions Dolibarr (seuls les utilisateurs avec le droit Comptabilité → Paiements peuvent annuler ou rembourser). Vérification des sauvegardes spécifiques au module (la table llx_mobilemoney_log doit être incluse dans le dump quotidien, et un test de restauration sur l’année doit être réalisable en moins de 30 minutes).
Notification client après paiement
Après confirmation du paiement Mobile Money, le client apprécie de recevoir une confirmation immédiate avec sa facture acquittée jointe. Étendre le webhook Paydunya pour qu’il déclenche, en plus de l’enregistrement dans Dolibarr, un envoi d’e-mail au client avec le PDF de la facture et un message de remerciement. La fonction $facture->sendByMail() de Dolibarr fait le travail en deux lignes de code, à condition que le SMTP soit correctement configuré.
Pour les clients qui n’ont pas d’e-mail, basculer sur un envoi WhatsApp via l’API Cloud : numéro client récupéré du tiers Dolibarr, message court avec lien d’accès au PDF stocké en URL signée temporaire (URL valable 7 jours pour permettre la récupération sans authentification mais éviter l’exposition durable). Cette double notification (e-mail + WhatsApp) augmente la satisfaction client mesurable et réduit les demandes de duplicata.
Statistiques par opérateur et négociation tarifaire
Au bout de quelques mois, les statistiques détaillées par opérateur fournissent un levier de négociation puissant avec Paydunya. Une PME qui passe 80 % de ses transactions par Wave peut négocier un tarif spécifique pour cet opérateur. Une PME dont le ticket moyen dépasse 50 000 XOF peut demander un palier dégressif sur les commissions. Préparer cette négociation en sortant chaque trimestre un rapport synthétique : nombre de transactions par opérateur, montant total, ticket moyen, taux d’échec, total des commissions versées.
Pour aller plus loin, comparer le coût réel Paydunya avec un branchement direct API d’opérateur. Wave Business propose en 2026 une API directe pour les marchands à 1 % de commission contre 1,5 à 2 % chez Paydunya. Le gain peut atteindre plusieurs millions de XOF par an pour une PME à fort volume, mais demande un développement spécifique et la gestion KYC directe avec l’opérateur. La règle : rester sur Paydunya tant que le volume mensuel est inférieur à 10 millions de XOF, basculer en API directe au-delà.
Gestion des litiges et chargebacks
Le Mobile Money introduit moins de litiges que la carte bancaire mais ils existent. Un client qui conteste une transaction auprès de l’opérateur déclenche une procédure de chargeback : l’opérateur prélève le montant sur le solde Paydunya de la PME et ouvre une enquête. Pour défendre la PME, conserver pour chaque paiement : le webhook Paydunya complet (preuve technique de la confirmation), le PDF de la facture associée, la trace de livraison ou de prestation rendue, l’éventuelle communication WhatsApp ou e-mail avec le client. Ce dossier de preuves transmis dans les 7 jours via le portail Paydunya retourne le chargeback dans la majorité des cas légitimes.
Mettre en place un module léger de gestion des litiges dans Dolibarr : nouvelle entrée de menu Mobile Money → Litiges, formulaire pour saisir une référence de chargeback, lien vers la facture concernée, statut (ouvert, en défense, résolu favorablement, perdu), commentaires datés. Cette traçabilité interne est précieuse en cas d’audit Paydunya ou de contrôle fiscal portant sur des écritures de remboursement.
Pour aller plus loin
🔝 Retour à l’article principal : Dolibarr 23 ERP/CRM pour TPE-PME francophone. Tutoriel précédent : installation Dolibarr sur Coolify. Documentation API Paydunya : paydunya.com/developers. Pour les TPE ivoiriennes, l’étape suivante consiste à intégrer la facturation FNE conforme DGI — sujet du tutoriel suivant de cette série.
Une fois le module en production, prévoir une revue trimestrielle des frais d’agrégateur facturés vs le volume traité — pour une TPE qui passe au-dessus de 5 000 000 XOF de transactions mensuelles, négocier un tarif dégressif avec Paydunya devient pertinent et peut faire économiser plusieurs centaines de milliers de francs par an. Tenir aussi un journal des incidents Mobile Money (paiements bloqués côté opérateur, délais de réversement) pour étayer toute discussion contractuelle.