SDK Flutter
Encaisser par carte dans une application mobile Flutter.
Principe
Le paiement se fait sur la page hébergée Mobupay (widget Monext) : la carte ne transite jamais par votre application. Vous présentez cette page de deux façons, au choix :
- WebView in-app (recommandé) : la page s'affiche dans un écran de votre application (votre barre d'app et votre marque, sans barre d'URL ni croix de navigateur). C'est le rendu le plus intégré.
- Navigateur système : la page s'ouvre dans Chrome Custom Tabs (Android) ou ASWebAuthenticationSession (iOS). Plus robuste pour la 3-D Secure, mais affiche l'URL Mobupay.
Dans les deux cas, la saisie carte reste sur la page hébergée : aucun champ carte natif n'est possible (Mobupay est agent non-PSP, votre application reste hors périmètre PCI DSS). Au retour, confirmez toujours la commande via le webhook signé reçu par votre backend.
Règle de sécurité
- Ne jamais embarquer de clé
sk_…dans l'app (elle serait extractible du binaire). La session est créée par votre backend, qui renvoie lecheckoutUrlà l'app. - Le statut lu au retour n'est pas une preuve de paiement. La vérité vient du webhook signé côté serveur : confirmez la commande via votre backend.
Installation
dependencies:
mobupay: ^0.2.0presentInApp s'appuie sur webview_flutter (v4.4+). present (navigateur système) s'appuie sur flutter_web_auth_2 (v5+).
Utilisation recommandée : WebView in-app
import 'package:mobupay/mobupay.dart';
// 1. Votre backend crée la session (avec sk_) et renvoie checkoutUrl.
final checkoutUrl = await monBackend.creerSessionMobupay(montant: 2500);
// 2. La page hébergée s'affiche DANS l'app (WebView native, thémable).
final result = await MobupayCheckout.presentInApp(
context: context,
checkoutUrl: checkoutUrl,
theme: const MobupayCheckoutTheme(
title: 'Paiement sécurisé',
appBarColor: 0xFF13C1C7, // votre couleur de marque
),
);
// 3. Confirmez via votre backend (webhook signé), pas via result.
if (result.outcome == MobupayCheckoutOutcome.returned) {
await monBackend.confirmerCommande();
}Comportement au succès : si un email a été fourni au paiement, le reçu est envoyé par email et la WebView se ferme automatiquement ; sinon la page reçu Mobupay s'affiche dans l'app avec un bouton « Terminé ». La 3-D Secure (redirection vers la banque) n'est jamais interceptée. Aucune configuration de schéma ou d'App Links n'est nécessaire pour ce mode.
MobupayCheckoutTheme personnalise seulement le cadre natif (barre d'app : couleur, texte, titre, cadenas, bouton fermer, indicateur de chargement). La page de paiement elle-même reste la page hébergée Mobupay.
Alternative : navigateur système
import 'package:mobupay/mobupay.dart';
final checkoutUrl = await monBackend.creerSessionMobupay(montant: 2500);
final result = await MobupayCheckout.present(
checkoutUrl: checkoutUrl,
callbackUrlScheme: 'https', // App Links (recommandé) ; ou votre schéma custom
);
if (result.outcome == MobupayCheckoutOutcome.returned) {
await monBackend.confirmerCommande();
}Pour un retour fiable vers l'app avec ce mode, le redirectUrl de la session doit être une URL https revendiquée par votre app (Android App Links, iOS Universal Links). Un schéma custom (monapp://) est possible mais moins fiable (certains navigateurs bloquent la navigation vers un schéma externe).
- 1Hébergez
/.well-known/assetlinks.json(Android) etapple-app-site-association(iOS) sur le domaine duredirectUrl, avec l'empreinte de signature de l'app. - 2Déclarez l'
intent-filterautoVerify(Android) et l'associated domain (iOS) pour ce domaine. - 3Utilisez
redirectUrl: https://votre-domaine/paiement-retourà la création de session.
Client API (backend / test uniquement)
final client = MobupayClient('sk_test_…'); // jamais sk_live_ dans une app distribuée
final session = await client.createCheckoutSession(
reference: 'CMD-1042',
amount: MobupayClient.toMinorUnits(25.00, 'EUR'), // 2500
currency: 'EUR',
redirectUrl: 'https://votre-domaine/paiement-retour',
notificationUrl: 'https://votre-domaine/mobupay-webhook',
externalId: '1042',
customerEmail: 'client@exemple.nc', // optionnel : masque le champ email + reçu par email
);
final paiement = await client.retrievePayment(session.paymentId);
await client.refund(session.paymentId); // total
await client.refund(session.paymentId, amount: 1000); // partielcustomerEmail est optionnel : s'il est fourni, le champ email n'est pas demandé sur la page hébergée et le reçu est envoyé par email (avec presentInApp, la WebView se ferme alors automatiquement au succès).
Tester
Avec une clé sk_test_…, lancez le paiement et réglez sur la page Mobupay avec la carte de test Monext 5476 4309 9999 9892 (CVV 123, expiration future). Devises : EUR et XPF (montants en unité mineure via toMinorUnits).