- Ouvrir le site en navigation privรฉe (ou vider cookies/localStorage)
- Vรฉrifier : Pas de login automatique
- Naviguer vers
/exploreโ Choisir un truck - Ajouter des items au panier
- Cliquer "Payer"
Rรฉsultat attendu :
- La page Checkout affiche : "๐ก Vous pouvez payer sans crรฉer de compte..."
- Pas d'erreur dans la console
- Cliquer sur "Payer sur Stripe"
- Ouvrir DevTools โ Console
- Vรฉrifier qu'un
signInAnonymously()est appelรฉ
Rรฉsultat attendu :
// Dans la console DevTools
[PLANIZZA] Firebase non configurรฉ (mode DEV)...
// OU si Firebase configurรฉ :
auth.currentUser.isAnonymous === true
auth.currentUser.uid !== null // UID Firebase valide (ex: "abc123xyz")- Aprรจs crรฉation du compte anonyme, vรฉrifier la redirection Stripe Checkout
Rรฉsultat attendu :
- Redirection vers
https://checkout.stripe.com/... - Aucune erreur 401 "Vous devez รชtre connectรฉ pour payer"
- Sur la page Stripe Checkout, utiliser une carte de test :
- Numรฉro :
4242 4242 4242 4242 - Expiration : N'importe quelle date future (ex:
12/34) - CVC : N'importe quel 3 chiffres (ex:
123)
- Numรฉro :
- Cliquer "Payer"
Rรฉsultat attendu :
- Redirection vers
/checkout/success?orderId=xxx&session_id=yyy
- Vรฉrifier l'affichage initial : "Commande en cours de validation"
- Attendre 3 secondes โ Le webhook Stripe devrait passer
- Vรฉrifier l'affichage final : "Paiement validรฉ !"
Rรฉsultat attendu :
- Bloc de crรฉation de compte visible avec texte :
"๐ Crรฉez un compte pour suivre votre commande !" "Votre paiement est confirmรฉ ! En crรฉant un compte maintenant..."
- Bouton "Crรฉer mon compte"
- Cliquer sur "Crรฉer mon compte"
- Vรฉrifier la redirection vers
/register
Rรฉsultat attendu :
- URL :
/register location.state.orderIdcontient l'ID de la commande- Titre : "Sauvegarder votre commande" (au lieu de "Crรฉer un compte")
- Remplir le formulaire :
- Email :
test+guest@example.com - Password :
password123
- Email :
- Cliquer "S'inscrire"
Rรฉsultat attendu dans DevTools Console :
[PLANIZZA] Compte anonyme upgradรฉ avec succรจs ! abc123xyzVรฉrifications Firebase :
- Ouvrir Firebase Console โ Authentication โ Users
- Chercher l'UID du user (ex:
abc123xyz) - Vรฉrifier :
- Provider :
password(plusanonymous) - Email :
test+guest@example.com - UID : IDENTIQUE ร celui crรฉรฉ au checkout
- Provider :
- Aprรจs inscription, vรฉrifier la redirection vers
/order/{orderId} - Vรฉrifier que la commande s'affiche correctement
- Ouvrir Firebase Console โ Realtime Database โ
orders/{orderId}
Rรฉsultat attendu dans RTDB :
{
"userUid": "abc123xyz", // โ Mรชme UID !
"status": "received",
"payment": {
"paymentStatus": "paid"
},
// ... reste des donnรฉes
}โ Preuve que l'upgrade a fonctionnรฉ : L'UID n'a pas changรฉ, donc la commande reste liรฉe au mรชme utilisateur.
cd functions
npm run lint
cd ..
npm run firebase:functionsRรฉsultat attendu :
โ functions[us-central1-cleanupAnonymousUsers]: Successful create operation.
Option A : Modifier le code temporairement
// Dans functions/index.js, ligne 1720
const RETENTION_MS = 10 * 1000; // 10 secondes (au lieu de 48h)Puis exรฉcuter :
# Lancer les รฉmulateurs
npm run emulators
# Dans un autre terminal, dรฉclencher manuellement la fonction
firebase functions:shell
> cleanupAnonymousUsers()Rรฉsultat attendu dans les logs :
[PLANIZZA][cleanupAnonymousUsers] Found 1 anonymous users older than 48h
[PLANIZZA] Keeping anonymous user abc123xyz (has orders)
[PLANIZZA][cleanupAnonymousUsers] Completed: 0 deleted, 1 protected, 0 errors
-
Crรฉer un compte anonyme orphelin :
// Dans la console DevTools du site await firebase.auth().signInAnonymously(); // Noter l'UID (ex: "orphan123") console.log(firebase.auth().currentUser.uid);
-
Ne PAS crรฉer de commande (juste se dรฉconnecter)
-
Attendre 48h (ou modifier
RETENTION_MSpour test) -
Exรฉcuter
cleanupAnonymousUsers()
Rรฉsultat attendu :
[PLANIZZA] Deleted anonymous user orphan123
[PLANIZZA][cleanupAnonymousUsers] Completed: 1 deleted, 0 protected, 0 errors
Cause : signInAnonymously() a รฉchouรฉ ou n'a pas รฉtรฉ appelรฉ.
Debug :
// Dans Checkout.jsx, ajouter un console.log
console.log('User UID:', userUid);
console.log('Auth currentUser:', auth.currentUser);Solution :
- Vรฉrifier que
authest bien importรฉ depuislib/firebase.js - Vรฉrifier que Firebase est configurรฉ (
.env.localrempli)
Cause : L'email existe dรฉjร dans un autre compte Firebase.
Solution :
- Supprimer le compte existant dans Firebase Console
- OU utiliser un autre email de test
Symptรดmes :
- Aprรจs inscription, l'UID dans RTDB a changรฉ
- La commande n'est plus visible pour le nouveau compte
Debug :
// Dans Register.jsx, avant linkWithCredential
console.log('Current user before link:', auth.currentUser.uid, auth.currentUser.isAnonymous);Solution :
- Vรฉrifier que
useAuth()retourne bienuser.isAnonymous === true - Vรฉrifier que
auth.currentUsern'est pasnull
Debug :
# Vรฉrifier que la fonction est dรฉployรฉe
firebase functions:list
# Vรฉrifier les logs
firebase functions:log --only cleanupAnonymousUsersSolution :
- Vรฉrifier que le schedule est correct (
every 24 hours) - Pour forcer l'exรฉcution : Firebase Console โ Functions โ cleanupAnonymousUsers โ "Test function"
Aprรจs 1 semaine de prod, vรฉrifier dans Firebase Analytics :
-
Taux de conversion Guest โ Compte :
- Combien de guests crรฉent un compte aprรจs paiement ?
- Cible : > 30%
-
Erreurs de paiement :
- Est-ce que les erreurs 401 "Vous devez รชtre connectรฉ" ont disparu ?
- Cible : 0 erreur
-
Comptes anonymes actifs :
- Combien de comptes anonymes ont > 48h et ont des commandes ?
- Ces comptes doivent รชtre protรฉgรฉs (pas supprimรฉs)
-
Cleanup efficace :
- Combien de comptes anonymes sans commandes sont supprimรฉs par jour ?
- Cible : Rรฉduction progressive du nombre total d'anonymes
Avant de pousser en production :
- Tests 1.1 ร 1.5 passent en local
- Tests 2.1 ร 2.3 passent en local
- Cloud Function dรฉployรฉe et testรฉe
- Cleanup orphan testรฉ (au moins 1 suppression rรฉussie)
- Pas de console.log sensibles (tokens, emails) en prod
-
.env.localne contient que des clรฉs TEST Stripe - README.md mis ร jour avec la nouvelle doc guest checkout
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Guest arrive sur le site (pas de compte) โ
โ โ auth.currentUser === null โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. Guest ajoute items au panier (localStorage) โ
โ โ Aucun compte crรฉรฉ ร ce stade โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. Guest clique "Payer sur Stripe" โ
โ โ Checkout.jsx : signInAnonymously(auth) โ
โ โ Firebase crรฉe un compte anonyme (UID: "abc123") โ
โ โ auth.currentUser.isAnonymous === true โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4. createCheckoutSession (Function) โ
โ โ Reรงoit le token Firebase du compte anonyme โ
โ โ Crรฉe orders/{orderId} avec userUid: "abc123" โ
โ โ Crรฉe session Stripe โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 5. Paiement Stripe + Webhook โ
โ โ orders/{orderId}/status = "received" โ
โ โ payment.paymentStatus = "paid" โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 6. CheckoutSuccess affiche "Crรฉer mon compte" โ
โ โ Guest clique โ Navigate to /register โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 7. Register.jsx dรฉtecte user.isAnonymous === true โ
โ โ linkWithCredential(currentUser, emailPasswordCredential) โ
โ โ UID reste "abc123" (pas de nouvel UID crรฉรฉ) โ
โ โ providerData change : [password] au lieu de [] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 8. Historique prรฉservรฉ โ
โ โ orders/{orderId}/userUid === "abc123" (inchangรฉ) โ
โ โ User peut suivre sa commande โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 9. Cleanup aprรจs 48h (si pas upgradรฉ) โ
โ โ cleanupAnonymousUsers() scanne les anonymes โ
โ โ Si commande existe โ PROTรGร โ
โ โ Si pas de commande โ SUPPRIMร โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Une fois tous les tests passรฉs, exรฉcuter ce dernier test end-to-end :
# 1. Build production
npm run build
# 2. Dรฉployer
npm run firebase:deploy
# 3. Test sur l'URL de production
# https://planizza-ac827.web.app
# 4. Navigation privรฉe โ Guest checkout complet โ Upgrade compte
# 5. Vรฉrifier Firebase Console :
# - Auth : 1 user avec email + password provider
# - RTDB : 1 order avec le bon userUid
# - Functions logs : cleanupAnonymousUsers scheduledSi tout passe : Fix #1 validรฉ โ
Prochaine รฉtape : Fix #2 (Validation prix serveur)