Guide de construction d'une boutique dropshipping (version Patounes)
Boutique de référence : Patounes (accessoires pour chiens et chats), construite avec Claude Code à partir de la boutique Maison Bien-Être. Ce guide rassemble tous les points de construction, dans l'ordre réel, avec les commandes, les formules, les scripts, les décisions et les pièges, pour recréer la même boutique sur une autre niche en un temps réduit. Il ne contient aucun secret : seuls les noms des variables sont indiqués. Il complète GUIDE-FABRICATION-BOUTIQUE.md (modèle Maison Bien-Être) avec ce qui a été appris sur Patounes.
0. Comment utiliser ce guide
Pour une nouvelle boutique, remplacer ces variables partout (fichier central : src/lib/site.ts).
| Variable | Patounes | Nouvelle boutique |
|---|---|---|
{{NOM}} | Patounes | … |
{{SOUS_TITRE}} | par : What else by Vinc | … |
{{DOMAINE}} | patounes.whatelsebyvinc.com (sous-domaine) | … |
{{THEME}} | accessoires et bien-être pour chiens et chats | … |
{{CATEGORIES}} | chiens, chats | 2 maximum |
{{SOUS_CATEGORIES}} | 3 par catégorie (6 au total) | 3 par catégorie |
{{PAYS}} | FR, BE, CH, LU | … |
{{DELAI}} | 7 à 20 jours ouvrés | selon la route CJ |
{{MARGE}} | 35 % (28 % pour la gamme d'appel) | … |
{{EMAIL}} | contact@whatelsebyvinc.com | … |
Ordre conseillé : lire 1 à 3, suivre 16 (checklist), copier les consignes du 17, adapter selon le 19.
1. Architecture
Visiteur ─▶ Next.js (Vercel) ─▶ Stripe Checkout ─▶ paiement
│ │ webhook checkout.session.completed
▼ ▼
Neon Postgres ◀── commande + lignes (une seule requête, idempotent)
│
CJ : créer la commande ─▶ payer sur le solde CJ
│
cron quotidien : relance, paiement en attente, suivi
│
alertes Slack (facultatif) · /admin pour les commandes à payer| Brique | Choix |
|---|---|
| Framework | Next.js 16.4 (App Router, Turbopack), React 19.3, TypeScript |
| Style | Tailwind CSS 4 (@tailwindcss/turbopack), thème sombre automatique, palette stone + accent amber |
| Base | Neon Postgres (@neondatabase/serverless) |
| Hébergement | Vercel (déploiement par CLI, 1 cron par jour sur l'offre gratuite) |
| Paiement | Stripe Checkout (test puis réel) |
| Fournisseur | CJdropshipping API v2 |
| Mesure | @vercel/analytics (sans cookies) |
| Code | Dépôt Git local (pas de GitHub sur Patounes) |
Principes : zéro capital d'avance (le client finance CJ) · honnêteté (aucune promesse de santé, délais = moyenne) ·
idempotence (un événement rejoué ne crée rien en double) · le serveur relit les prix en base · les règles
(livraison, retours, contact) sont écrites une seule fois (src/lib/faq.ts, src/lib/site.ts) et reprises partout.
2. Déroulé réel (Patounes) et durées indicatives
| # | Étape | Qui | Durée |
|---|---|---|---|
| 1 | Cadrage : niche, 2 catégories, 6 sous-catégories, domaine | vous + Claude | 15 min |
| 2 | Socle Next.js, schéma SQL, pages, checkout, webhook | Claude | 1 h |
| 3 | Commande fournisseur CJ, cron, alertes | Claude | 30 min |
| 4 | Compte Vercel relié, déploiement, domaine, DNS Cloudflare, certificat | vous + Claude | 30 min |
| 5 | Base Neon, schéma, secrets locaux, variables Vercel | vous + Claude | 30 min |
| 6 | Vague 1 de produits (3) puis vague 2 (23) puis vague 3 (28) | Claude | 1 h chacune |
| 7 | Flux Google/Meta/Pinterest, 3 guides, JSON-LD | Claude | 1 h |
| 8 | Reprise des fonctionnalités de l'ancienne boutique (voir 5.2) | Claude | 1 h |
| 9 | Routine quotidienne de produits | Claude | 45 min |
| 10 | Gamme d'appel (prix d'entrée) et rappel de bilan | Claude | 30 min |
Total : environ une journée de travail pour une boutique de 60 produits, hors comptes et validations.
3. Comptes et partage des tâches
À créer par vous (Claude ne crée pas de compte et n'accepte pas de conditions) : Vercel, Neon, Stripe, CJdropshipping (clé API), Cloudflare (DNS), GitHub (facultatif), Slack (webhook, facultatif), Google Merchant Center / Meta Commerce / Pinterest Business / Search Console (voir 12.4).
| Vous (obligatoire) | Claude |
|---|---|
| Créer les comptes, accepter les conditions | Écrire tout le code, les textes, les scripts |
| Saisir les clés Stripe (secrète et webhook) dans Vercel ou dans un fichier local | Lire les secrets via des scripts, sans jamais les afficher |
| Recharger le solde CJ avec l'argent des ventes | Créer les commandes, relancer, alerter |
Définir ADMIN_PASSWORD | Préparer l'écran /admin |
Taper un vrai paiement de test (carte 4242…) | Vérifier base, webhook, alertes ensuite |
| Valider les actions en mode réel et sur la base de production | Préparer, tester, déployer après accord |
Outils en ligne de commande à avoir connectés : vercel (compte lié), neon (organisation choisie via --org-id),
stripe (travaille dans le bac à sable par défaut), node ≥ 20, git, python + Pillow (planches de photos).
4. Fondations : Vercel, Neon, DNS, secrets
4.1 Projet
npx create-next-app@latest . --ts --tailwind --app --eslint --src-dir --use-npm --import-alias "@/*" --yes
npm i @neondatabase/serverless stripe @vercel/analyticsNext 16 : retirer cacheComponents et partialPrefetching du next.config.ts ; garder la règle turbopack pour
Tailwind ("*.css": { loaders: ["@tailwindcss/turbopack"], as: "*.css" }) sinon @theme n'est pas reconnu.
Images : images.remotePatterns pour **.cjdropshipping.com et cj-product-center.oss-accelerate.aliyuncs.com.
4.2 Vercel
vercel link --yes --project <nom> # crée et relie le projet
vercel deploy --yes # le tout premier déploiement part en PRODUCTION
vercel deploy --prod --yes # déploiements suivants
vercel domains add <sous-domaine> <projet>
vercel certs issue <sous-domaine> # le certificat n'est pas toujours émis seul
vercel env add NOM production --sensitive --yes # valeur lue sur l'entrée standard, jamais affichée
vercel env ls production # noms seulementUne variable ajoutée n'est prise en compte qu'au déploiement suivant. Ajouter chaque secret en production,
preview et development. vercel.json : un seul cron quotidien (/api/cron/supplier-sync, 0 7 * * *).
4.3 DNS (Cloudflare)
Enregistrement A, nom = le sous-domaine, valeur 76.76.21.21, DNS uniquement (nuage gris, pas de proxy).
Un sous-domaine s'écrit patounes.mondomaine.com : patounes-mondomaine.com serait un autre domaine à acheter.
Vérifier : nslookup <sous-domaine> 1.1.1.1, puis vercel domains inspect, puis attendre le certificat.
4.4 Neon
npx neon@latest projects list --org-id <org> # le CLI demande l'organisation sinon (interactif)
npx neon@latest connection-string --project-id <id> --pooled # à rediriger vers un fichier, jamais à l'écranRejouer sql/schema.sql (uniquement create … if not exists). Installer les skills : npx neon@latest skills -s neon -s neon-postgres -y.
4.5 Fichiers de secrets locaux (tous ignorés par Git : .env*)
| Fichier | Contenu |
|---|---|
.env.db.local | DATABASE_URL |
.env.cj.local | CJ_API_KEY, CJ_ACCESS_TOKEN, CJ_REFRESH_TOKEN, CRON_SECRET |
.env.stripe.local | STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET |
.env.local | créé par Vercel (VERCEL_OIDC_TOKEN) |
Ne jamais charger ces fichiers avec source : l'URL Neon contient des & que le shell coupe. Utiliser
node --env-file=.env.db.local … ou les lire dans les scripts. Afficher seulement le préfixe d'une clé (sk_test / sk_live).
4.6 Variables d'environnement (noms)
DATABASE_URL · STRIPE_SECRET_KEY · STRIPE_WEBHOOK_SECRET · CJ_ACCESS_TOKEN · CRON_SECRET ·
NEXT_PUBLIC_SITE_URL · ADMIN_PASSWORD · (facultatif) ALERT_WEBHOOK_URL, NEXT_PUBLIC_CONTACT_EMAIL.
5. Code
5.1 Arborescence
src/app/ page.tsx · layout.tsx · sitemap.ts · robots.ts · icon.svg · favicon.ico · apple-icon.png
produits/[slug] categorie/[category](/[subcategory]) panier suivi-commande guides(/[slug])
faq livraison retours contact a-propos mentions-legales cgv confidentialite
commande/succes commande/meta (pont Meta) flux/produits.xml/route.ts
admin/avis admin/commandes api/{checkout,webhooks/stripe,cron/supplier-sync,order-status,avis,chat}
src/components/ ProductDetailV2 · ProductGallery · StickyBuyBar · ProductGrid · CategoryCards · CategoryNav ·
RotatingImage · ReviewForm · ChatWidget · SiteLogo · SiteFooter · LegalHeader · InfoPage · JsonLd
src/lib/ site · products · product-sections · db · stripe · cjdropshipping · fulfillment · orders · reviews ·
admin-auth · alerts · delivery · faq · guides · cart-context · chat/{engine,catalog}
sql/ schema.sql · ajustements/ (traces des vagues) · routine/ (traces quotidiennes)
scripts/ cj.mjs · wave*.json · gamme-appel.json · bilan-gamme.mjs · routine/{cj,q,ins}.mjs + jour.json5.2 Reprendre une boutique existante (méthode la plus rapide)
Quand une boutique de même architecture existe déjà : copier les fichiers génériques éprouvés, puis adapter les
chaînes propres à la niche. Fichiers génériques : components/*, lib/{admin-auth,alerts,cart-context,cjdropshipping, delivery,fulfillment,orders,product-sections,reviews,stripe,db}, app/{admin,api,commande,suivi-commande,categorie, produits,panier}. À réécrire : lib/products.ts (libellés), lib/guides.ts, lib/chat/catalog.ts (synonymes),
CategoryCards, textes de l'accueil, layout.tsx, app/flux (catégorie Google), pages d'information.
Rechercher ensuite les résidus : grep -rniE "<ancien nom>|<saison>|<ancienne niche>" src.
5.3 Particularités Next.js 16 à connaître
paramsetsearchParamssont des Promesses ;cookies()est asynchrone.- Une page qui interroge la base et n'a pas
dynamic = "force-dynamic"nirevalidateest pré-générée au build : si le build n'a pasDATABASE_URL, elle fige l'état « base indisponible » (ISR de 60 s la corrige à la première requête). sitemap.tsdoit êtreforce-dynamic, sinon il ne voit pas les produits ajoutés après le build.- Les pages doivent tolérer une base absente (
.catch(() => [])) : le build ne doit jamais casser. - Fichiers copiés depuis Windows : fins de ligne CRLF. Normaliser (
sed -i 's/\r$//') avant tout remplacement par expression régulière, sinon les remplacements multi-lignes échouent sans erreur. - Logo : composant SVG inline (
SiteLogo) +icon.svg,favicon.ico(16/32/48) etapple-icon.png(180) danssrc/app/.
6. Base de données
Tables : products, orders, order_items, supplier_orders, reviews (schéma complet : sql/schema.sql).
Colonnes clés de products : slug (unique), description (format strict, voir 7.2), price_cents, category,
subcategory, in_stock, images (jsonb : la 1re = image_url), cj_product_id, cj_variant_id, cj_logistic_name.
Conventions : sql/schema.sql rejouable · chaque écriture de données laisse une trace datée dans
sql/ajustements/AAAA-MM-JJ-sujet.sql (vagues, prix) ou sql/routine/AAAA-MM-JJ.sql (routine) · insertions
paramétrées avec on conflict (slug) do nothing · changement de prix gardé :
update products set price_cents = NEW where slug = 'x' and price_cents = OLD.
Scripts d'écriture jetables (*.tmp.mjs) : ils lisent .env.db.local, n'affichent jamais de valeur, sont supprimés après usage.
7. Catalogue
7.1 Taxonomie
2 catégories, 3 sous-catégories chacune (6 au total). Libellés dans CATEGORY_LABELS / SUBCATEGORY_LABELS
(src/lib/products.ts). Déployer un nouveau libellé avant d'insérer des produits, sinon le slug brut s'affiche.
Patounes : chiens → promenade, jouets-chiens, couchage-chiens ; chats → jouets-chats, griffoirs, couchage-chats.
7.2 Format d'une fiche (parsé par le gabarit de page)
Accroche d'une phrase.
Ce que vous obtenez :
• 4 puces factuelles (matière, taille, contenu, particularité visible sur la photo)
Phrase d'usage.Règles : français soigné, uniquement des faits (fiche CJ ou photo) ; sinon « selon la fiche du fournisseur » ;
aucune allégation de santé ; aucune marque ; une puce « Vendu à l'unité (modèle X ; les autres coloris visibles ne
sont pas inclus) » quand les photos montrent d'autres variantes ; nom court avec matière ou format entre parenthèses ;
slug kebab-case sans accents, unique.
7.3 Photos
image_url = photo de la variante vendue ; images = 1 à 4 photos de la même variante. Rejeter : texte publicitaire
ou cotes sur la photo principale, filigrane, logo d'une autre marque, variantes côte à côte, rendu IA différent du produit,
photos d'un autre article que celui vendu (ex. pièce seule vs set complet). Une photo avec cotes n'est acceptable qu'en
dernière position de la galerie.
8. Sourcing CJdropshipping
8.1 Authentification (piège majeur)
La clé API CJ (forme xxxx@api@xxxx) n'est pas le jeton d'accès. L'échanger :
POST /v1/authentication/getAccessToken {"apiKey": "..."} → accessToken (valable environ 6 mois) + refreshToken.
Renouvellement : POST /v1/authentication/refreshAccessToken. Limite : 1 échange toutes les 5 minutes.
Le jeton se met aussi dans Vercel (CJ_ACCESS_TOKEN) : la tâche de commandes l'utilise. Noter la date d'expiration.
8.2 API (base https://developers.cjdropshipping.com/api2.0, en-tête CJ-Access-Token)
| Usage | Appel |
|---|---|
| Recherche | GET /v1/product/listV2?keyWord=<anglais>&size=20 → data.content[0].productList |
| Détail | GET /v1/product/query?pid= → variantes (vid, variantKey, variantSellPrice, variantImage, variantStandard), productImage (chaîne JSON), description |
| Livraison | POST /v1/logistic/freightCalculate {startCountryCode:"CN", endCountryCode:"FR", products:[{quantity:1, vid}]} |
| Commande | POST /v1/shopping/order/createOrderV3 (isSandbox 1/0, iossType: 3, iossNumber: "CJ-IOSS") |
| Payer | POST /v1/shopping/pay/payBalance · solde : GET /v1/shopping/pay/getBalance |
| My Products | POST /v1/product/addToMyProduct {productId} (code 100002 = déjà ajouté) |
1 appel par seconde (code 1600200) : espacer de 1,3 à 1,5 s et réessayer. Les commandes sandbox ne se paient pas. |
8.3 Pipeline d'une vague de produits (reproductible)
- Recherche : 40 à 50 mots-clés en anglais répartis par sous-catégorie ; garder les 4 premiers par
listedNumavecwarehouseInventoryNum > 100; exclure ce qui est déjà en base (cj_product_id) et le bruit (regex : vêtements, médical/vétérinaire, électronique, piles, LED, laser, GPS, caméra, distributeur automatique, cage, marque, adulte…). - Détail + livraison de chaque candidat (variante la moins chère) ; route au
totalPostageFeele plus bas dont le délai maximal est ≤ 15 jours ; calcul du prix et de la marge (section 9) ; écarter au-delà de 34,90 € (couchages 44,90 €). - Planches de photos numérotées (Python + Pillow, 8 produits par planche, 1re vignette = variante vendue) : regarder toutes les planches. Taux de rejet observé : environ 40 % (texte sur la photo, mauvaise variante, produit différent, marque, parodie de marque, produit électronique).
- Rédiger les fiches (7.2) dans un fichier
wave*.json:slug, name, description, price_cents, category, subcategory, cj_product_id, cj_variant_id, cj_logistic_name, wholesale_usd, postage_usd, net_margin_eur, delivery_days, images[]. - Valider sans écrire : doublons en base, prix en ,90 ≥ 12,90 €, marge ≥ seuil, 4 puces, pas d'allégation, hôtes d'images.
- Présenter le lot et attendre l'accord, puis insérer, écrire la trace SQL, ajouter à « My Products », vérifier en
ligne (page 200, image via
/_next/image, flux, sitemap). Rendement observé : vague 2 = 23 produits retenus sur 58 candidats ; vague 3 = 28 retenus sur 115 candidats (67 passés en revue visuelle). Arrêter plutôt que de forcer un produit médiocre.
9. Prix et marges
net = P / 1,2 − (0,015 × P + 0,25) − (prix_gros_USD + totalPostageFee_USD) × 0,86P = prix TTC en euros ; toujours totalPostageFee (jamais logisticPrice, qui sous-estime) ; en franchise de TVA
remplacer P / 1,2 par P. Prix en ,90, minimum 12,90 € ; livraison offerte (son coût est dans le prix).
Fonctions de référence : netMargin et priceFor (annexe 18.1).
Ordres de grandeur observés : prix moyen 21,5 €, marge nette moyenne 7,8 € (35-38 %). Baisser un prix de 1 € TTC retire environ 0,8 € de marge.
Gamme d'appel (décision du 2026-10-10) : 10 produits d'entrée à 28 % de marge plancher (au lieu de 35 %) pour
obtenir les premières commandes et les premiers avis : prix moyen 17,70 € → 15,60 €, marge moyenne 6,45 € → 4,73 €
(-27 %), soit +36 % de ventes nécessaires pour gagner autant. Produits d'entrée = articles courants, comparables dans
Google Shopping, hors saison. Ne pas baisser globalement ; mesurer 3 semaines (scripts/bilan-gamme.mjs), puis
garder, étendre ou revenir. Tant qu'il y a peu de visites, le prix n'est pas le problème : trafic et confiance d'abord.
10. Paiement, commande fournisseur, suivi
- Checkout (
/api/checkout) : reçoit{slug, quantity}, relit prix et stock en base, crée la session avec collecte d'adresse (pays livrés) et téléphone obligatoire (exigé par CJ). - Webhook (
/api/webhooks/stripe) : signature vérifiée sur le corps brut ; commande + lignes insérées en une requête ;mode = livemode ? "live" : "test"; erreur → alerte + réponse 500 (Stripe rejoue). - Fulfillment : regrouper par route logistique, numéro de commande stable (
PAT-<id>ou-N),createOrderV3(sandbox si mode test), paiement sur le solde ; solde insuffisant → statut « Paiement CJ en attente » + une alerte. - Cron quotidien : relance des commandes non transmises, paiements en attente, numéros de suivi.
- Admin :
/admin/avis(modération),/admin/commandes(bouton « Payer maintenant ») ; cookiehttpOnly, 8 h, comparaison à temps constant ; fermé tant queADMIN_PASSWORDn'est pas défini et déployé. - Suivi :
/suivi-commande(numéro et e-mail doivent correspondre).
Stripe : test et réel sont deux mondes séparés
Clé, webhook et secret de webhook doivent être du même mode. Un webhook de test ne reçoit rien des paiements réels.
La CLI Stripe travaille dans le bac à sable ; pour agir en réel, lui fournir la clé réelle (variable STRIPE_API_KEY)
et obtenir l'accord explicite avant. Contrôle sans payer : créer une session via /api/checkout et lire le préfixe de
l'URL (cs_test_ ou cs_live_). Test du webhook sans carte : envoyer un événement checkout.session.completed signé
(HMAC-SHA256 de t.payload avec le secret) pour une vraie session ; vérifier signature fausse = 400, rejeu = pas de
doublon ; puis supprimer la commande fictive (sinon le cron la relance).
11. Pages et gabarits
Fiche produit V2 : galerie, titre, prix, accroche, cartes « Ce que vous obtenez », encadré de livraison estimée
(dates calculées, jamais une promesse), bouton d'achat, barre d'achat fixe sur mobile, sections dépliables, avis, produits
associés. Accueil : bannière compacte, deux cartes de catégories animées (RotatingImage), thèmes, nouveautés,
catalogue groupé, guides, garanties. Pages légales : reprendre l'éditeur (entreprise individuelle, SIRET, adresse,
e-mail) depuis src/lib/site.ts ; hébergeur Vercel ; CGV 7 articles ; confidentialité (Stripe, CJ, Vercel, RGPD, 10 ans).
Règles uniques (faq.ts) : livraison offerte FR/BE/CH/LU, 7 à 20 jours ouvrés (moyenne), rétractation 14 jours, retour par
envoi postal, frais à la charge du client sauf défaut, pas d'échange, remboursement sous 14 jours, réponse sous 48 h ouvrées.
Ne jamais inventer une règle (ex. hygiène) qui n'est pas partout identique.
12. SEO, données structurées et flux
12.1 Métadonnées
Un <title> avec mot-clé par page, description de 120 à 160 caractères, URL canonique, Open Graph, un seul <h1>.
12.2 JSON-LD
Accueil : Organization, WebSite · Fiche : Product + Offer avec OfferShippingDetails (0 €, pays livrés) et
MerchantReturnPolicy (14 jours, par envoi postal, ReturnShippingFees) · Avis : AggregateRating seulement s'il existe
de vrais avis publiés · FAQ : FAQPage · Guides : Article · Fil d'Ariane : BreadcrumbList.
12.3 Flux produits (/flux/produits.xml)
RSS 2.0 espace g: (accepté par Google, Meta, Pinterest) : g:id (slug), title, description (accroche + puces
ponctuées), link, g:image_link, g:additional_image_link (≤ 10), g:availability, g:price (12.90 EUR),
g:condition, g:brand, g:identifier_exists = no, g:google_product_category (chemin en texte, ex.
Animals & Pet Supplies > Pet Supplies > Dog Supplies), g:product_type. Cache s-maxage=300 : un changement de prix
n'apparaît qu'après 5 minutes. Livraison et TVA se règlent dans chaque compte plateforme.
12.4 À faire par vous dans chaque plateforme (non automatisable)
- Google Merchant Center : source = le flux (récupération planifiée) ; pays ; livraison (offerte, 1-3 j de traitement + 6-17 j d'acheminement, corriger le fuseau horaire) ; retours (échanges : Non ; neufs et légèrement utilisés ; à la charge du client) ; service client (page contact, cocher le chatbot). Statut « limité » = normal sans publicité.
- Meta : catalogue alimenté par le flux ; URL de paiement
/commande/meta?products=slug:qty,…. - Pinterest (fait sur Patounes) : 1) Paramètres → Lien vers Pinterest → Sites Web → Revendiquer vos contenus ; la balise
p:domain_verifyaffichée est propre au compte Pinterest, pas au domaine : la même sert pour tous vos sites ; l'ajouter dansmetadata.otherdelayout.tsx, déployer, puis valider (méthode « balise HTML »). 2) Catalogues → Ajouter une source de données → Fournissez un lien URL : nom, adresse du flux, format XML, pays France, langue Français, devise EUR (par défaut : CSV, États-Unis, English, USD), ingestion toutes les 24 h, puis Importer et Continuer (validation par e-mail sous 24 h). Le catalogue de Maison Bien-Être peut recevoir plusieurs sources (une par boutique). Pièges : le navigateur automatisé fige souvent (attendre 10 s avant chaque capture), les listes se règlent avecform_input, et un clic hors du panneau déclenche « fermer cette page ? ». - Google Search Console : soumettre
https://<domaine>/sitemap.xml. Un nouveau magasin n'apparaît qu'après plusieurs semaines : zéro clic au début est normal.
12.5 Contenu
3 guides de fond liés aux produits (choix de l'équipement, occuper l'animal, aménager un coin repos), sans allégation de santé. Le contenu met des mois à produire du trafic : le faire tôt.
13. Automatisation
13.1 Routine quotidienne de produits (tâche planifiée Claude Code)
- 3 scripts à noms constants dans
scripts/routine/:cj.mjs(search, detail, freight, image, mine ; renouvelle le jeton si besoin),q.mjs(lecturesselect: products, counts, next, exists),ins.mjs(--drypuis insertion + trace). Chaque forme de commande nouvelle déclenche une demande d'autorisation : n'utiliser que ces formes, avec chemins absolus, et passer les paramètres du jour parscripts/routine/jour.json(écrit avec l'outil de fichiers). - Garde-fous dans
ins.mjs: 3 produits au plus par jour, 1 par sous-catégorie, sous-catégories connues seulement, prix en ,90 ≥ 12,90 €, marge ≥ 35 % avectotalPostageFee, format de fiche, pas d'allégation, hôtes d'images CJ. - Rotation :
q.mjs nextchoisit les 3 sous-catégories les moins fournies, puis celles où l'ajout est le plus ancien. - Interdits explicites : Stripe, commandes, achats, secrets affichés, modification de produits existants, nouvelles
catégories, fichiers du site,
vercel/npm/git push/reset/checkout, navigateur. - Horaire décalé de celles des autres boutiques (limite CJ de 1 appel par seconde partagée) ; 8 h 30 ici.
- Le prompt doit être entièrement autonome (contexte, chemins, règles, format du compte rendu).
13.2 Fonctionnement des tâches planifiées
Elles ne s'exécutent que si l'application est ouverte (sinon au prochain lancement). « Run now » une première fois
pour préapprouver les outils. Une exécution peut être lancée à la demande. Un rappel unique utilise fireAt (ex. bilan
de la gamme d'appel à 3 semaines, en lecture seule, qui recommande sans rien modifier).
14. Claude Code : permissions et sécurité
- Le contrôle automatique refuse : lire un dossier de secrets (
~/.claude/secrets),vercel deploy --prod, toute action en mode réel non autorisée. Ne pas contourner : demander l'accord, ou ajouter une règle dans.claude/settings.local.json(personnel, ignoré par Git), ex.{"permissions":{"allow":["Bash(vercel deploy --prod:*)"]}}(peut nécessiter une nouvelle session pour être lue). - Secrets : fichiers
.env*.localcréés par vous ; Claude les lit via des scripts, ne les affiche jamais, ne les colle pas dans le chat, n'entre pas de clés ou de cartes dans un formulaire d'une page tierce (même une carte de test sur Stripe). - Mode réel (Stripe, base de production, déploiement, DNS) : toujours un « oui » explicite, par action.
- Bash sous Windows :
vercel curl /cheminest déformé par Git Bash (préfixerMSYS_NO_PATHCONV=1) ; éviter les heredocs contenant des apostrophes (utiliser l'outil de création de fichier) ;sleeplong refusé → boucleuntil. - Navigateur intégré : fenêtre étroite = version mobile des sites ; fermer les fenêtres d'accueil ; préférer lire le texte de la page et la ligne de commande aux captures.
15. Pièges et leçons (par ordre d'importance)
- Stripe : clé réelle + webhook de test = paiements encaissés mais commandes perdues. Vérifier le mode avant tout.
totalPostageFee, jamaislogisticPrice: sinon marges fausses.- La clé API CJ n'est pas le jeton ; noter l'expiration ; reporter le jeton renouvelé dans Vercel.
- Solde CJ à 0 = commande créée mais non expédiée : alerte + bouton « Payer maintenant » ; premières ventes retardées.
- Libellé de sous-catégorie à déployer avant les produits.
- Une variable Vercel ne s'applique qu'au déploiement suivant ; copie locale ≠ valeur Vercel.
- Photos CJ : 40 % de rejet ; toujours regarder ; la photo de la variante vendue doit montrer le produit vendu.
- Produits à éviter : électronique/piles, médical/vétérinaire, marques et parodies de marques, produits à texte personnalisé, doublons de modèles, articles lourds et fragiles.
- Page pré-générée sans base = « catalogue indisponible » figé ;
sitemapdoit être dynamique. source .envcasse les URL Neon (&) ; CRLF casse les remplacements ; shell et apostrophes.- Sous-domaine ≠ nouveau domaine ; DNS en « DNS uniquement » ; émettre le certificat si besoin.
- Commande fictive de test : toujours la supprimer (le cron la relance sinon).
- Baisser les prix n'attire pas de trafic ; mesurer avant ; gamme d'appel limitée et réversible.
- Les valeurs par défaut de Merchant Center sont fausses pour vous (fuseau horaire, échanges, état).
- Deux routines partagent la limite CJ : décaler les horaires.
- Une règle inventée (hygiène, etc.) crée une incohérence avec Merchant Center et la FAQ : ne jamais en ajouter.
- Un changement invisible (SEO, flux) ne se voit pas : le grouper avec un changement visible.
16. Checklist de lancement
Phase 0 — Cadrage : niche, 2 catégories, 6 sous-catégories, nom, sous-domaine, e-mail, pays, délai ; vérifier 60+ produits CJ éligibles.
Phase 1 — Fondations : projet Next ; Vercel lié ; Neon créé et schéma rejoué ; DNS ; certificat ; secrets locaux ; variables Vercel.
Phase 2 — Catalogue : libellés de taxonomie ; vague 1 (3 à 5 produits, pour valider le circuit) puis vagues de 25 ; traces SQL.
Phase 3 — Tunnel en TEST : clé de test, webhook de test, commande sandbox CJ, événement signé, suppression de la commande fictive.
Phase 4 — Confiance et légal : pages d'information, éditeur, FAQ unique, CGV, confidentialité, avis, admin (ADMIN_PASSWORD).
Phase 5 — SEO : métadonnées, JSON-LD, sitemap dynamique, flux, 3 guides.
Phase 6 — Passage en réel (accord explicite) : clé réelle et webhook réel (secret en production) dans le même déploiement ;
solde CJ ; un vrai petit achat remboursé pour valider le circuit.
Phase 7 — Visibilité : Merchant Center, Meta, Pinterest, Search Console.
Phase 8 — Pilotage : routine quotidienne, gamme d'appel, bilan à 3 semaines.
- Clé Stripe et webhook du même mode · [ ]
ADMIN_PASSWORD,CRON_SECRETdéfinis et déployés · [ ] solde CJ vérifié - pages légales relues · [ ] commande réelle de test réussie · [ ] sitemap soumis · [ ] flux importé · [ ] routine « Run now »
17. Consignes prêtes à copier pour Claude
Lancement d'une boutique
Crée une boutique de dropshipping sur la niche : {{THEME}}, en suivant GUIDE-CONSTRUCTION-BOUTIQUE.md. Nom : {{NOM}},
domaine : {{DOMAINE}}, pays : {{PAYS}}. Reprends les fichiers génériques de la boutique Patounes (section 5.2). Aucune action
en mode réel ni écriture en base de production sans mon « oui » explicite ; n'affiche jamais un secret ; demande-moi seulement
ce que toi seul ne peux pas faire (comptes, clés Stripe, solde CJ, DNS).Vague de produits
Prépare environ {{N}} produits : {{X}} pour {{CATEGORIE_A}} et {{Y}} pour {{CATEGORIE_B}}. Méthode 8.3 : 40 à 50 mots-clés en
anglais, détail et livraison (totalPostageFee, ≤ 15 j), planches de photos que tu regardes toutes, fiches au format 7.2,
validation sans écriture, puis présente le lot. Insère seulement après mon accord (trace SQL, My Products, vérification en ligne).Gamme d'appel : « Propose 10 produits d'entrée à 28 % de marge, montre avant/après, applique après accord, ajoute un rappel de bilan à 3 semaines. » Routine : « Crée la routine quotidienne sur le modèle de patounes-routine-quotidienne (scripts à noms constants, garde-fous, rotation). »
18. Annexes
18.1 Fonctions de prix
export function netMargin(price: number, wholesaleUsd: number, postageUsd: number): number {
return price / 1.2 - (0.015 * price + 0.25) - (wholesaleUsd + postageUsd) * 0.86;
}
export function priceFor(wholesaleUsd: number, postageUsd: number, minMargin = 0.35): number {
let p = 12.9;
while (netMargin(p, wholesaleUsd, postageUsd) < minMargin * p) p = Math.round((p + 0.5) * 100) / 100;
const cand = Math.ceil(p) - 0.1;
return cand >= p ? cand : cand + 1;
}18.2 Aide-mémoire de commandes
vercel deploy --prod --yes | vercel env ls production | vercel domains inspect <d> | vercel certs issue <d>
stripe webhook_endpoints list --limit 20 # bac à sable par défaut
STRIPE_API_KEY=<clé réelle> stripe webhook_endpoints create --url <url> -d "enabled_events[]=checkout.session.completed"
npx neon@latest projects list --org-id <org>
node scripts/routine/q.mjs next | counts | products node scripts/routine/ins.mjs --dry
node scripts/bilan-gamme.mjs # lecture seule
npx tsc --noEmit && npx eslint && npm run build # avant tout déploiement18.3 Glossaire
Variante (vid) déclinaison précise d'un produit · totalPostageFee frais de livraison réellement facturés par CJ ·
Sandbox commande fictive sans argent · Webhook appel automatique de Stripe vers le site · Idempotent rejouable
sans effet double · IOSS régime de TVA à l'import des petits colis · Gamme d'appel produits d'entrée à marge réduite.
19. Adapter à une nouvelle niche : où changer quoi
| Fichier | À adapter |
|---|---|
src/lib/site.ts | nom, sous-titre, thème, URL, e-mail, pays, délais, éditeur |
src/lib/products.ts | CATEGORY_LABELS, CATEGORY_ORDER, SUBCATEGORY_LABELS, URL par défaut |
src/lib/chat/catalog.ts | dictionnaire SYNONYMS (vocabulaire de la niche) ; suggestions dans engine.ts et ChatWidget.tsx |
src/lib/guides.ts | 3 guides (slugs, textes, productSlugs) |
src/components/CategoryCards.tsx, src/app/page.tsx | textes d'accueil, titre, description, JSON-LD |
src/app/layout.tsx | titre, description, retirer toute balise de vérification d'un autre domaine |
src/app/flux/produits.xml/route.ts | marque, catégorie Google (texte) par catégorie |
src/components/SiteLogo.tsx, icon.svg, favicon.ico, apple-icon.png | logo et icônes |
src/lib/cart-context.tsx | clé localStorage (<nom>.cart) |
scripts/routine/*.mjs | arbre TREE, liste des sous-catégories de q.mjs next, plafonds de prix |
scripts/gamme-appel.json, bilan-gamme.mjs | produits de la gamme d'appel de la nouvelle boutique |
| Tâche planifiée | prompt : nom, domaine, chemins, sous-catégories, critères d'éligibilité propres à la niche |
Critères d'éligibilité à réécrire pour la niche : exclusions (réglementées, électroniques, de marque), articles saisonniers et leurs dates, plafonds de prix par sous-catégorie, vocabulaire des mots-clés anglais.
20. Reste à faire sur Patounes (au 2026-10-10)
Premier achat réel de validation (puis remboursement) · alimenter le solde CJ · Merchant Center, Meta, Pinterest,
Search Console · balise Pinterest du domaine · ALERT_WEBHOOK_URL (facultatif) · bilan de la gamme d'appel le 2026-10-31 ·
jeton CJ à renouveler avant le 2027-04-06 · relire les fiches les plus chères ajoutées par la routine.