Architecture Stripe - Design Technique
Date de crΓ©ation : 11 novembre 2025
Statut : π΅ Design technique
PropriΓ©taire : Γquipe Dev
Dernière mise à jour : 11 novembre 2025
π Guide d'Utilisation
Ce document dΓ©crit : - Architecture globale : Comment tout s'imbrique - Flux de paiement : Comment les paiements fonctionnent - Flux d'authentification : Comment l'authentification fonctionne - SΓ©curitΓ© : Comment les donnΓ©es sont protΓ©gΓ©es - Stockage : OΓΉ les donnΓ©es sont stockΓ©es
ποΈ Architecture Globale
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLIENT (Flutter App) β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Auth Screen β β Payment β β Settings β β
β β β β Screen β β Screen β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HTTPS
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FIREBASE (Backend) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Firebase Auth β β
β β - Email/Password β β
β β - Google OAuth β β
β β - Apple OAuth β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Firestore Database β β
β β - app_users (profils) β β
β β - customers (infos Stripe) β β
β β - audit_logs (traΓ§abilitΓ©) β β
β β - webhook_logs (webhooks) β β
β β - invoices (factures) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Cloud Functions β β
β β - handleStripeWebhook (validation webhooks) β β
β β - createCheckoutSession (crΓ©er session) β β
β β - handlePaymentSuccess (paiement rΓ©ussi) β β
β β - handlePaymentFailure (paiement Γ©chouΓ©) β β
β β - deleteUserData (suppression compte) β β
β β - exportUserData (export donnΓ©es) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HTTPS
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β STRIPE (Payment Provider) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Stripe API β β
β β - Checkout Sessions β β
β β - Customers β β
β β - Subscriptions β β
β β - Invoices β β
β β - Webhooks β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Flux de Paiement
1. Initiation du Paiement
User clicks "Subscribe"
β
App calls Cloud Function: createCheckoutSession
β
Cloud Function:
- VΓ©rifier authentification
- CrΓ©er session Stripe
- Stocker session_id dans Firestore
β
Stripe retourne URL de checkout
β
App ouvre URL dans navigateur
β
User remplit les infos de paiement
β
User clique "Pay"
Code Flutter :
Future<void> startCheckout(BuildContext context, PaymentPlanModel product) async {
final checkout = FirebaseFirestore.instance
.collection('customers')
.doc(FirebaseAuth.instance.currentUser!.uid)
.collection('checkout_sessions')
.doc();
await checkout.set({
'price': product.stripePriceId,
'success_url': 'https://yinshi.com/success',
'cancel_url': 'https://yinshi.com/cancel',
});
checkout.snapshots().listen((snapshot) {
final data = snapshot.data();
if (data?.containsKey('url') ?? false) {
launchUrl(Uri.parse(data!['url']));
}
});
}
2. Traitement du Paiement
Stripe processes payment
β
Payment successful
β
Stripe sends webhook: payment_intent.succeeded
β
Cloud Function: handleStripeWebhook
- VΓ©rifier signature HMAC-SHA256
- VΓ©rifier timestamp
- Logger le webhook
- CrΓ©er facture
- Mettre Γ jour rΓ΄le utilisateur
- Envoyer email de confirmation
β
Firestore updated:
- customers.subscriptionStatus = "active"
- app_users.role = "paid"
- invoices créée
- audit_logs créé
β
User reΓ§oit email de confirmation
Code Cloud Function :
exports.handleStripeWebhook = functions.https.onRequest((req, res) => {
const signature = req.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(
req.rawBody,
signature,
process.env.STRIPE_WEBHOOK_SECRET
);
} catch (err) {
res.status(400).send(`Webhook Error: ${err.message}`);
return;
}
// Log webhook
admin.firestore().collection('webhook_logs').add({
timestamp: admin.firestore.FieldValue.serverTimestamp(),
event_id: event.id,
type: event.type,
status: 'received'
});
// Handle payment success
if (event.type === 'payment_intent.succeeded') {
const paymentIntent = event.data.object;
const customerId = paymentIntent.customer;
// Update user role
admin.firestore().collection('customers').doc(customerId).update({
subscriptionStatus: 'active',
updatedAt: admin.firestore.FieldValue.serverTimestamp()
});
}
res.status(200).json({received: true});
});
3. Gestion des Erreurs
Payment fails
β
Stripe sends webhook: payment_intent.payment_failed
β
Cloud Function: handlePaymentFailure
- Logger l'erreur
- Mettre Γ jour statut
- Envoyer email d'alerte
- Planifier retry automatique
β
Stripe retry automatiquement (3 fois)
β
Si succès : Webhook payment_intent.succeeded
Si Γ©chec : Webhook invoice.payment_failed
β
Cloud Function: handleInvoicePaymentFailed
- Annuler l'abonnement
- Mettre Γ jour rΓ΄le utilisateur
- Envoyer email d'alerte
π Flux d'Authentification
1. Inscription
User enters email + password
β
App calls Firebase Auth: createUserWithEmailAndPassword
β
Firebase Auth:
- Valider email format
- Hacher le mot de passe
- CrΓ©er compte
- Envoyer email de vΓ©rification
β
Cloud Function: onCreate (trigger)
- CrΓ©er profil utilisateur dans Firestore
- Ajouter rΓ΄le "trial"
- Ajouter date d'essai (30 jours)
- CrΓ©er audit log
β
User reΓ§oit email de vΓ©rification
β
User clique sur lien
β
Email vΓ©rifiΓ©
Code Flutter :
Future<void> signUp(String email, String password) async {
try {
await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: email,
password: password,
);
// Cloud Function crΓ©e le profil automatiquement
} catch (e) {
throw Exception('Erreur inscription: $e');
}
}
2. Connexion
User enters email + password
β
App calls Firebase Auth: signInWithEmailAndPassword
β
Firebase Auth:
- VΓ©rifier email existe
- VΓ©rifier mot de passe correct
- CrΓ©er session
β
Cloud Function: onSignIn (trigger)
- VΓ©rifier email vΓ©rifiΓ©
- VΓ©rifier statut d'essai
- CrΓ©er audit log
β
App récupère profil utilisateur
β
App affiche Γ©cran principal
3. Suppression de Compte
User clicks "Delete account"
β
App demande confirmation
β
App calls Cloud Function: deleteUserData
β
Cloud Function:
- VΓ©rifier authentification
- Annuler abonnement Stripe
- Supprimer donnΓ©es Firestore
- Supprimer compte Firebase Auth
- CrΓ©er audit log
β
Firestore updated:
- app_users supprimΓ©
- customers supprimΓ©
- audit_logs supprimΓ©
β
Firebase Auth: compte supprimΓ©
β
User reΓ§oit email de confirmation
πΎ ModΓ¨le de DonnΓ©es Firestore
Collection : app_users
/app_users/{uid}
βββ uid : string (Firebase UID)
βββ email : string
βββ role : string (trial, paid, expired, admin)
βββ trialEndDate : timestamp
βββ createdAt : timestamp
βββ updatedAt : timestamp
βββ lastLoginDate : timestamp
βββ lastLogoutDate : timestamp
βββ language : string (fr, en, etc.)
βββ consentement_accepte : boolean
βββ date_consentement : timestamp
βββ version_consentement : string
Collection : customers
/customers/{uid}
βββ uid : string (Firebase UID)
βββ stripeCustomerId : string
βββ subscriptionStatus : string (active, canceled, etc.)
βββ subscriptionId : string
βββ priceId : string
βββ currentPeriodStart : timestamp
βββ currentPeriodEnd : timestamp
βββ canceledAt : timestamp
βββ updatedAt : timestamp
Collection : audit_logs
/audit_logs/{logId}
βββ timestamp : timestamp
βββ user_id : string
βββ action : string (login, payment, role_change, etc.)
βββ result : string (success, failure)
βββ details : object
β βββ amount : number (si paiement)
β βββ currency : string (si paiement)
β βββ error : string (si erreur)
β βββ ...
βββ ip : string (optionnel)
Collection : webhook_logs
/webhook_logs/{logId}
βββ timestamp : timestamp
βββ event_id : string
βββ type : string (payment_intent.succeeded, etc.)
βββ status : string (received, processed, error)
βββ details : object
βββ error : string (si erreur)
Collection : invoices
/customers/{uid}/invoices/{invoiceId}
βββ stripe_invoice_id : string
βββ amount : number
βββ currency : string
βββ date : timestamp
βββ status : string (draft, open, paid, void)
βββ pdf_url : string
βββ metadata : object
π SΓ©curitΓ© - Firestore Rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// === app_users : Accès restreint au propre profil ===
match /app_users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
// === customers : Accès restreint au propre profil ===
match /customers/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
// === invoices : Accès restreint au propre profil ===
match /invoices/{invoiceId} {
allow read: if request.auth != null && request.auth.uid == userId;
}
}
// === audit_logs : Seuls admins peuvent lire ===
match /audit_logs/{logId} {
allow read: if isAdmin();
allow write: if false;
}
// === webhook_logs : Seuls admins peuvent lire ===
match /webhook_logs/{logId} {
allow read: if isAdmin();
allow write: if false;
}
// === Fonction utilitaire : vΓ©rifie si l'utilisateur est admin ===
function isAdmin() {
return request.auth != null
&& exists(/databases/$(database)/documents/app_users/$(request.auth.uid))
&& get(/databases/$(database)/documents/app_users/$(request.auth.uid)).data.role == "admin";
}
}
}
π Cloud Functions
Function 1 : handleStripeWebhook
Trigger : HTTP POST
Endpoint : /webhooks/stripe
SΓ©curitΓ© : Validation HMAC-SHA256
ResponsabilitΓ©s : - Valider la signature du webhook - Logger le webhook - Traiter l'Γ©vΓ©nement - Mettre Γ jour Firestore - Envoyer emails
ΓvΓ©nements traitΓ©s :
- payment_intent.succeeded : Paiement rΓ©ussi
- payment_intent.payment_failed : Paiement Γ©chouΓ©
- invoice.payment_failed : Facture non payΓ©e
- customer.subscription.deleted : Abonnement annulΓ©
Function 2 : createCheckoutSession
Trigger : Firestore write
Path : /customers/{uid}/checkout_sessions/{sessionId}
SΓ©curitΓ© : Authentification Firebase
ResponsabilitΓ©s : - VΓ©rifier authentification - CrΓ©er session Stripe - Stocker session_id - GΓ©nΓ©rer URL de checkout
Function 3 : deleteUserData
Trigger : HTTP POST
Endpoint : /users/delete
SΓ©curitΓ© : Authentification Firebase
ResponsabilitΓ©s : - VΓ©rifier authentification - Annuler abonnement Stripe - Supprimer donnΓ©es Firestore - Supprimer compte Firebase Auth - CrΓ©er audit log - Envoyer email de confirmation
Function 4 : exportUserData
Trigger : HTTP POST
Endpoint : /users/export
SΓ©curitΓ© : Authentification Firebase
ResponsabilitΓ©s : - VΓ©rifier authentification - RΓ©cupΓ©rer toutes les donnΓ©es - GΓ©nΓ©rer JSON/CSV - Chiffrer le fichier - Envoyer lien par email
π Flux de DonnΓ©es - Diagramme Complet
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β USER ACTIONS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β 1. Sign up β Firebase Auth β Create profile β
β 2. Login β Firebase Auth β Load profile β
β 3. Subscribe β Stripe Checkout β Payment β
β 4. Delete account β Cloud Function β Delete all data β
β 5. Export data β Cloud Function β Download JSON β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FIRESTORE DATABASE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β app_users β User profiles & roles β
β customers β Stripe customer info β
β audit_logs β All actions (admin only) β
β webhook_logs β Stripe webhooks (admin only) β
β invoices β Factures β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLOUD FUNCTIONS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β handleStripeWebhook β Validate & process webhooks β
β createCheckoutSession β Create Stripe session β
β deleteUserData β Delete account & data β
β exportUserData β Export data to JSON β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β STRIPE API β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Customers β Store customer info β
β Subscriptions β Manage subscriptions β
β Invoices β Generate invoices β
β Webhooks β Send events β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π DΓ©ploiement
Firebase Deployment
# Deploy Firestore Rules
firebase deploy --only firestore:rules
# Deploy Cloud Functions
firebase deploy --only functions
# Deploy everything
firebase deploy
Environment Variables
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PUBLISHABLE_KEY=pk_live_...
SENDGRID_API_KEY=SG...
π Monitoring & Logging
Firestore Logging
admin.firestore().collection('audit_logs').add({
timestamp: admin.firestore.FieldValue.serverTimestamp(),
user_id: userId,
action: 'payment_success',
result: 'success',
details: {
amount: 999,
currency: 'EUR',
subscription_id: 'sub_...'
}
});
Cloud Functions Logging
console.log('Payment processed:', {
userId: uid,
amount: amount,
timestamp: new Date()
});
Monitoring
- Firebase Console : Voir les logs en temps rΓ©el
- Stripe Dashboard : Voir les paiements
- Firestore Console : Voir les donnΓ©es
π Maintenance & Updates
Mises à Jour Régulières
- DΓ©pendances : Chaque mois
- SΓ©curitΓ© : ImmΓ©diatement
- Stripe API : Suivre les annonces
- Firebase : Suivre les mises Γ jour
Backup & Recovery
- Firestore : Backup automatique (Google)
- Stripe : DonnΓ©es sauvegardΓ©es (Stripe)
- Recovery : Plan de rΓ©cupΓ©ration dΓ©fini
π Support & Troubleshooting
Problèmes Courants
Webhook non reΓ§u : - VΓ©rifier que Cloud Function est dΓ©ployΓ©e - VΓ©rifier que endpoint est accessible - VΓ©rifier les logs Stripe
Paiement Γ©chouΓ© : - VΓ©rifier les logs Firestore - VΓ©rifier les logs Stripe - VΓ©rifier la configuration Stripe
DonnΓ©es manquantes : - VΓ©rifier les Firestore Rules - VΓ©rifier les audit logs - VΓ©rifier les webhook logs
Document créé par Cascade - Architecture Stripe pour Yinshi