Gestion Avancée Stripe - Guide Complet
Date de création : 11 novembre 2025
Statut : 🔵 En cours de rédaction
Propriétaire : Équipe
Dernière mise à jour : 11 novembre 2025
📖 Guide d'Utilisation
Ce document couvre les aspects avancés de la gestion Stripe : - Gestion des Litiges (Disputes) : Comment répondre et prévenir. - Gestion des Moyens de Paiement : Mise à jour des cartes. - Upgrade/Downgrade d'Abonnement : Changement de plan. - Prévention de la Fraude (Stripe Radar) : Configuration et règles.
1. Gestion des Litiges (Disputes/Chargebacks)
1.1 Qu'est-ce qu'un litige ?
Un client conteste un paiement auprès de sa banque. La banque retire les fonds de votre compte Stripe et vous facture des frais de litige (environ 15€). Vous avez une période limitée (généralement 7 à 21 jours) pour soumettre des preuves que le paiement était légitime.
1.2 Processus de Gestion
Client conteste un paiement
↓
Stripe envoie le webhook `charge.dispute.created`
↓
Cloud Function `handleDisputeCreated`:
- Logger le litige dans Firestore (`disputes` collection)
- Envoyer une notification interne (email, Slack) à l'équipe
↓
Équipe Support/Admin examine le litige
↓
Collecter les preuves de légitimité :
- Logs de connexion de l'utilisateur (`audit_logs`)
- Preuve de téléchargement/utilisation du service
- Factures (`invoices`)
- Communication avec le client
↓
Soumettre les preuves via le Dashboard Stripe ou l'API
↓
Stripe et la banque examinent les preuves (peut prendre 60-75 jours)
↓
Décision finale : Litige gagné ou perdu
↓
Webhook `charge.dispute.closed` reçu et loggué
1.3 Implémentation Technique
Webhook Handler :
// Dans `handleStripeWebhook`
if (event.type === 'charge.dispute.created') {
const dispute = event.data.object;
// 1. Logger le litige
await admin.firestore().collection('disputes').doc(dispute.id).set({
chargeId: dispute.charge,
amount: dispute.amount,
currency: dispute.currency,
reason: dispute.reason,
status: dispute.status,
createdAt: admin.firestore.FieldValue.serverTimestamp(),
});
// 2. Envoyer une notification à l'équipe
await sendInternalNotification(`Nouveau litige de ${dispute.amount} ${dispute.currency}. Raison: ${dispute.reason}`);
}
Collecte de preuves (via une interface admin) :
- Afficher les détails du litige.
- Afficher les logs de l'utilisateur concerné (audit_logs).
- Afficher les factures associées.
- Permettre de télécharger un package de preuves.
1.4 Prévention
- Communication claire : Assurez-vous que le nom de votre entreprise est reconnaissable sur les relevés bancaires.
- Factures détaillées : Envoyez des factures claires pour chaque paiement.
- Support client réactif : Répondez rapidement aux demandes pour éviter qu'elles ne se transforment en litiges.
- Utiliser Stripe Radar : Pour bloquer les paiements frauduleux en amont.
2. Gestion des Moyens de Paiement
2.1 Pourquoi c'est important ?
Les cartes de crédit expirent, sont perdues ou annulées. Si un utilisateur ne peut pas mettre à jour son moyen de paiement, son abonnement sera annulé au prochain échec de paiement. C'est du churn involontaire.
2.2 Flux de mise à jour
Utilisateur veut mettre à jour sa carte
↓
Appelle la Cloud Function `createSetupIntent`
↓
Cloud Function retourne un `client_secret`
↓
L'application utilise le `client_secret` avec le SDK Stripe pour afficher un formulaire de carte sécurisé
↓
L'utilisateur entre les nouvelles informations de carte
↓
Le SDK Stripe envoie les détails de manière sécurisée à Stripe
↓
Stripe attache le nouveau moyen de paiement au `customer` Stripe
↓
Stripe définit ce nouveau moyen comme celui par défaut pour l'abonnement
↓
Confirmation affichée à l'utilisateur
2.3 Implémentation Technique
Cloud Function pour créer un SetupIntent :
exports.createSetupIntent = functions.https.onCall(async (data, context) => {
if (!context.auth) throw new Error('Non authentifié');
const uid = context.auth.uid;
const customerDoc = await admin.firestore().collection('customers').doc(uid).get();
const stripeCustomerId = customerDoc.data().stripeCustomerId;
const setupIntent = await stripe.setupIntents.create({
customer: stripeCustomerId,
});
return { client_secret: setupIntent.client_secret };
});
Interface Flutter (simplifiée) :
// Utiliser le package `flutter_stripe`
void _updatePaymentMethod() async {
// 1. Appeler la Cloud Function `createSetupIntent` pour obtenir le client_secret
final functions = FirebaseFunctions.instance;
final result = await functions.httpsCallable('createSetupIntent').call();
final clientSecret = result.data['client_secret'];
// 2. Présenter le formulaire de carte à l'utilisateur
await Stripe.instance.confirmSetupIntent(
paymentIntentClientSecret: clientSecret,
params: PaymentMethodParams.card(),
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Moyen de paiement mis à jour !')),
);
}
2.4 Notifications Proactives
- Webhook
payment_method.automatically_updated: Stripe (via les réseaux de cartes) peut parfois mettre à jour automatiquement une carte expirée. Loggez cet événement. - Email de rappel : Créez une tâche planifiée (Cloud Scheduler) qui vérifie chaque jour les cartes expirant dans les 30 prochains jours et envoie un email de rappel.
3. Upgrade/Downgrade d'Abonnement
3.1 Logique de Facturation
Stripe gère automatiquement le calcul au prorata. - Upgrade : L'utilisateur paie immédiatement la différence au prorata pour la période en cours. - Downgrade : Un crédit est appliqué au compte du client, qui sera utilisé pour les prochaines factures. Aucun remboursement n'est effectué par défaut.
3.2 Flux de Changement de Plan
Utilisateur choisit un nouveau plan
↓
Appelle la Cloud Function `updateSubscription` avec le nouveau `priceId`
↓
Cloud Function :
- Récupère l'abonnement actuel de l'utilisateur
- Appelle `stripe.subscriptions.update()` avec le nouveau `priceId`
- Stripe calcule le prorata et facture si nécessaire
↓
Webhook `customer.subscription.updated` reçu
↓
Cloud Function `handleStripeWebhook`:
- Met à jour le `priceId` dans la base de données Firestore
- Met à jour le rôle si nécessaire (ex: `paid_premium`)
↓
Confirmation affichée à l'utilisateur
3.3 Implémentation Technique
Cloud Function pour mettre à jour l'abonnement :
exports.updateSubscription = functions.https.onCall(async (data, context) => {
if (!context.auth) throw new Error('Non authentifié');
const uid = context.auth.uid;
const newPriceId = data.priceId;
const customerDoc = await admin.firestore().collection('customers').doc(uid).get();
const subscriptionId = customerDoc.data().subscriptionId;
const subscription = await stripe.subscriptions.retrieve(subscriptionId);
await stripe.subscriptions.update(subscriptionId, {
items: [{
id: subscription.items.data[0].id, // ID de l'item de l'abonnement
price: newPriceId,
}],
proration_behavior: 'create_prorations', // Comportement par défaut
});
return { success: true };
});
4. Prévention de la Fraude (Stripe Radar)
4.1 Configuration de Radar
Stripe Radar est activé par défaut, mais sa puissance réside dans la personnalisation.
Actions à prendre dans le Dashboard Stripe : 1. Activer Radar for Fraud Teams (si disponible avec votre plan Stripe). 2. Examiner les règles par défaut. 3. Créer des règles personnalisées.
Exemples de règles personnalisées :
- Block if :card_country: = 'XX' AND :risk_level: = 'high' : Bloquer les paiements de pays à haut risque si le score de risque est élevé.
- Review if :amount_in_usd: > 1000 AND is_first_payment_for_customer : Mettre en revue manuellement les premiers paiements importants.
- Block if count(:ip_address:, 1h) > 5 : Bloquer une adresse IP qui tente plus de 5 paiements en une heure.
4.2 Gestion des Faux Positifs
- Webhook
charge.dispute.createdavecreason: 'fraudulent': Si un paiement est contesté pour fraude, ajoutez l'email et l'IP du client à une liste de blocage dans Radar. - Liste blanche : Si un client légitime est bloqué, vous pouvez ajouter son email ou sa carte à une liste blanche pour autoriser ses futurs paiements.
4.3 3D Secure
Pour les paiements dans l'Espace Économique Européen, la SCA (Strong Customer Authentication) est obligatoire. Stripe gère cela automatiquement via 3D Secure lors du checkout. Assurez-vous que votre intégration de checkout est compatible.
Document créé par Cascade - Gestion Avancée Stripe pour Yinshi