Flutter Templates
Créer une application de commerce électronique avec Flutter, Back4App et intégration de Stripe via Cloud Code
49 min
introduction développer une application de commerce électronique implique plusieurs composants, y compris les listes de produits, la fonctionnalité de panier d'achat, le traitement sécurisé des paiements, le suivi des commandes et les avis des utilisateurs combiner l'outil ui puissant de flutter avec les services backend évolutifs de back4app simplifie le processus de développement de plus, l'intégration de stripe pour le traitement des paiements via back4app cloud code permet de gérer les transactions de manière sécurisée et professionnelle dans ce tutoriel, vous allez créer une application de commerce électronique avec les fonctionnalités suivantes listes de produits afficher les produits avec des images, des descriptions et des prix panier d'achat ajouter et supprimer des produits du panier comptes utilisateurs gérer les profils et adresses des utilisateurs paiement sécurisé traiter les paiements de manière sécurisée en utilisant stripe via back4app cloud code suivi des commandes suivre l'état et l'historique des commandes avis et évaluations permettre aux utilisateurs de soumettre des avis et des évaluations prérequis pour suivre ce tutoriel, vous aurez besoin de flutter sdk installé sur votre machine suivez le guide d'installation de flutter https //flutter dev/docs/get started/install connaissances de base en flutter et dart un ide ou éditeur de texte comme visual studio code ou android studio un compte back4app inscrivez vous sur back4app https //www back4app com/ compte stripe inscrivez vous sur stripe https //stripe com/ pour obtenir des clés api node js et npm installés pour le développement de cloud code étape 1 – configuration du projet flutter 1 1 créer un nouveau projet flutter ouvrez votre terminal et exécutez flutter create ecommerce app naviguez vers le répertoire du projet cd ecommerce app 1 2 ajouter des dépendances ouvrez pubspec yaml et ajoutez les dépendances suivantes dependencies flutter sdk flutter parse server sdk flutter ^4 0 1 provider ^6 0 0 cached network image ^3 2 0 flutter stripe ^5 2 0 uuid ^3 0 6 exécutez flutter pub get pour installer les paquets remarque parse server sdk flutter pour l'intégration back4app provider pour la gestion d'état cached network image pour un chargement d'images efficace flutter stripe pour l'intégration stripe côté client uuid pour générer des identifiants uniques étape 2 – configuration de back4app 2 1 créer une nouvelle application back4app connectez vous à votre tableau de bord back4app https //dashboard back4app com/ cliquez sur "créer une nouvelle application" entrez "ecommerceapp" comme nom de l'application et cliquez sur "créer" 2 2 configurer les modèles de données nous devons créer plusieurs classes dans back4app produit utilisateur (classe intégrée) commande article de commande avis 2 2 1 classe produit naviguez vers la "base de données" section cliquez sur "créer une classe" sélectionnez "personnalisé" et entrez "produit" comme nom de classe ajoutez les colonnes suivantes nom chaîne description chaîne prix nombre image fichier catégorie chaîne inventaire nombre 2 2 2 classe commande créez une "commande" classe avec les colonnes suivantes utilisateur pointeur< utilisateur> montanttotal nombre statut chaîne (valeurs "en attente", "payé", "expédié", "livré") paymentintentid chaîne (pour suivre le paiement stripe) adressedelivraison chaîne 2 2 3 classe orderitem créer un "orderitem" classe avec les colonnes suivantes commande pointeur produit pointeur quantité nombre prix nombre 2 2 4 classe d'évaluation créer une "review" classe avec les colonnes suivantes produit pointeur utilisateur pointeur< utilisateur> évaluation nombre commentaire chaîne 2 3 obtenir les identifiants de l'application naviguez vers paramètres de l'application > sécurité et clés notez votre id d'application et clé client étape 3 – mise en œuvre de la gestion des produits 3 1 initialiser parse dans flutter ouvrez lib/main dart et modifiez le import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'package\ provider/provider dart'; import 'screens/home screen dart'; import 'services/product service dart'; void main() async { widgetsflutterbinding ensureinitialized(); const keyapplicationid = 'your application id'; const keyclientkey = 'your client key'; const keyparseserverurl = 'https //parseapi back4app com'; await parse() initialize( keyapplicationid, keyparseserverurl, clientkey keyclientkey, autosendsessionid true, debug true, ); runapp(myapp()); } class myapp extends statelesswidget { @override widget build(buildcontext context) { return changenotifierprovider\<productservice>( create ( ) => productservice(), child materialapp( title 'e commerce app', theme themedata( primaryswatch colors blue, ), home homescreen(), ), ); } } remplacez 'votre id application' et 'votre clé client' par vos identifiants back4app 3 2 création du modèle de produit créez un répertoire models sous lib et ajoutez product dart // lib/models/product dart class product { string id; string name; string description; double price; string imageurl; string category; int inventory; product({ required this id, required this name, required this description, required this price, required this imageurl, required this category, required this inventory, }); } 3 3 mise en œuvre du service produit créez un répertoire services sous lib et ajoutez product service dart // lib/services/product service dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/product dart'; class productservice with changenotifier { list\<product> products = \[]; future\<void> fetchproducts() async { final query = querybuilder\<parseobject>(parseobject('product')); final response = await query query(); if (response success && response results != null) { products = response results! map((data) { return product( id data objectid!, name data get\<string>('name')!, description data get\<string>('description')!, price data get\<num>('price')! todouble(), imageurl data get\<parsefilebase>('image')! url!, category data get\<string>('category')!, inventory data get\<num>('inventory')! toint(), ); }) tolist(); notifylisteners(); } } } 3 4 création de l'écran d'accueil créer un répertoire d'écrans sous lib et ajouter home screen dart // lib/screens/home screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/product service dart'; import 'product detail screen dart'; class homescreen extends statefulwidget { @override homescreenstate createstate() => homescreenstate(); } class homescreenstate extends state\<homescreen> { late productservice productservice; @override void initstate() { super initstate(); productservice = provider of\<productservice>(context, listen false); productservice fetchproducts(); } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('e commerce app'), actions \[ iconbutton( icon icon(icons shopping cart), onpressed () { // navigate to cart screen (to be implemented) }, ), ], ), body consumer\<productservice>( builder (context, productservice, child) { if (productservice products isempty) { return center(child circularprogressindicator()); } return gridview\ builder( padding edgeinsets all(8 0), itemcount productservice products length, griddelegate slivergriddelegatewithfixedcrossaxiscount( crossaxiscount 2, childaspectratio 0 75, ), itembuilder (context, index) { final product = productservice products\[index]; return gesturedetector( ontap () { navigator push( context, materialpageroute( builder ( ) => productdetailscreen(product product), ), ); }, child card( child column( children \[ expanded( child image network( product imageurl, fit boxfit cover, ), ), text(product name), text('\\$${product price tostringasfixed(2)}'), ], ), ), ); }, ); }, ), ); } } 3 5 écran de détails du produit créer product detail screen dart sous lib/screens/ // lib/screens/product detail screen dart import 'package\ flutter/material dart'; import ' /models/product dart'; import ' /services/cart service dart'; import 'package\ provider/provider dart'; class productdetailscreen extends statelesswidget { final product product; productdetailscreen({required this product}); @override widget build(buildcontext context) { final cartservice = provider of\<cartservice>(context); return scaffold( appbar appbar(title text(product name)), body column( children \[ expanded(child image network(product imageurl)), padding( padding const edgeinsets all(16 0), child text(product description), ), text('\\$${product price tostringasfixed(2)}'), elevatedbutton( onpressed () { cartservice addtocart(product); scaffoldmessenger of(context) showsnackbar( snackbar(content text('added to cart')), ); }, child text('add to cart'), ), ], ), ); } } étape 4 – mise en œuvre des comptes utilisateurs 4 1 service d'authentification ajouter auth service dart sous lib/services/ // lib/services/auth service dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; class authservice with changenotifier { parseuser? user; future\<bool> signup(string username, string password, string email) async { user = parseuser createuser(username, password, email); final response = await user! signup(); if (response success) { notifylisteners(); return true; } else { user = null; return false; } } future\<bool> login(string username, string password) async { user = parseuser(username, password, null); final response = await user! login(); if (response success) { notifylisteners(); return true; } else { user = null; return false; } } future\<void> logout() async { if (user != null) { await user! logout(); user = null; notifylisteners(); } } bool get isauthenticated => user != null; } 4 2 écrans d'authentification créer login screen dart et signup screen dart sous lib/screens/ écran de connexion // lib/screens/login screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/auth service dart'; import 'home screen dart'; import 'signup screen dart'; class loginscreen extends statelesswidget { final texteditingcontroller usernamecontroller = texteditingcontroller(); final texteditingcontroller passwordcontroller = texteditingcontroller(); void login(buildcontext context) async { final authservice = provider of\<authservice>(context, listen false); bool success = await authservice login( usernamecontroller text trim(), passwordcontroller text trim(), ); if (success) { navigator pushreplacement( context, materialpageroute(builder ( ) => homescreen()), ); } else { scaffoldmessenger of(context) showsnackbar(snackbar(content text('login failed'))); } } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('e commerce app login'), ), body padding( padding const edgeinsets all(16), child column( children \[ textfield( controller usernamecontroller, decoration inputdecoration(labeltext 'username or email'), ), textfield( controller passwordcontroller, decoration inputdecoration(labeltext 'password'), obscuretext true, ), sizedbox(height 20), elevatedbutton( onpressed () => login(context), child text('login'), ), textbutton( onpressed () { navigator push( context, materialpageroute(builder ( ) => signupscreen()), ); }, child text('don\\'t have an account? sign up'), ) ], ), ), ); } } écran d'inscription // lib/screens/signup screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/auth service dart'; import 'home screen dart'; class signupscreen extends statelesswidget { final texteditingcontroller usernamecontroller = texteditingcontroller(); final texteditingcontroller emailcontroller = texteditingcontroller(); final texteditingcontroller passwordcontroller = texteditingcontroller(); void signup(buildcontext context) async { final authservice = provider of\<authservice>(context, listen false); bool success = await authservice signup( usernamecontroller text trim(), passwordcontroller text trim(), emailcontroller text trim(), ); if (success) { navigator pushreplacement( context, materialpageroute(builder ( ) => homescreen()), ); } else { scaffoldmessenger of(context) showsnackbar(snackbar(content text('signup failed'))); } } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('e commerce app signup'), ), body padding( padding const edgeinsets all(16), child column( children \[ textfield( controller usernamecontroller, decoration inputdecoration(labeltext 'username'), ), textfield( controller emailcontroller, decoration inputdecoration(labeltext 'email'), ), textfield( controller passwordcontroller, decoration inputdecoration(labeltext 'password'), obscuretext true, ), sizedbox(height 20), elevatedbutton( onpressed () => signup(context), child text('sign up'), ), ], ), ), ); } } 4 3 mettre à jour main pour inclure authservice dans main dart , enveloppez le materialapp avec multiprovider // in main dart class myapp extends statelesswidget { @override widget build(buildcontext context) { return multiprovider( providers \[ changenotifierprovider\<productservice>( create ( ) => productservice(), ), changenotifierprovider\<authservice>( create ( ) => authservice(), ), changenotifierprovider\<cartservice>( create ( ) => cartservice(), ), ], child materialapp( // ), ); } } 4 4 redirection basée sur l'état d'authentification modifiez main dart pour vérifier l'état d'authentification // main dart // inside the build method home consumer\<authservice>( builder (context, authservice, child) { if (authservice isauthenticated) { return homescreen(); } else { return loginscreen(); } }, ), étape 5 – fonctionnalité du panier 5 1 créer le service de panier ajouter cart service dart sous lib/services/ // lib/services/cart service dart import 'package\ flutter/material dart'; import ' /models/product dart'; class cartitem { final product product; int quantity; cartitem({required this product, this quantity = 1}); } class cartservice with changenotifier { map\<string, cartitem> items = {}; void addtocart(product product) { if ( items containskey(product id)) { items\[product id]! quantity++; } else { items\[product id] = cartitem(product product); } notifylisteners(); } void removefromcart(string productid) { items remove(productid); notifylisteners(); } void clearcart() { items clear(); notifylisteners(); } map\<string, cartitem> get items => items; double get totalamount { double total = 0 0; items foreach((key, cartitem) { total += cartitem product price cartitem quantity; }); return total; } } 5 2 créer l'écran du panier ajouter cart screen dart sous lib/screens/ // lib/screens/cart screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/cart service dart'; import 'checkout screen dart'; class cartscreen extends statelesswidget { @override widget build(buildcontext context) { final cartservice = provider of\<cartservice>(context); final cartitems = cartservice items values tolist(); return scaffold( appbar appbar(title text('your cart')), body column( children \[ expanded( child listview\ builder( itemcount cartservice items length, itembuilder (context, index) { final cartitem = cartitems\[index]; return listtile( leading image network(cartitem product imageurl), title text(cartitem product name), subtitle text('quantity ${cartitem quantity}'), trailing text('\\$${(cartitem product price cartitem quantity) tostringasfixed(2)}'), ); }, ), ), text('total \\$${cartservice totalamount tostringasfixed(2)}'), elevatedbutton( onpressed () { navigator push( context, materialpageroute(builder ( ) => checkoutscreen()), ); }, child text('proceed to checkout'), ), ], ), ); } } étape 6 – paiement sécurisé avec intégration stripe via cloud code 6 1 configurer le compte stripe inscrivez vous pour un compte stripe https //dashboard stripe com/register obtenez votre clé publique et clé secrète depuis le tableau de bord stripe sous développeurs > clés api 6 2 installer le sdk stripe dans cloud code back4app prend en charge les fonctions cloud code écrites en javascript nous allons écrire des fonctions cloud code pour gérer le traitement des paiements 6 2 1 créer un projet cloud code dans le tableau de bord de votre application back4app, allez à paramètres de l'application > fonctions cloud code cliquez sur "modifier le code" pour ouvrir l'éditeur de cloud code 6 2 2 initialiser npm et installer le package stripe dans le terminal cloud code (fourni dans l'éditeur), exécutez npm init y npm install stripe\@8 174 0 remarque le cloud code de back4app utilise la version 14 x de node js, donc assurez vous de la compatibilité 6 3 créer une fonction cloud pour l'intention de paiement créez ou modifiez main js dans l'éditeur de cloud code // main js const stripe = require('stripe'); const stripe = stripe('your stripe secret key'); parse cloud define('createpaymentintent', async (request) => { const { amount, currency } = request params; try { const paymentintent = await stripe paymentintents create({ amount amount, currency currency, }); return { clientsecret paymentintent client secret }; } catch (error) { throw new parse error(500, error message); } }); remplacez 'votre cle secrete stripe' par votre véritable clé secrète stripe remarque de sécurité ne jamais exposer votre clé secrète côté client gardez la sécurisée dans le cloud code 6 4 déployer le cloud code cliquez sur "déployer" dans l'éditeur de cloud code pour déployer vos fonctions 6 5 implémenter le paiement dans flutter 6 5 1 initialiser stripe dans flutter dans main dart , après parse() initialize , ajoutez import 'package\ flutter stripe/flutter stripe dart'; // inside main() async stripe publishablekey = 'your stripe publishable key'; remplacez 'votre cle publiable stripe' par votre clé publiable stripe 6 5 2 créer l'écran de paiement ajoutez checkout screen dart sous lib/screens/ // lib/screens/checkout screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/cart service dart'; import 'package\ flutter stripe/flutter stripe dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'order confirmation screen dart'; class checkoutscreen extends statelesswidget { future\<void> processpayment(buildcontext context) async { final cartservice = provider of\<cartservice>(context, listen false); final totalamount = (cartservice totalamount 100) toint(); // amount in cents // call cloud function to create payment intent final response = await parsecloudfunction('createpaymentintent') execute( parameters { 'amount' totalamount, 'currency' 'usd', }, ); if (response success) { final clientsecret = response result\['clientsecret']; // initialize payment sheet await stripe instance initpaymentsheet( paymentsheetparameters setuppaymentsheetparameters( paymentintentclientsecret clientsecret, merchantdisplayname 'your e commerce app', ), ); // display payment sheet await stripe instance presentpaymentsheet(); // payment successful // save order to back4app (to be implemented) cartservice clearcart(); navigator pushreplacement( context, materialpageroute(builder ( ) => orderconfirmationscreen()), ); } else { scaffoldmessenger of(context) showsnackbar( snackbar(content text('payment failed ${response error! message}')), ); } } @override widget build(buildcontext context) { final cartservice = provider of\<cartservice>(context); return scaffold( appbar appbar(title text('checkout')), body column( children \[ text('total \\$${cartservice totalamount tostringasfixed(2)}'), elevatedbutton( onpressed () => processpayment(context), child text('pay now'), ), ], ), ); } } 6 5 3 gérer la confirmation de paiement créer order confirmation screen dart sous lib/screens/ // lib/screens/order confirmation screen dart import 'package\ flutter/material dart'; class orderconfirmationscreen extends statelesswidget { @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('order confirmed'), automaticallyimplyleading false, ), body center( child text('thank you for your purchase!'), ), ); } } 6 6 enregistrement de la commande dans back4app modifier la processpayment méthode pour enregistrer les détails de la commande // after successful payment final authservice = provider of\<authservice>(context, listen false); final user = authservice user!; // create order object final order = parseobject('order') set('user', user) set('totalamount', cartservice totalamount) set('status', 'paid') set('paymentintentid', clientsecret); // save order final orderresponse = await order save(); if (orderresponse success) { final orderobject = orderresponse result; // save orderitems for (var cartitem in cartservice items values) { final orderitem = parseobject('orderitem') set('order', orderobject) set('product', parseobject('product') objectid = cartitem product id) set('quantity', cartitem quantity) set('price', cartitem product price); await orderitem save(); } // clear cart and navigate cartservice clearcart(); navigator pushreplacement( context, materialpageroute(builder ( ) => orderconfirmationscreen()), ); } else { scaffoldmessenger of(context) showsnackbar( snackbar(content text('failed to save order')), ); } étape 7 – suivi de commande 7 1 créer un service de commande ajouter order service dart sous lib/services/ // lib/services/order service dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/order dart'; class orderservice with changenotifier { list\<order> orders = \[]; future\<void> fetchorders(parseuser user) async { final query = querybuilder\<parseobject>(parseobject('order')) whereequalto('user', user) orderbydescending('createdat'); final response = await query query(); if (response success && response results != null) { orders = response results! map((data) { return order fromparseobject(data); }) tolist(); notifylisteners(); } } } 7 2 créer le modèle de commande ajouter order dart sous lib/models/ // lib/models/order dart import 'package\ parse server sdk flutter/parse server sdk dart'; class order { string id; double totalamount; string status; datetime createdat; order({ required this id, required this totalamount, required this status, required this createdat, }); factory order fromparseobject(parseobject object) { return order( id object objectid!, totalamount object get\<num>('totalamount')! todouble(), status object get\<string>('status')!, createdat object createdat!, ); } } 7 3 créer l'écran des commandes ajouter orders screen dart sous lib/screens/ // lib/screens/orders screen dart import 'package\ flutter/material dart'; import 'package\ provider/provider dart'; import ' /services/order service dart'; import ' /services/auth service dart'; import ' /models/order dart'; class ordersscreen extends statefulwidget { @override ordersscreenstate createstate() => ordersscreenstate(); } class ordersscreenstate extends state\<ordersscreen> { late orderservice orderservice; @override void initstate() { super initstate(); orderservice = provider of\<orderservice>(context, listen false); final authservice = provider of\<authservice>(context, listen false); orderservice fetchorders(authservice user!); } @override widget build(buildcontext context) { return scaffold( appbar appbar(title text('your orders')), body consumer\<orderservice>( builder (context, orderservice, child) { if (orderservice orders isempty) { return center(child text('no orders found ')); } return listview\ builder( itemcount orderservice orders length, itembuilder (context, index) { final order = orderservice orders\[index]; return listtile( title text('order #${order id}'), subtitle text('status ${order status}'), trailing text('\\$${order totalamount tostringasfixed(2)}'), ); }, ); }, ), ); } } étape 8 – avis et évaluations 8 1 créer le service d'avis ajouter review service dart sous lib/services/ // lib/services/review service dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/review\ dart'; class reviewservice with changenotifier { list\<review> reviews = \[]; future\<void> fetchreviews(string productid) async { final query = querybuilder\<parseobject>(parseobject('review')) whereequalto('product', parseobject('product') objectid = productid) includeobject(\['user']); final response = await query query(); if (response success && response results != null) { reviews = response results! map((data) { return review\ fromparseobject(data); }) tolist(); notifylisteners(); } } future\<void> submitreview(string productid, parseuser user, int rating, string comment) async { final review = parseobject('review') set('product', parseobject('product') objectid = productid) set('user', user) set('rating', rating) set('comment', comment); await review\ save(); await fetchreviews(productid); } } 8 2 créer le modèle d'évaluation ajouter review\ dart sous lib/models/ // lib/models/review\ dart import 'package\ parse server sdk flutter/parse server sdk dart'; class review { string id; int rating; string comment; parseuser user; review({ required this id, required this rating, required this comment, required this user, }); factory review\ fromparseobject(parseobject object) { return review( id object objectid!, rating object get\<num>('rating')! toint(), comment object get\<string>('comment')!, user object get\<parseuser>('user')!, ); } } 8 3 mettre à jour l'écran de détails du produit dans product detail screen dart , ajoutez une section pour afficher et soumettre des avis // at the end of the column in productdetailscreen expanded( child column( children \[ // display reviews expanded( child consumer\<reviewservice>( builder (context, reviewservice, child) { if (reviewservice reviews isempty) { return center(child text('no reviews yet ')); } return listview\ builder( itemcount reviewservice reviews length, itembuilder (context, index) { final review = reviewservice reviews\[index]; return listtile( title text(review\ user username ?? 'anonymous'), subtitle text(review\ comment), trailing text('${review\ rating}/5'), ); }, ); }, ), ), // submit review textfield( controller reviewcontroller, decoration inputdecoration(hinttext 'write a review'), ), row( children \[ text('rating '), dropdownbutton\<int>( value rating, onchanged (value) { setstate(() { rating = value!; }); }, items list generate(5, (index) => index + 1) map((e) => dropdownmenuitem(value e, child text('$e'))) tolist(), ), elevatedbutton( onpressed () { final authservice = provider of\<authservice>(context, listen false); reviewservice submitreview( product id, authservice user!, rating, reviewcontroller text trim(), ); reviewcontroller clear(); }, child text('submit'), ), ], ), ], ), ), conclusion dans ce tutoriel complet, vous avez construit une application de commerce électronique en utilisant flutter et back4app, intégrée avec stripe pour un traitement sécurisé des paiements via cloud code vous avez mis en œuvre des fonctionnalités clés telles que les listes de produits, la fonctionnalité de panier d'achat, l'authentification des utilisateurs, le suivi des commandes et les avis points clés intégration back4app simplifie la gestion du backend pour votre application flutter intégration stripe via cloud code traite les paiements de manière sécurisée sans exposer de clés sensibles architecture modulaire la séparation des services et des modèles améliore la maintenabilité prochaines étapes améliorer la sécurité mettre en œuvre une gestion appropriée des erreurs et une validation des entrées améliorations ui/ux affiner l'interface utilisateur pour une meilleure expérience utilisateur gestion des stocks mettre à jour l'inventaire des produits lors de l'achat notifications par e mail envoyer des e mails de confirmation de commande aux utilisateurs panneau d'administration créer une interface d'administration pour gérer les produits et les commandes ressources supplémentaires documentation back4app https //www back4app com/docs guide de parse server https //docs parseplatform org/ documentation officielle de flutter https //flutter dev/docs référence api stripe https //stripe com/docs/api package flutter stripe https //pub dev/packages/flutter stripe bonne programmation !