Flutter et Mobile Money : SDK Kkiapay, FedaPay sans SDK officiel
Le paquet kkiapay_flutter_sdk, le paquet tiers feda_flutter (AGPL-3.0 ou licence commerciale) et une architecture où le serveur seul confirme le paiement, relus dans les documentations et les dépôts.
Flutter et Mobile Money : SDK Kkiapay, FedaPay sans SDK officiel
Dans une application mobile, le téléphone ouvre le paiement, mais il ne doit jamais décider qu'il a réussi : c'est le rôle de votre serveur.
Réponse courte. Pour encaisser par Mobile Money dans une application Flutter, Kkiapay publie un paquet, kkiapay_flutter_sdk, qui ouvre le paiement dans une WebView. FedaPay n'en publie pas : sa page des SDK liste PHP, Node.js, Ruby, React et Angular, et les paquets Flutter de FedaPay sur pub.dev sont tiers. L'un d'eux, feda_flutter, est sous licence AGPL-3.0 ou commerciale, et son README recommande pour la production un serveur intermédiaire. Dans les deux cas, la règle qui évite les pertes d'argent est la même : l'application déclenche le paiement, le serveur le vérifie par l'API de l'agrégateur, et l'application ne fait qu'afficher l'état que le serveur lui donne.
Transparence. BOVO Digital est une agence basée au Bénin qui développe des applications Flutter : nous avons donc un intérêt dans le sujet. Cet article ne repose sur aucune donnée, aucun client et aucun résultat de BOVO. Il lit des pages pub.dev, un dépôt GitHub et des documentations publiques, consultés le 7 novembre 2026. Nous n'avons pas exécuté ces paquets : ce qui relève de notre raisonnement est écrit comme tel.
Les trois paquets, côte à côte
Valeurs relevées sur pub.dev (kkiapay_flutter_sdk, feda_flutter, feda) et sur l'API de pub.dev le 7 novembre 2026.
| kkiapay_flutter_sdk | feda_flutter | feda | |
|---|---|---|---|
| Dernière version stable | 1.3.4, 22 avril 2025 (prérelease 1.4.0-beta2, 5 décembre 2025) | 1.0.1, 22 mars 2026 | 0.0.3, 2 mars 2023 |
| Licence | MIT | AGPL-3.0 ou licence commerciale | MIT |
| Éditeur affiché | « unverified uploader » | ashgateway.com | non affiché |
| Mentions « j'aime » | 27 | 2 | 6 |
| Contrainte du SDK Dart | >=3.3.3 <4.0.0 | ^3.0.0 | >=2.18.1 <3.0.0 |
| Plateformes | Android, iOS, web | Android, iOS, macOS, web | Android, iOS, Windows, Linux, macOS |
Trois lectures, les nôtres. Le paquet Kkiapay est celui que la documentation de Kkiapay présente (page « SDK Flutter »), mais sa dernière version stable a plus de dix-huit mois. Le paquet feda_flutter est récent, mais très peu utilisé. Le paquet feda n'a pas bougé depuis 2023 et sa borne <3.0.0 sur Dart signifie qu'un projet Dart 3 ne devrait pas pouvoir le résoudre : nous ne l'avons pas testé.
Le principe : l'application ouvre, le serveur confirme
Les articles précédents ont détaillé les webhooks de paiement Mobile Money et les passerelles du point de vue développeur. Sur mobile, la même logique s'applique avec une raison de plus : le code qui tourne sur le téléphone n'est pas sous votre contrôle. Ce que dit chaque documentation va dans ce sens :
- FedaPay, page « Gestion des clés API » : les clés publiques peuvent être utilisées côté client et ne permettent que des actions limitées ; les clés secrètes donnent un accès complet, et il ne faut jamais en intégrer dans des applications mobiles. Pour le côté client, la page demande d'utiliser les clés publiques ou des points de terminaison serveur intermédiaires.
- Kkiapay, page « Developers » : la clé publique peut être intégrée côté client (la page cite le JavaScript et Android) ; la clé privée est destinée au serveur et permet de vérifier les transactions ; la clé secrète est aussi réservée au serveur.
Le schéma qui en découle est notre recommandation, pas une exigence écrite :
- L'application demande à votre serveur de créer la commande et, selon l'agrégateur, la transaction.
- L'application ouvre le paiement (WebView du SDK Kkiapay, ou lien de paiement FedaPay).
- L'utilisateur valide sur son téléphone, auprès de l'opérateur.
- L'agrégateur prévient votre serveur par webhook.
- Le serveur relit la transaction par l'API avec ses clés privées, compare statut, montant et référence, puis marque la commande comme payée, une seule fois.
- L'application demande l'état à votre serveur et l'affiche.
Le callback que le SDK déclenche sur le téléphone n'intervient qu'à l'étape 2 : il sert à fermer l'écran de paiement et à lancer l'étape 6, pas à livrer.
Option 1 : le SDK Kkiapay
Ce que dit le README. Le paquet ouvre le paiement dans une WebView sur mobile (« Create payment webview instance », puis Navigator.push avec l'objet KKiaPay). Sur le web, il faut ajouter le script k.js de Kkiapay dans index.html et appeler KkiapayFlutterSdkPlatform.instance.pay. Les paramètres de KKiaPay marqués obligatoires dans le bloc d'utilisation sont callback, amount, apikey (la clé publique) et sandbox. Voici l'initialisation, recopiée du README avec des valeurs factices :
final kkiapay = KKiaPay(
amount: 1000,
apikey: 'CLE_PUBLIQUE_FACTICE',
sandbox: true,
phone: '22961000000',
paymentMethods: ['momo', 'card'],
callback: (response, context) {
switch (response['status']) {
case PAYMENT_SUCCESS:
// response['transactionId'] : à envoyer à VOTRE serveur,
// pas à traiter comme une preuve de paiement.
break;
case PAYMENT_CANCELLED:
Navigator.pop(context);
break;
default:
break;
}
},
);
Les constantes PAYMENT_SUCCESS, PAYMENT_CANCELLED, PAYMENT_INIT et PENDING_PAYMENT viennent de l'exemple du README. Le commentaire sur l'envoi de transactionId à votre serveur est le nôtre.
Les pièges relevés dans le paquet.
- Une documentation qui se contredit. Dans le tableau de référence du README, le paramètre de succès s'appelle
successCallbacketphoneest obligatoire ; le bloc d'utilisation et l'exemple écriventcallback, et ne marquent pasphonecomme obligatoire. Nous n'avons pas compilé le paquet : testez avant de vous fier à l'un ou l'autre. - Pas d'événement d'échec documenté. L'exemple du README ne traite que quatre statuts, sans cas d'échec. Le journal des modifications indique, pour la version 1.3.0-dev.4, « Remove payment_failed event ». Notre lecture, non testée : un paiement refusé ne produit peut-être pas de callback distinct. Prévoyez donc un délai et une relecture côté serveur plutôt que d'attendre un événement d'échec.
- La clé publique est la seule à mettre dans l'application. Le champ
apikeydu README est décrit comme « public api key ». Les clés privée et secrète de Kkiapay servent à la vérification et au serveur. - Des dépendances à surveiller. Le fichier
pubspecdu paquet déclare notammentstacked,stacked_services,webview_flutter,url_launcherethttp. Elles s'ajoutent à votre application et à vos mises à jour. - Une maintenance stable mais lente. Version stable de 2025, prérelease de décembre 2025. Le README ne parle ni de vérification de signature ni de webhook.
La vérification côté serveur. La page du SDK Node de Kkiapay (paquet @kkiapay-org/nodejs-sdk) décrit une fonction verify qui prend l'identifiant de transaction et renvoie, dans son exemple, un status (« SUCCESS »), un amount, un transactionId et un partnerId. Elle s'initialise avec les trois clés et un indicateur sandbox. C'est le moyen documenté de comparer ce que l'application affirme à ce que Kkiapay a enregistré. Le champ partnerId du SDK Flutter est décrit comme « Your id to find transaction » : notre idée, non testée, est d'y mettre l'identifiant de votre commande pour la retrouver.
Option 2 : FedaPay, sans SDK Flutter officiel
La page des SDK de FedaPay liste des SDK serveur (PHP, Node.js, Ruby) et des composants web (React, Angular). Rien pour Flutter ni Dart. Deux chemins restent.
Chemin A : votre serveur parle à FedaPay, l'application ouvre un lien. Il s'appuie uniquement sur les pages d'API de FedaPay lues. Le serveur crée la transaction (POST /transactions, avec description, amount, currency.iso et une clé secrète en Bearer), puis demande le lien de paiement : la page « Get the payment link for a transaction » décrit POST /transactions/{id}/token, qui renvoie un token et une url. L'application ouvre cette url dans une WebView ou dans le navigateur. Le statut se lit ensuite par GET /transactions/{id} (valeurs données en exemple : « pending », « approved », « canceled »), et le webhook prévient le serveur. Le paiement par Mobile Money reste validé sur le téléphone de l'utilisateur, auprès de son opérateur.
Chemin B : un paquet tiers. Le seul que nous ayons lu en détail est feda_flutter.
- Ce qu'il offre (README) : des dépôts typés pour les transactions, les clients et les paiements sortants, un widget
PayWidgetqui crée la transaction et ouvre le paiement, une WebView sur mobile, une redirection vers le navigateur avec relecture périodique du statut sur le web. - Deux modes d'initialisation.
applyConfig(apiKey: 'sk_...')appelle l'API de FedaPay directement avec une clé secrète. Le README le présente comme « Legacy & Testing » et l'écarte pour la production.applyCloudConfig(projectKey, cloudUrl)passe par un serveur intermédiaire : le README recommande pour la production un « Cloud Proxy (like ashgateway) » et donnehttps://ashgateway.comen exemple. Ce domaine est aussi celui de l'éditeur affiché sur pub.dev. Nous n'avons pas lu les conditions de ce service ni évalué qui y voit vos clés ou vos paiements. - Contradiction avec FedaPay. Le mode direct met une clé secrète dans le binaire de l'application, ce que la page FedaPay sur les clés interdit. Le fichier
SECURITY.mddu dépôt recommande de ne pas coder les clés en dur, de passer par un échange de jetons côté serveur (exemple Dart Frog dans le dépôt) et de recevoir les confirmations côté serveur par l'URL de rappel. - Maintenance. Le dépôt GitHub (
Blasterx7/feda_flutter) compte 4 étoiles, 7 tickets ouverts (tous des propositions de mise à jour de dépendances), et son dernier commit date du 26 octobre 2026. Le paquet a été créé en octobre 2025 et la version 1.0.0 date de mars 2026. Cela dit qu'il est suivi, pas qu'il est éprouvé.
Notre lecture : pour FedaPay, le chemin A évite d'ajouter une dépendance peu utilisée et un tiers dans le flux de paiement. Le chemin B se justifie si vous acceptez la licence, le tiers et les risques décrits plus bas.
Licences : AGPL-3.0 ou commerciale
Le paquet feda_flutter est annoncé « dual-licensed » sur pub.dev et dans son README : AGPL-3.0, ou licence commerciale « for closed-source or commercial use », à demander par courriel à l'auteur. Le fichier LICENSE_COMMERCIAL.md du dépôt ajoute que l'utilisation commerciale sans licence commerciale valide est interdite.
Ce que dit le texte de l'AGPL-3.0, que nous avons relu :
- la section 5(c) demande, lorsque vous diffusez une œuvre fondée sur le programme, de placer l'œuvre entière sous cette licence ;
- la section 6 demande de fournir le code source correspondant avec le code objet ;
- la section 13 ajoute une obligation pour les versions modifiées accessibles à distance par un réseau.
Notre lecture, qui n'est pas un avis juridique : une application Flutter compilée avec ce paquet relève probablement de la section 5(c), ce qui poserait problème à une application dont le code doit rester fermé. Nous ne l'avons pas vérifié, et la phrase du fichier commercial sur l'« usage commercial » ne se concilie pas facilement avec une licence libre qui autorise l'usage commercial : seul l'auteur peut dire ce qu'il entend. Si vous livrez une application à un client, demandez la licence commerciale par écrit ou n'utilisez pas le paquet, et gardez une copie de la réponse.
Les paquets kkiapay_flutter_sdk et feda sont sous licence MIT d'après pub.dev. Vérifiez aussi les licences de leurs dépendances, ce que nous n'avons pas fait.
L'état du paiement dans l'application, et le réseau instable
Un téléphone passe en zone sans couverture, l'application est tuée par le système, la WebView se ferme sur un écran blanc. Ce qui suit est notre raisonnement, pas une règle des agrégateurs.
| État affiché | Qui le décide | Ce que fait l'application |
|---|---|---|
| Commande créée | serveur | ouvre le paiement |
| Paiement ouvert | application | n'affirme rien, interroge le serveur |
| En attente de confirmation | serveur | affiche « vérification en cours », réessaie, ne relance pas un autre paiement |
| Payée | serveur, après relecture par l'API | affiche le reçu |
| Échouée ou annulée | serveur, après relecture ou délai | propose de réessayer |
Quatre habitudes en découlent :
- Une commande, un paiement en cours à la fois. Si l'utilisateur rouvre l'application, elle demande d'abord l'état de la commande au serveur avant de proposer de repayer. Sans cela, un paiement validé mais jamais vu par l'application est payé une seconde fois.
- L'état est stocké côté serveur et relu au démarrage. Si l'application est tuée pendant le paiement, c'est le serveur, alerté par le webhook, qui a la bonne réponse.
- La connectivité ne se déduit pas d'un indicateur. Le README du paquet
connectivity_plusprécise qu'un type de connexion disponible ne garantit pas un accès à Internet (exemple : un Wi-Fi à portail captif). Traitez un échec réseau comme « inconnu », pas comme « échoué ». - Les demandes de création sont idempotentes. Si l'application renvoie la demande de création après une coupure, le serveur doit retrouver la commande existante au lieu d'en créer une deuxième, avec les mêmes garde-fous que pour les doublons de webhook décrits dans l'article sur les webhooks.
Checklist de neuf points
- Aucune clé secrète ou privée d'agrégateur dans l'application ni dans le dépôt de l'application.
- Le paiement est créé et suivi par votre serveur ; l'application ne transmet que l'identifiant de commande.
- Le callback du SDK ne sert qu'à fermer l'écran et à demander l'état au serveur.
- Le serveur relit la transaction par l'API avant de livrer : statut, montant, devise, référence.
- Le webhook est reçu, dédupliqué et surveillé comme décrit dans l'article sur les webhooks.
- La licence de chaque paquet est lue, et la réponse écrite de l'auteur est conservée si elle est commerciale.
- La date de dernière version, les dépendances et l'éditeur de chaque paquet sont vérifiés le jour du choix.
- Les parcours échec, annulation, fonds insuffisants et coupure réseau sont testés en sandbox (numéros de test de Kkiapay dans son guide).
- L'application gère un retour tardif : paiement validé après la fermeture de la WebView.
Ce que nous ne savons pas
- Le comportement réel des paquets. Nous avons lu des README, des journaux de modifications et des fichiers
pubspec, nous n'avons exécuté aucun paquet sur un téléphone. - Le callback d'échec de
kkiapay_flutter_sdk. Existe-t-il un statut distinct après un refus ? Le README n'en montre pas, le journal indique la suppression depayment_faileden 1.3.0-dev.4. - La nature de la version 1.4.0-beta2 de Kkiapay. Nous n'avons pas lu ce qu'elle change.
- L'éditeur de
kkiapay_flutter_sdk. pub.dev l'affiche comme « unverified uploader ». La documentation de Kkiapay renvoie à ce paquet, mais nous n'avons pas de confirmation écrite de Kkiapay sur son statut de paquet officiel. - Le service ashgateway. Conditions, tarifs, hébergement, journalisation : non lus.
- La portée de l'AGPL-3.0 sur une application fermée, et le sens exact de la mention « commercial » du fichier de licence : à demander à l'auteur et à un juriste.
- Les numéros de test de FedaPay, introuvables dans la documentation consultée.
- Les règles des magasins d'applications sur les paiements externes pour les biens numériques : nous ne les avons pas relues pour cet article.
- Le comportement de la WebView (cookies, redirections d'applications d'opérateurs, boutons retour) sur vos appareils cibles.
Sources consultées le 7 novembre 2026
- pub.dev, kkiapay_flutter_sdk (README, journal des modifications, versions, licence MIT) et API de pub.dev.
- Kkiapay, SDK Flutter, menu Developers, SDK Node.js (pages non datées).
- pub.dev, feda_flutter, sa licence et API de pub.dev ; dépôt GitHub (README, LICENSE_COMMERCIAL.md, SECURITY.md, CHANGELOG.md, tickets).
- pub.dev, feda et API de pub.dev.
- FedaPay, SDK, gestion des clés API, Get a transaction, Create a transaction, lien de paiement (pages non datées).
- pub.dev, connectivity_plus (README).
Pour aller plus loin
Pour le coût d'une application, voir le prix d'une application Flutter ; pour la démarche, créer une application mobile ; pour le choix du framework, Flutter ou React Native. Pour le contexte du marché, la lecture du rapport BCEAO sur le Mobile Money au Bénin.
Vous voulez une application Flutter avec un paiement Mobile Money vérifié côté serveur et des licences lues avant la livraison ? Découvrez notre agence de développement d'applications mobiles au Bénin.
Étiquettes
FAQ
FedaPay a-t-il un SDK officiel pour Flutter ?
Pas d'après la page des SDK de FedaPay, consultée le 7 novembre 2026 : elle liste PHP, Node.js, Ruby, React et Angular, et ne mentionne ni Flutter ni Dart. Des paquets tiers existent sur pub.dev, par exemple feda_flutter, mais ils ne sont pas publiés par FedaPay.
Le paquet feda_flutter est-il utilisable dans une application commerciale ?
Son dépôt annonce une double licence : AGPL-3.0, ou licence commerciale à demander à l'auteur. Le texte de l'AGPL-3.0 prévoit, quand on diffuse une œuvre dérivée, de la placer en entier sous cette licence et de fournir le code source. Nous ne sommes pas juristes et n'avons pas tranché le cas d'une application fermée : écrivez à l'auteur et faites relire la licence avant de livrer.
Peut-on mettre la clé secrète FedaPay dans l'application Flutter ?
Non. La page de FedaPay sur la gestion des clés demande de ne jamais intégrer de clé secrète dans des applications mobiles, et de passer par les clés publiques ou par un point de terminaison serveur intermédiaire. Le mode direct de feda_flutter, qui prend une clé secrète, est présenté par son propre README comme réservé aux prototypes.
Le callback de succès du SDK Kkiapay suffit-il pour livrer une commande ?
Non, c'est notre recommandation. Ce callback s'exécute sur le téléphone, que l'utilisateur ou un logiciel modifié peut manipuler. La documentation Kkiapay prévoit une vérification côté serveur (fonction verify du SDK Node) et un webhook : c'est là qu'il faut confirmer le statut, le montant et la référence avant de livrer.
Que faire si le réseau coupe pendant le paiement ?
Ne pas considérer le paiement comme échoué et ne pas en relancer un deuxième aussitôt. Gardez la commande à l'état « en attente de confirmation » côté serveur, laissez l'application interroger votre serveur au retour du réseau, et laissez le webhook mettre l'état à jour. Ce schéma est notre raisonnement, pas une exigence écrite des documentations.
Votre site prend-il des rendez-vous — ou il présente ?
On ouvre votre URL ensemble, on pointe les 3 fuites, on vous dit si une optimisation suffit ou s’il faut refondre.
- 30 min
- Sans engagement
- Plan d’action

Singbo Davy AGONMA
Développeur Fullstack & Expert IA. Spécialiste automatisation n8n, développement Laravel/Flutter et intégration d'agents IA. Master CS — IFRI.
