Architecture Stripe - Design Technique
Date de crรฉation : 11 novembre 2025
Statut : ๐ต Design technique
Propriรฉtaire : รquipe Dev
Derniรจre mise ร jour : 15 dรฉcembre 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
โ รtat actuel (implรฉmentation as-is)
L'intรฉgration Stripe actuellement en place dans Firebase est basรฉe sur une Firebase Extension (et non sur des Cloud Functions โmaisonโ dรฉclarรฉes dans ce repo) :
- Extension Firebase :
invertase/firestore-stripe-payments(Firestore Stripe Payments) - Fonctions dรฉployรฉes par l'extension (exemples) :
ext-firestore-stripe-payments-createCustomerext-firestore-stripe-payments-createCheckoutSessionext-firestore-stripe-payments-handleWebhookEventsext-firestore-stripe-payments-createPortalLinkext-firestore-stripe-payments-onUserDeletedext-firestore-stripe-payments-onCustomerDataDeleted- Secrets Stripe : stockรฉs dans Google Cloud Secret Manager (gรฉrรฉs par l'extension), notamment :
STRIPE_API_KEYSTRIPE_WEBHOOK_SECRET- Collections Firestore utilisรฉes par l'extension :
customers/{uid}/checkout_sessions/{sessionId}customers/{uid}/subscriptions/{subscriptionId}products(paramรฉtrage extension)customers(paramรฉtrage extension)
Note (environnements) :
- DEV/TEST : la PWA de test https://yinshi-test.yinshi.app/ pointe vers yin-shi-dev (extension installรฉe cรดtรฉ DEV/TEST).
- PROD : la migration/alignement de la prod vers cette extension (et/ou son paramรฉtrage รฉquivalent) n'est pas encore faite.
Pour les choix d'environnements (test/prod) :
- dรฉcision : docs/06_decisions/ADR-001-environnements-firebase-stripe-pwa-first.md
- plan de mise en place : docs/05_chantiers_actifs/stripe/OPTIONS_ENVIRONNEMENTS_TEST_PROD.md
๐๏ธ 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']));
}
});
}
Note : dans le code actuel, les URLs utilisรฉes sont :
- success_url: https://yinshi.app/web
- cancel_url: https://yinshi.app/web/#/premium-plans
Note (DEV/TEST PWA-first) : l'URL Web de test prรฉvue est https://yinshi-test.yinshi.app/ (voir ADR-001). Les URLs de retour Stripe (success/cancel) doivent pointer vers l'environnement correspondant.
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
Note : les fonctions dรฉcrites ci-dessous reprรฉsentent le design cible. Cรดtรฉ DEV/TEST (PWA-first), le flux Stripe est assurรฉ via l'extension invertase/firestore-stripe-payments (fonctions prรฉfixรฉes ext-firestore-stripe-payments-*). Cรดtรฉ PROD, la migration/alignement vers cette extension (ou รฉquivalent) reste ร faire.
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
Note : ce bloc est un exemple โdesign cibleโ. Dans l'implรฉmentation as-is basรฉe sur l'extension invertase/firestore-stripe-payments, les secrets Stripe sont gรฉrรฉs via Secret Manager (ex : STRIPE_API_KEY, STRIPE_WEBHOOK_SECRET) et ne sont pas attendus en clair dans le repo.
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