Le compte Stripe de developpement, et ce qui reste a faire dessus
Cet etat n'existait que dans une conversation. Il est ici pour survivre a sa fermeture : quel compte, quels Price IDs, ce qui est configure, ce qui ne l'est pas et pourquoi.
Cet etat n'existait que dans une conversation. Il est ici pour survivre a sa fermeture : quel compte, quels Price IDs, ce qui est configure, ce qui ne l'est pas et pourquoi.
Le compte
acct_1T7oJZ3Puq5YY65L, sandbox, FR, devise par defaut EUR.
Le mot compte, et ce document a d'abord ecrit l'autre. Un compte Stripe
ordinaire a deux modes, test et live, sous un seul acct_ : « passer
en live » y veut dire basculer un interrupteur et recreer les objets de
l'autre cote. Un sandbox n'est pas ce compte-la. C'est un compte a
part entiere, permanent, qui n'a aucun mode live et n'en aura jamais.
La preuve est un refus de l'API, pas une lecture de tableau de bord :
GET /v1/products (acct_1T7oJZ3Puq5YY65L, livemode: true)
-> The provided account acct_1T7oJZ3Puq5YY65L is a sandbox account.
Retry with livemode set to false.
Ce que « sandbox » coute se lit plus bas, dans Le passage en live : rien de ce qui suit n'est migrable.
Il y a deux comptes Stripe nommes boostecom.app, tous les deux des
sandbox, et l'API ne les distingue ni par leurs produits (les deux etaient
vides) ni par leur solde (les deux en EUR). Ce qui les separe :
acct_1T7oFI3OYmwbBTJN | acct_1T7oJZ3Puq5YY65L | |
|---|---|---|
| Cree | 1772764568 | 1772764833, 265 s plus tard |
business_profile | aucun | « Environnement de test boostecom.app » + URL |
| Libelle bancaire | CHRISTOPHER LASGI | BOOSTECOM.APP |
| Fuseau | Etc/UTC | Europe/Paris |
Le premier est un brouillon, le second celui qui a ete configure deliberement. Tout a ete monte sur le second. Le doublon n'est pas supprimable par l'API : aucune operation de suppression de compte n'existe dans la surface exposee, c'est une action de tableau de bord.
Les Price IDs
Sept prix, tous en USD et non en EUR : PLAN_PRICING
(src/types/billing-plans.ts) est
libelle en dollars, et la devise par defaut du compte ne change pas ce que
le catalogue declare. C'est le piege devise que
cac-report.ts nomme deja pour
la depense publicitaire, rencontre ici pour de vrai.
NEXT_PUBLIC_STRIPE_PRO_MONTHLY=price_1UEfAj3Puq5YY65LHh37xyaz # 79 $/mois
NEXT_PUBLIC_STRIPE_PRO_YEARLY=price_1UEfAl3Puq5YY65LkFEh4Bjl # 750 $/an
NEXT_PUBLIC_STRIPE_MAX_5X_MONTHLY=price_1UEfAw3Puq5YY65LP58txpmG # 199 $/mois
NEXT_PUBLIC_STRIPE_MAX_5X_YEARLY=price_1UEfB03Puq5YY65LlGd4IPyi # 1910 $/an
NEXT_PUBLIC_STRIPE_MAX_20X_MONTHLY=price_1UEfB83Puq5YY65LImyOUouV # 399 $/mois
NEXT_PUBLIC_STRIPE_MAX_20X_YEARLY=price_1UEfBC3Puq5YY65LWkPD3ePU # 3830 $/an
Ces sept-la ne sont pas des secrets : six sont NEXT_PUBLIC_ par
construction et partent dans le bundle navigateur. Le huitieme l'est et
n'est donc pas ici :
STRIPE_WEBHOOK_SECRET=whsec_… # rendu UNE SEULE FOIS, a la creation
Stripe ne re-affiche jamais un signing secret. Perdu = recreer l'endpoint.
Tous les prix portent tax_behavior: "exclusive" : la taxe s'ajoute
au-dessus, ce qui correspond au fait que le grant de credits lit
metadata.amount (hors taxe) et jamais amount_total.
Le webhook
we_1UEfBm3Puq5YY65L4xDQ2C91, status: enabled, vers
https://boostecom.app/api/webhooks/stripe.
Les 14 evenements sont exactement ceux que
src/services/webhooks.ts traite, ni un
de plus :
checkout.session.completed
customer.subscription.created | updated | deleted
invoice.paid | payment_failed | payment_action_required
payment_intent.succeeded | payment_failed
charge.refunded | dispute.created | dispute.closed
payout.failed
account.updated
Ce qui N'A PAS ete cree, et pourquoi
Pas de prix trimestriel
Il n'y a pas de cadence trimestrielle a configurer : le proprietaire l'a
supprimee le 2026-10-02 (billing/0373). Les trois variables
NEXT_PUBLIC_STRIPE_*_QUARTERLY ont quitte le schema (src/env/server.ts),
.env.example et l'audit d'environnement. Deux cadences sont vendues :
mensuel et annuel, six Price IDs.
Rien pour trois des quatre entrees d'argent
Le systeme complet d'entree et de sortie d'argent, releve depuis le code :
| Flux | Chemin | Besoin Stripe |
|---|---|---|
| Abonnements | api/stripe/checkout | 6 Price IDs — faits |
| Boutique additionnelle | non vendue (ADR 0037, puis 0039 : boutiques incluses par palier, sans add-on) | l'ancien Price ID price_1UEfCo3Puq5YY65L1Dq4YEOb reste dans le sandbox, porte par aucun abonnement (verifie le 2026-09-25). A garder pour un eventuel retour de l'add-on, a ne pas copier en live |
| Achat de credits | api/credits/purchase | aucun : price_data, montant libre USD |
| Sponsors | api/sponsor/checkout | aucun : price_data, montants de SPONSOR_PRICE_CENTS (services/billing/items.ts), USD depuis billing/3137 |
| Marketplace | api/marketplace/.../checkout | Connect |
| Remboursements | services/stripe/refunds | aucun |
| Payouts vendeurs + clawback | services/stripe/connect | Connect |
Le 9 $/boutique n'invente rien : ADDITIONAL_STORE_PRICE_MONTHLY = 9,
et les cartes de pricing le vendent deja. C'est ce qui le distingue du
trimestriel.
Le portail client (sandbox)
Le sandbox n'avait aucune configuration de portail : billing-portal
et le changement de plan de checkout (qui ouvrent la configuration par
defaut) echouaient donc. Creee le 2026-09-25 et marquee par defaut :
bpc_1UJUs53Puq5YY65Lh7zaYgcI.
| Reglage | Valeur | Pourquoi |
|---|---|---|
| Changement de plan | Pro, Max 5x, Max 20x, mensuel et annuel | les 6 prix du catalogue ; pas le trimestriel (non vendu), pas l'ancien add-on |
| Montee de palier | always_invoice | facturee tout de suite : le webhook recredite sur la montee, donc elle doit etre payee avant |
| Descente de palier ou d'intervalle | a la fin de la periode | sinon monter puis redescendre dans l'heure donnait les credits du palier superieur quasi gratuitement |
| Annulation | en fin de periode, motif demande | |
| Factures, moyen de paiement, adresse, numero de TVA | modifiables |
En live, la meme configuration est a recreer (ou « Copy to live mode » depuis le Dashboard), avec les Price IDs live.
Tester de bout en bout (sandbox)
boostecom.app tourne sur les cles du sandbox (les sessions Checkout du
sandbox renvoient vers www.boostecom.app). Carte de test : 4242 4242 4242 4242, date future, CVC quelconque. Carte refusee : 4000 0000 0000 9995. Carte 3DS : 4000 0025 0000 3155.
| # | Action | Attendu |
|---|---|---|
| 1 | Creer un compte neuf (/auth), une organisation | Plan Free, 0 credit |
| 2 | Connecter 1 boutique, puis tenter une 2e | La 2e est refusee (402) et propose Pro |
| 3 | /pricing → Pro mensuel → payer avec 4242 | ~/billing/activate passe au vert, plan Pro, 49 $ de credits, bonus quotidien 1 $ |
| 4 | Creer les boutiques 2 et 3, puis une 4e | 2 et 3 passent ; la 4e est refusee et propose Max 5x |
| 5 | ~/billing → Gerer l'abonnement → passer a Max 5x | Facture immediate au prorata, plan Max 5x, credits completes a 149 $ |
| 6 | Portail → redescendre a Pro | Programme pour la fin de periode, plan inchange d'ici la |
| 7 | Portail → annuler | Actif jusqu'a la fin de periode, puis Free ; les boutiques restent, aucune creation au-dela d'une |
| 8 | Refaire 3 avec la carte 4000 0000 0000 9995 | Echec affiche, plan inchange |
| 9 | Refaire 3 avec la carte 3DS | Defi 3DS, puis actif |
| 10 | /admin/revenue/webhooks | Chaque evenement en succes, aucun en rouge |
L'annuel ne s'ouvre qu'a une organisation de plus de 30 jours
(billing-cadence) : pour le tester, utiliser une organisation ancienne.
Releve par l'API le 2026-09-12, pas par impression :
| Preuve | |
|---|---|
| Compte active | charges_enabled: true, payouts_enabled: true, details_submitted: true, ToS acceptes, compte bancaire verifie |
| Connect active | POST /v1/_unstable/connect/enable rend {"enabled": true}. Marketplace et payouts vendeurs sont donc debloques |
Le premier appel a EnableConnect avait rendu un timeout a 9,9 s, et
GET /v1/accounts repondait ensuite sans erreur. Ce n'etait PAS une
preuve : le meme appel repond pareil sur le compte doublon, ou Connect
n'a jamais ete active. Le test controle ne discriminait pas. Seul le
rappel de l'operation a tranche.
Ce qui reste, et qui ne peut pas etre fait par l'API
- Poser les 8 variables ci-dessus.
- Remplir
head_office.GET /v1/tax/settingsrendstatus: "pending",missing_fields: ["head_office"]. C'est une adresse d'etablissement, donc une declaration fiscale : elle ne s'invente pas. - Supprimer le doublon
acct_1T7oFI3OYmwbBTJN. Toujours present au 2026-09-12.
Numero de TVA intracommunautaire (autoliquidation B2B)
La saisie du numero de TVA au Checkout n'est pas un reglage du
Dashboard : c'est le parametre d'API tax_id_collection: { enabled: true },
pose par src/app/api/stripe/checkout/route.ts (abonnement) et
src/app/api/credits/purchase/route.ts (credits). Quand un customer
existant est passe, la session porte aussi
customer_update: { name: "auto", address: "auto" } (Stripe refuse
tax_id_collection sur un customer existant sans customer_update.name) ;
sans customer, l'abonnement en cree un et l'achat de credits passe
customer_creation: "always", ce qui garde le numero sur le customer.
Ce qui reste cote Dashboard, d'apres la doc Stripe Tax : Stripe Tax actif
avec head_office rempli (point 2 ci-dessus) et les enregistrements
fiscaux (Tax > Registrations) des pays ou BoostEcom est immatricule.
L'autoliquidation n'est calculee que pour un acheteur situe dans un pays
de l'UE autre que celui d'un enregistrement, avec un numero valide. Le
checkout sponsor (pilier marketplace) et le checkout marketplace (retire
par marketplace/3145) ne collectent pas le numero.
Le passage en live
Le compte ci-dessus etant un sandbox, il n'y a rien a basculer. Aucun
des objets releves dans ce document ne traverse : ni les sept Price IDs,
ni le webhook we_…, ni l'activation Connect, ni les reglages Tax. Le
jour du passage en production, tout est a recreer sur un autre
acct_, et les identifiants seront differents jusqu'au dernier
caractere.
Ce n'est pas une mauvaise nouvelle, c'est une nouvelle a connaitre avant d'y etre : travailler en sandbox reste le bon choix tant qu'aucun vrai utilisateur n'est la, parce qu'un sandbox ne peut structurellement pas encaisser un vrai paiement par erreur.
Les comptes joignables, et lequel est lequel
| Compte | acct_ | Live | Sandbox |
|---|---|---|---|
boostecom.app | acct_1T7oJZ3Puq5YY65L | non | oui (celui-ci) |
boostecom.app | acct_1T7oFI3OYmwbBTJN | oui (vide au 2026-09-25 : 0 produit, 0 prix, 0 abonnement) | oui (vide) |
boostecom.fr | acct_1FrGnWKdjXqy9xFN | oui | oui |
easyconnector.app | acct_1T7od5Kn1YFvny11 | oui | oui |
Au 2026-09-25, acct_1T7oFI3OYmwbBTJN repond en live sous le nom
boostecom.app : c'est le compte de production de la plateforme, et il est
vide. Il n'est donc plus a supprimer comme doublon. Le releve du
2026-09-12 (« aucun compte live ne s'appelle boostecom.app ») est
perime.
Le piege : une cle live branchee sur le mauvais compte
Il decoule directement du tableau. Une cle live « de boostecom.app »
donnee a un tiers (DataFast, un tableau de bord, un connecteur) ne peut
pas venir d'un compte qui n'existe pas : elle vient de boostecom.fr ou
d'easyconnector.app.
Le tiers rapporte alors du revenu reel, arrive vraiment,
correctement attribue... a la mauvaise entreprise. Rien n'echoue, rien ne
s'affiche en rouge, et le chiffre a l'air juste. Le seul controle qui
tranche est de comparer, dans le tableau de bord du tiers, l'acct_
connecte a la colonne acct_ ci-dessus : le nom affiche ne suffit pas,
puisque deux comptes portent le meme.
Ce que la migration demande reellement
Douze variables portent Stripe dans
src/env/server.ts. La liste est derivee, pas
retapee : src/test/stripe-setup-doc-covers-the-price-keys.test.ts echoue
si une cle du schema manque ici.
| Variable | A refaire en live | Pourquoi |
|---|---|---|
STRIPE_SECRET_KEY | oui | la cle EST le compte |
STRIPE_WEBHOOK_SECRET | oui | rendu une seule fois, a la creation de l'endpoint |
NEXT_PUBLIC_STRIPE_PRO_MONTHLY | oui | Price ID, lie au compte |
NEXT_PUBLIC_STRIPE_PRO_YEARLY | oui | Price ID, lie au compte |
NEXT_PUBLIC_STRIPE_MAX_5X_MONTHLY | oui | Price ID, lie au compte |
NEXT_PUBLIC_STRIPE_MAX_5X_YEARLY | oui | Price ID, lie au compte |
NEXT_PUBLIC_STRIPE_MAX_20X_MONTHLY | oui | Price ID, lie au compte |
NEXT_PUBLIC_STRIPE_MAX_20X_YEARLY | oui | Price ID, lie au compte |
Et trois choses qui ne sont pas des variables : les 14 evenements du
webhook, l'activation Connect (sans quoi marketplace et payouts
vendeurs sont morts) et les reglages Tax, head_office compris.
Une seule chose traverse reellement : ce fichier. Il decrira alors deux jeux d'identifiants et non un.