Colas Mérand
18/04/2025
Firebase
Flutter
Stripe
5 minutes
Dans un monde où la mobilité urbaine se digitalise à grande vitesse, les applications de VTC et de taxi sont devenues incontournables. Cependant, développer et maintenir ces plateformes complexes présente de nombreux défis techniques, particulièrement lorsqu'il s'agit d'intégrer des systèmes de paiement fiables et de garantir une expérience utilisateur fluide.
Chez Platane, nous avons accompagné plusieurs entreprises dans l'optimisation de leurs applications mobiles, notamment dans le secteur du transport. Cet article explore les problématiques courantes rencontrées dans les applications VTC/Taxi utilisant Firebase, Flutter et Stripe, et propose des solutions concrètes basées sur notre expertise.
L'intégration de Stripe dans une application de transport présente plusieurs subtilités, particulièrement lorsqu'il s'agit de gérer différents types de prestataires (VTC, taxis traditionnels) ayant des règles de facturation distinctes.
Un problème fréquent est l'application d'une même logique de majoration à tous les chauffeurs, sans distinction de leur statut. Cette approche "one-size-fits-all" ne correspond pas à la réalité du terrain où les VTC et les taxis peuvent avoir des structures tarifaires différentes.
Solution : Implémenter une logique conditionnelle dans vos fonctions Firebase qui applique des règles de majoration spécifiques selon le type de chauffeur. Par exemple :
// Exemple simplifié de code Firebase Functions
exports.processFare = functions.https.onCall(async (data, context) => {
const { driverId, fareAmount } = data;
// Récupérer le profil du chauffeur
const driverSnapshot = await admin.firestore().collection('drivers').doc(driverId).get();
const driverType = driverSnapshot.data().type; // 'VTC' ou 'TAXI'
// Appliquer la majoration selon le type
let surcharge = 0;
if (driverType === 'VTC') {
surcharge = calculateVTCSurcharge(fareAmount);
} else if (driverType === 'TAXI') {
surcharge = calculateTaxiSurcharge(fareAmount);
}
// Continuer avec le traitement du paiement...
});
Un autre problème courant concerne la gestion des intentions de paiement (PaymentIntent) de Stripe. Certaines implémentations annulent et recréent l'intention de paiement en fin de course au lieu de simplement la modifier, ce qui peut entraîner des échecs de transaction et une expérience utilisateur dégradée.
Solution : Privilégier la mise à jour des PaymentIntent existants plutôt que leur annulation/recréation :
// Approche recommandée
try {
// Mettre à jour l'intention de paiement existante
const updatedIntent = await stripe.paymentIntents.update(paymentIntentId, {
amount: finalAmount,
metadata: { finalFare: true, driverType }
});
// Capturer le paiement si nécessaire
if (captureNow) {
await stripe.paymentIntents.capture(paymentIntentId);
}
} catch (error) {
console.error('Erreur lors de la mise à jour du paiement:', error);
// Gérer l'erreur de manière appropriée
}
Les utilisateurs confrontés à des échecs de paiement reçoivent souvent des messages d'erreur génériques comme "carte non à jour" au lieu d'informations précises sur la nature du problème (fonds insuffisants, carte expirée, etc.).
Solution : Intercepter et traduire correctement les codes d'erreur Stripe :
// Exemple Flutter pour intercepter les erreurs Stripe
try {
final paymentResult = await _stripePaymentService.processPayment(amount, currency);
// Traiter le succès
} catch (e) {
String userFriendlyMessage;
if (e is StripeException) {
// Mapper les codes d'erreur Stripe à des messages utilisateur
switch (e.error.code) {
case 'card_declined':
userFriendlyMessage = 'Votre carte a été refusée. Veuillez vérifier vos fonds disponibles.';
break;
case 'expired_card':
userFriendlyMessage = 'Votre carte est expirée. Veuillez utiliser une autre carte.';
break;
case 'insufficient_funds':
userFriendlyMessage = 'Fonds insuffisants sur votre carte. Veuillez utiliser un autre moyen de paiement.';
break;
default:
userFriendlyMessage = 'Une erreur est survenue lors du paiement. Veuillez réessayer.';
}
} else {
userFriendlyMessage = 'Une erreur inattendue est survenue. Veuillez réessayer.';
}
// Afficher le message à l'utilisateur
showErrorDialog(context, userFriendlyMessage);
}
Un problème critique dans de nombreuses applications est l'échec de l'envoi d'emails de vérification lors de l'inscription, bloquant ainsi le processus d'onboarding des utilisateurs.
Solution : Mettre en place un système robuste de vérification d'email :
// Exemple Flutter pour la vérification d'email
Future<void> sendVerificationEmail() async {
try {
User? user = FirebaseAuth.instance.currentUser;
if (user != null && !user.emailVerified) {
await user.sendEmailVerification();
// Informer l'utilisateur
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Email de vérification envoyé'),
content: Text('Veuillez vérifier votre boîte de réception et cliquer sur le lien de confirmation.'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('OK'),
),
],
),
);
// Vérifier périodiquement si l'email a été vérifié
Timer.periodic(Duration(seconds: 5), (timer) async {
await FirebaseAuth.instance.currentUser?.reload();
User? updatedUser = FirebaseAuth.instance.currentUser;
if (updatedUser?.emailVerified ?? false) {
timer.cancel();
// Procéder à l'étape suivante de l'inscription
navigateToNextStep();
}
});
}
} catch (e) {
print('Erreur lors de l\'envoi de l\'email de vérification: $e');
// Gérer l'erreur
}
}
De nombreuses applications ne permettent pas aux utilisateurs de modifier leur moyen de paiement une fois celui-ci enregistré, ce qui peut entraîner une frustration et des abandons.
Solution : Implémenter une interface de gestion des moyens de paiement :
// Exemple Flutter pour la gestion des moyens de paiement
class PaymentMethodsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Mes moyens de paiement')),
body: FutureBuilder<List<PaymentMethod>>(
future: _stripeService.getPaymentMethods(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('Erreur lors du chargement des moyens de paiement'));
}
final paymentMethods = snapshot.data ?? [];
return Column(
children: [
// Liste des cartes existantes
Expanded(
child: ListView.builder(
itemCount: paymentMethods.length,
itemBuilder: (context, index) {
final method = paymentMethods[index];
return PaymentMethodCard(
method: method,
onDelete: () => _deletePaymentMethod(method.id),
isDefault: index == 0,
onSetDefault: () => _setDefaultPaymentMethod(method.id),
);
},
),
),
// Bouton pour ajouter une nouvelle carte
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: () => _addNewPaymentMethod(context),
child: Text('Ajouter une nouvelle carte'),
style: ElevatedButton.styleFrom(
minimumSize: Size(double.infinity, 50),
),
),
),
],
);
},
),
);
}
// Méthodes pour gérer les cartes...
}
Fort de notre expérience dans le développement d'applications mobiles complexes, notamment avec notre projet Dealt (une marketplace de jobbing intégrant des paiements via Stripe), nous recommandons les pratiques suivantes :
Le développement d'applications VTC/Taxi avec Firebase, Flutter et Stripe présente des défis uniques qui nécessitent une expertise technique approfondie et une compréhension des enjeux métier spécifiques à ce secteur.
Chez Platane, nous avons relevé ces défis pour plusieurs clients, en développant des solutions robustes et évolutives. Notre expérience avec des projets comme Dealt (marketplace avec paiements intégrés) et Easop (plateforme de gestion financière utilisant Stripe) nous a permis d'acquérir une expertise pointue dans l'intégration de systèmes de paiement sécurisés et la création d'expériences utilisateur fluides.
Que vous cherchiez à corriger des problèmes dans une application existante ou à développer une nouvelle solution de mobilité, une approche méthodique et une expertise technique solide sont essentielles pour garantir le succès de votre projet.
Vous rencontrez des défis similaires avec votre application mobile ? Notre équipe d'experts en Firebase, Flutter et Stripe peut vous aider à résoudre vos problèmes techniques et à optimiser votre plateforme.
Prenez rendez-vous via notre formulaire de contact pour échanger sur votre projet. Chez Platane, nous combinons expertise technique et compréhension métier pour vous proposer des solutions sur mesure qui répondent précisément à vos besoins.
Collaborer avec Platane, c'est bénéficier d'une équipe réactive, autonome et expérimentée, capable de déboguer des cas réels et d'implémenter des solutions durables. N'attendez plus pour faire passer votre application au niveau supérieur !
Vous préférez discuter de vive voix ? Nous aussi et c'est évidemment sans engagement !
Une question, un besoin de renseignements ? N'hésitez pas à nous contacter.