Publication IA: - 4 templates (magazine, brief, essay, simple) avec CSS riche - Rewrite IA (article/exercises/tutorial/reference/mixed) - Modération avec timeout 12s + fallback safe - Quotas publish_enhance par tier (basic=2, pro=15, business=100) - Détection contenu stale (hash) - Migration DB publishedContent/publishedTemplate/publishedSourceHash Fixes: - cheerio v1.2: Element -> AnyNode (domhandler), decodeEntities cast - _isShared ajouté au type Note (champ virtuel serveur) - callout colors PDF export: extraction fonction pure testable - admin/published: guard note.userId null - Cmd+S fonctionne en mode dialog (pas seulement fullPage) i18n: - 23 clés publish* traduites dans les 15 locales - Extension Web Clipper: 13 locales mise à jour Tests: - callout-colors.test.ts (6 tests) - note-visible-in-view.test.ts (5 tests) - entitlements.test.ts + byok-entitlements.test.ts: mock usageLog + unstubAllEnvs - 199/199 tests passent Tracker: user-stories.md sync avec sprint-status.yaml
493 lines
22 KiB
Markdown
493 lines
22 KiB
Markdown
# Memento — Guide Stripe : Configuration, Architecture et Utilisation
|
|
|
|
## Vue d'ensemble
|
|
|
|
Memento utilise **Stripe** pour la gestion des abonnements payants (Pro, Business, Enterprise). Le système repose sur :
|
|
|
|
- **Stripe Embedded Checkout** (modal dans l'app, sans redirection)
|
|
- **Webhooks** pour synchroniser l'état des abonnements en temps réel
|
|
- **Customer Portal** pour que les utilisateurs gèrent leur carte/facturation
|
|
- Un **feature flag** pour activer/désactiver le billing sans déploiement
|
|
|
|
---
|
|
|
|
## 1. Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Frontend (React) │
|
|
│ │
|
|
│ /settings/billing │
|
|
│ └─ billing-plans.tsx │
|
|
│ ├─ Cartes Free / Pro / Business / Enterprise │
|
|
│ ├─ Toggle mensuel/annuel │
|
|
│ ├─ Embedded Checkout (modal Stripe) │
|
|
│ └─ Lien vers Customer Portal │
|
|
│ │
|
|
│ /settings → SettingsNav → onglet "Facturation" │
|
|
│ Sidebar → UsageMeter → lien vers /settings/billing │
|
|
└───────────────────────┬─────────────────────────────────┘
|
|
│
|
|
POST /api/billing/create-checkout
|
|
POST /api/billing/portal
|
|
GET /api/billing/status
|
|
│
|
|
┌───────────────────────▼─────────────────────────────────┐
|
|
│ Backend (Next.js API) │
|
|
│ │
|
|
│ lib/stripe.ts → Client Stripe singleton │
|
|
│ lib/billing/ → Logique métier billing │
|
|
│ ├─ stripe-prices.ts → Mapping priceId ↔ tier │
|
|
│ └─ sync-subscription-from-stripe.ts │
|
|
│ → Upsert Prisma Subscription depuis webhook │
|
|
│ │
|
|
│ POST /api/billing/webhook → Reception événements │
|
|
│ Stripe (raw body + sig) │
|
|
└───────────────────────┬─────────────────────────────────┘
|
|
│
|
|
┌────────────▼────────────┐
|
|
│ PostgreSQL (Prisma) │
|
|
│ │
|
|
│ Subscription { │
|
|
│ userId │
|
|
│ tier (BASIC/PRO/ │
|
|
│ BUSINESS/ENTERP.) │
|
|
│ status (ACTIVE/ │
|
|
│ CANCELED/...) │
|
|
│ stripeCustomerId │
|
|
│ stripeSubscriptionId │
|
|
│ stripePriceId │
|
|
│ currentPeriodStart │
|
|
│ currentPeriodEnd │
|
|
│ cancelAtPeriodEnd │
|
|
│ } │
|
|
└────────────┬────────────┘
|
|
│
|
|
┌────────────▼────────────┐
|
|
│ Redis │
|
|
│ │
|
|
│ usage:{userId}: │
|
|
│ {feature}:{period} │
|
|
│ → Compteurs mensuels │
|
|
└─────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Configuration pas à pas
|
|
|
|
### 2.1 Créer un compte Stripe
|
|
|
|
1. Aller sur https://dashboard.stripe.com/register
|
|
2. Créer un compte (utiliser l'email `sales@memento-note.com`)
|
|
3. Activer le **mode test** (toggle en haut à droite)
|
|
|
|
### 2.2 Créer les produits et prix
|
|
|
|
Dans le **Stripe Dashboard** → **Produits** :
|
|
|
|
#### Produit 1 : Memento Pro
|
|
|
|
| Champ | Valeur |
|
|
|-------|--------|
|
|
| Nom | Memento Pro |
|
|
| Description | Pour les consultants et créateurs exigeants |
|
|
|
|
Créer **2 prix** :
|
|
|
|
| Prix | Montant | Récurrent |
|
|
|------|---------|-----------|
|
|
| Pro Mensuel | 9,90 EUR | Tous les mois |
|
|
| Pro Annuel | 99 EUR | Tous les ans |
|
|
|
|
#### Produit 2 : Memento Business
|
|
|
|
| Champ | Valeur |
|
|
|-------|--------|
|
|
| Nom | Memento Business |
|
|
| Description | Pour les équipes et chefs de produit |
|
|
|
|
Créer **2 prix** :
|
|
|
|
| Prix | Montant | Récurrent |
|
|
|------|---------|-----------|
|
|
| Business Mensuel | 29,90 EUR | Tous les mois |
|
|
| Business Annuel | 299 EUR | Tous les ans |
|
|
|
|
> **Enterprise** n'a pas de prix Stripe — c'est un contact manuel (`sales@memento-note.com`).
|
|
|
|
### 2.3 Récupérer les clés et price IDs
|
|
|
|
Dans **Stripe Dashboard** → **Développeurs** → **Clés API** :
|
|
|
|
| Variable | Où la trouver |
|
|
|----------|---------------|
|
|
| `STRIPE_SECRET_KEY` | Clés API → Clé secrète (sk_test_...) |
|
|
| `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` | Clés API → Clé publiable (pk_test_...) |
|
|
|
|
Dans **Stripe Dashboard** → **Produits** → cliquer sur chaque prix :
|
|
|
|
| Variable | Source |
|
|
|----------|--------|
|
|
| `STRIPE_PRICE_PRO_MONTHLY` | Produit Pro → Prix mensuel → `price_1xxx...` |
|
|
| `STRIPE_PRICE_PRO_ANNUAL` | Produit Pro → Prix annuel → `price_1yyy...` |
|
|
| `STRIPE_PRICE_BUSINESS_MONTHLY` | Produit Business → Prix mensuel → `price_1zzz...` |
|
|
| `STRIPE_PRICE_BUSINESS_ANNUAL` | Produit Business → Prix annuel → `price_1www...` |
|
|
|
|
### 2.4 Configurer le webhook
|
|
|
|
Dans **Stripe Dashboard** → **Développeurs** → **Webhooks** :
|
|
|
|
1. Cliquer **Ajouter un endpoint**
|
|
2. URL : `https://memento-note.com/api/billing/webhook`
|
|
3. Événements à écouter :
|
|
- `checkout.session.completed`
|
|
- `customer.subscription.created`
|
|
- `customer.subscription.updated`
|
|
- `customer.subscription.deleted`
|
|
- `invoice.payment_failed`
|
|
4. Copier la **signature secrète** → `STRIPE_WEBHOOK_SECRET` (commence par `whsec_...`)
|
|
|
|
### 2.5 Configurer le Customer Portal
|
|
|
|
Dans **Stripe Dashboard** → **Paramètres** → **Customer Portal** :
|
|
|
|
1. Activer le portal
|
|
2. Configurer les fonctions autorisées :
|
|
- Mettre à jour le moyen de paiement
|
|
- Voir les factures
|
|
- Annuler l'abonnement
|
|
- Changer de plan (optionnel)
|
|
3. URL de retour : `https://memento-note.com/settings/billing`
|
|
|
|
### 2.6 Remplir le fichier `.env`
|
|
|
|
Ajouter dans `memento-note/.env` :
|
|
|
|
```env
|
|
# Stripe — Server-side (NE JAMAIS exposer côté client)
|
|
STRIPE_SECRET_KEY="sk_test_VOTRE_CLE_SECRETE"
|
|
STRIPE_WEBHOOK_SECRET="whsec_VOTRE_SIGNATURE_WEBHOOK"
|
|
|
|
# Stripe — Price IDs
|
|
STRIPE_PRICE_PRO_MONTHLY="price_ID_PRO_MENSUEL"
|
|
STRIPE_PRICE_PRO_ANNUAL="price_ID_PRO_ANNUEL"
|
|
STRIPE_PRICE_BUSINESS_MONTHLY="price_ID_BUSINESS_MENSUEL"
|
|
STRIPE_PRICE_BUSINESS_ANNUAL="price_ID_BUSINESS_ANNUEL"
|
|
|
|
# Stripe — Client-side (sûr à exposer)
|
|
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_test_VOTRE_CLE_PUBLIABLE"
|
|
|
|
# Activer l'interface de facturation
|
|
NEXT_PUBLIC_FEATURE_BILLING_ENABLED="true"
|
|
```
|
|
|
|
> **Important** : Relancer le serveur après modification du `.env`.
|
|
|
|
### 2.7 Résumé des variables
|
|
|
|
| Variable | Où | Obligatoire |
|
|
|----------|----|----|
|
|
| `STRIPE_SECRET_KEY` | `.env` (server) | Oui |
|
|
| `STRIPE_WEBHOOK_SECRET` | `.env` (server) | Oui |
|
|
| `STRIPE_PRICE_PRO_MONTHLY` | `.env` (server) | Oui |
|
|
| `STRIPE_PRICE_PRO_ANNUAL` | `.env` (server) | Oui |
|
|
| `STRIPE_PRICE_BUSINESS_MONTHLY` | `.env` (server) | Oui |
|
|
| `STRIPE_PRICE_BUSINESS_ANNUAL` | `.env` (server) | Oui |
|
|
| `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` | `.env` (client+server) | Oui |
|
|
| `NEXT_PUBLIC_FEATURE_BILLING_ENABLED` | `.env` (client+server) | Oui |
|
|
|
|
---
|
|
|
|
## 3. Flux utilisateur
|
|
|
|
### 3.1 Checkout (achat d'un plan)
|
|
|
|
```
|
|
Utilisateur Frontend Backend Stripe
|
|
│ │ │ │
|
|
│ Clique "Passer Pro" │ │ │
|
|
│───────────────────────────>│ │ │
|
|
│ │ POST /api/billing/ │ │
|
|
│ │ create-checkout │ │
|
|
│ │ {tier: "PRO", │ │
|
|
│ │ interval: "month"} │ │
|
|
│ │─────────────────────────>│ │
|
|
│ │ │ Crée/respire │
|
|
│ │ │ Customer + Session │
|
|
│ │ │───────────────────────>│
|
|
│ │ │ │
|
|
│ │ │ {clientSecret} │
|
|
│ │ │<───────────────────────│
|
|
│ │ │ │
|
|
│ │ Modal Embedded │ │
|
|
│ │ Checkout Stripe │ │
|
|
│ │<─────────────────────────│ │
|
|
│ │ │ │
|
|
│ Remplit carte 4242... │ │ │
|
|
│───────────────────────────>│ │ │
|
|
│ │ Paiement Stripe │ │
|
|
│ │─────────────────────────────────────────────────>│
|
|
│ │ │ │
|
|
│ │ │ Webhook: │
|
|
│ │ │ checkout.session. │
|
|
│ │ │ completed │
|
|
│ │ │<───────────────────────│
|
|
│ │ │ │
|
|
│ │ │ Upsert Subscription │
|
|
│ │ │ tier=PRO status=ACTIVE│
|
|
│ │ │ │
|
|
│ Toast "Bienvenue Pro !" │ │ │
|
|
│ UsageMeter rafraîchi │ │ │
|
|
│<───────────────────────────│ │ │
|
|
```
|
|
|
|
### 3.2 Webhook — Cycle de vie des abonnements
|
|
|
|
| Événement Stripe | Action Memento | Statut Prisma |
|
|
|------------------|---------------|---------------|
|
|
| `checkout.session.completed` | Upsert subscription avec tier/periode | `ACTIVE` |
|
|
| `customer.subscription.created` | Upsert (nouvelle souscription) | Selon Stripe |
|
|
| `customer.subscription.updated` | Upsert (changement de plan, etc.) | Selon Stripe |
|
|
| `customer.subscription.deleted` | Marquer annulé | `CANCELED` |
|
|
| `invoice.payment_failed` | Sync subscription (passage en `PAST_DUE`) | `PAST_DUE` |
|
|
|
|
### 3.3 Mapping statuts Stripe → Prisma
|
|
|
|
| Stripe | Prisma | Comportement `getEffectiveTier()` |
|
|
|--------|--------|----------------------------------|
|
|
| `active` | `ACTIVE` | Retourne le tier payé (PRO/BUSINESS) |
|
|
| `trialing` | `TRIALING` | Retourne le tier (accès complet pendant l'essai) |
|
|
| `past_due` | `PAST_DUE` | Garde le tier jusqu'à `currentPeriodEnd` |
|
|
| `canceled` / `unpaid` | `CANCELED` | Garde le tier jusqu'à `currentPeriodEnd`, puis BASIC |
|
|
| `incomplete_expired` | `INACTIVE` | Retourne BASIC |
|
|
|
|
---
|
|
|
|
## 4. Pages et composants
|
|
|
|
### 4.1 Accès utilisateur
|
|
|
|
| URL | Description |
|
|
|-----|-------------|
|
|
| `/settings/billing` | Page principale : plans, usage, facturation |
|
|
| `/settings` → onglet "Facturation" | Navigation via SettingsNav |
|
|
| UsageMeter (sidebar) → "Upgrade" | Lien direct vers `/settings/billing` |
|
|
|
|
### 4.2 Composants clés
|
|
|
|
| Fichier | Rôle |
|
|
|---------|------|
|
|
| `components/settings/billing-plans.tsx` | Cartes de plans, checkout modal, usage grid, portal |
|
|
| `components/settings/SettingsNav.tsx` | Onglet "Facturation" avec icône CreditCard |
|
|
| `components/settings/billing-history.tsx` | Lien vers le portal Stripe pour factures |
|
|
| `components/usage-meter.tsx` | Meter sidebar → lien vers billing quand quota dépassé |
|
|
|
|
### 4.3 API Routes
|
|
|
|
| Route | Méthode | Auth | Description |
|
|
|-------|---------|------|-------------|
|
|
| `/api/billing/create-checkout` | POST | Session | Crée une session checkout embedded |
|
|
| `/api/billing/portal` | POST | Session | Ouvre le portal client Stripe |
|
|
| `/api/billing/status` | GET | Session | Retourne tier, status, periodEnd |
|
|
| `/api/billing/webhook` | POST | Signature Stripe | Reçoit les événements lifecycle |
|
|
|
|
### 4.4 Librairies backend
|
|
|
|
| Fichier | Rôle |
|
|
|---------|------|
|
|
| `lib/stripe.ts` | Client Stripe singleton (`getStripe()`) |
|
|
| `lib/billing/stripe-prices.ts` | `resolvePriceId()` et `priceIdToTier()` |
|
|
| `lib/billing/sync-subscription-from-stripe.ts` | Upsert Prisma depuis webhook Stripe |
|
|
| `lib/entitlements.ts` | `getEffectiveTier()`, `TIER_LIMITS`, `getUserQuotas()` |
|
|
|
|
---
|
|
|
|
## 5. Quotas par tier
|
|
|
|
| Feature | BASIC | PRO | BUSINESS | ENTERPRISE |
|
|
|---------|-------|-----|----------|------------|
|
|
| Recherche sémantique | 30 | 100 | 1000 | ∞ |
|
|
| Tags automatiques | 20 | 200 | 1000 | ∞ |
|
|
| Titres automatiques | 10 | 200 | 1000 | ∞ |
|
|
| Reformulation | — | 50 | 500 | ∞ |
|
|
| Chat IA | — | 100 | 1000 | ∞ |
|
|
| Brainstorm (création) | 1 | 30 | 200 | ∞ |
|
|
| Brainstorm (expansion) | 10 | 100 | 500 | ∞ |
|
|
| Brainstorm (enrichissement) | 20 | 200 | 1000 | ∞ |
|
|
|
|
> Les compteurs sont stockés dans Redis avec un TTL de 90 jours. Le tier détermine les limites, pas les compteurs.
|
|
|
|
---
|
|
|
|
## 6. Tests
|
|
|
|
### Tests unitaires (22 tests, 100% passent)
|
|
|
|
| Fichier | Tests | Description |
|
|
|---------|-------|-------------|
|
|
| `tests/unit/billing-price-map.test.ts` | 10 | Mapping priceId → tier, erreurs si env manquant |
|
|
| `tests/unit/billing-sync.test.ts` | 12 | Upsert Prisma, mapping statuts Stripe→Prisma, métadonnées |
|
|
|
|
### Lancer les tests
|
|
|
|
```bash
|
|
cd memento-note
|
|
npx vitest run tests/unit/billing-price-map.test.ts tests/unit/billing-sync.test.ts
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Test local avec Stripe CLI
|
|
|
|
### 7.1 Installer Stripe CLI
|
|
|
|
```bash
|
|
# macOS
|
|
brew install stripe/stripe-cli/stripe
|
|
|
|
# Linux
|
|
curl -s https://packages.stripe.dev/api/security/keypair/stripe-cli-gpg/public/download.gpg | sudo tee /usr/share/keyrings/stripe.gpg
|
|
echo "deb [signed-by=/usr/share/keyrings/stripe.gpg] https://packages.stripe.dev/stripe-cli-debian-local stable main" | sudo tee -a /etc/apt/sources.list.d/stripe.list
|
|
sudo apt update && sudo apt install stripe
|
|
```
|
|
|
|
### 7.2 Forward des webhooks en local
|
|
|
|
```bash
|
|
stripe listen --forward-to localhost:3000/api/billing/webhook
|
|
```
|
|
|
|
Cette commande affiche la signature webhook (`whsec_...`) à mettre dans `STRIPE_WEBHOOK_SECRET`.
|
|
|
|
### 7.3 Tester un paiement
|
|
|
|
1. Lancer le serveur : `npm run dev`
|
|
2. Aller sur `/settings/billing`
|
|
3. Cliquer "Passer au Plan Pro"
|
|
4. Utiliser la carte test : **4242 4242 4242 4242**
|
|
5. Date d'expiration : n'importe quelle date future
|
|
6. CVC : n'importe quels 3 chiffres
|
|
7. Le webhook se déclenche → `Subscription` upserté dans la DB
|
|
|
|
### 7.4 Vérifier en base
|
|
|
|
```sql
|
|
SELECT tier, status, "currentPeriodStart", "currentPeriodEnd"
|
|
FROM "Subscription"
|
|
WHERE "userId" = 'VOTRE_USER_ID';
|
|
```
|
|
|
|
### 7.5 Vérifier via l'API
|
|
|
|
```bash
|
|
curl http://localhost:3000/api/billing/status -H "Cookie: next-auth.session-token=VOTRE_TOKEN"
|
|
```
|
|
|
|
Devrait retourner :
|
|
```json
|
|
{
|
|
"tier": "PRO",
|
|
"effectiveTier": "PRO",
|
|
"status": "ACTIVE",
|
|
"currentPeriodEnd": "2026-06-16T...",
|
|
"cancelAtPeriodEnd": false,
|
|
"hasStripeSubscription": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Passage en production
|
|
|
|
### 8.1 Checklist
|
|
|
|
- [ ] Compte Stripe vérifié (KYC complété)
|
|
- [ ] Produits et prix créés en **mode live**
|
|
- [ ] Webhook configuré en mode live avec l'URL de production
|
|
- [ ] Variables `.env` mises à jour avec les clés live (`sk_live_...`, `pk_live_...`)
|
|
- [ ] `NEXT_PUBLIC_FEATURE_BILLING_ENABLED="true"`
|
|
- [ ] Customer Portal configuré pour le mode live
|
|
- [ ] Tester un paiement réel avec une vraie carte
|
|
|
|
### 8.2 Sécurité
|
|
|
|
- **Jamais** de `STRIPE_SECRET_KEY` ou `STRIPE_WEBHOOK_SECRET` côté client
|
|
- Les price IDs sont côté serveur uniquement
|
|
- Le webhook vérifie la signature Stripe-Signature sur chaque requête
|
|
- L'upsert par `stripeSubscriptionId` garantit l'idempotence
|
|
|
|
---
|
|
|
|
## 9. Dépannage
|
|
|
|
### Les cartes de plans ne s'affichent pas
|
|
→ Vérifier `NEXT_PUBLIC_FEATURE_BILLING_ENABLED="true"` dans `.env` et relancer le serveur.
|
|
|
|
### Le checkout ne s'ouvre pas
|
|
→ Vérifier `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` est défini. Regarder la console navigateur.
|
|
|
|
### Le webhook ne se déclenche pas
|
|
→ En local : utiliser `stripe listen --forward-to localhost:3000/api/billing/webhook`
|
|
→ En production : vérifier l'URL du webhook dans le Stripe Dashboard.
|
|
|
|
### L'abonnement reste BASIC après paiement
|
|
→ Vérifier les logs du webhook (`[billing/webhook]`). Le `userId` doit être dans les metadata de la session.
|
|
|
|
### `getStripe()` throw "STRIPE_SECRET_KEY is required"
|
|
→ Ajouter `STRIPE_SECRET_KEY` dans `.env`.
|
|
|
|
---
|
|
|
|
## 10. Tarification
|
|
|
|
| Tier | Mensuel | Annuel | Économie annuelle |
|
|
|------|---------|--------|-------------------|
|
|
| Gratuit | 0 € | — | — |
|
|
| Pro | 9,90 € | 99 € | ~17% |
|
|
| Business | 29,90 € | 299 € | ~17% |
|
|
| Enterprise | Sur devis | Sur devis | — |
|
|
|
|
Devise : EUR (configurable dans Stripe Dashboard pour multi-devises).
|
|
|
|
---
|
|
|
|
## 11. Bons de réduction & Codes de promotion (Coupons & Promo Codes)
|
|
|
|
Memento intègre le support natif et sécurisé de Stripe pour les codes promotionnels lors du paiement en Embedded Checkout via l'attribut `allow_promotion_codes: true` dans `/api/billing/create-checkout/route.ts`.
|
|
|
|
### 11.1 Concepts Clés : Bon de réduction (Coupon) vs Code de promotion (Promo Code)
|
|
Dans Stripe, la gestion des remises se fait en deux niveaux :
|
|
1. **Le Bon de réduction (Coupon)** : C'est la règle financière sous-jacente (ex. `-20 % sur l'abonnement pendant 6 mois` ou `-10 € à vie`). Un coupon n'est pas vu par le client final sous cette forme.
|
|
2. **Le Code de promotion (Promo Code)** : C'est la chaîne de caractères réelle saisie par le client (ex. `WELCOME20`, `LAUNCH50`). Un code promo est obligatoirement rattaché à un Coupon. Vous pouvez créer plusieurs codes promos pour un seul et même coupon (ex. `INFLUENCEUR1` et `INFLUENCEUR2` qui appliquent tous les deux la même réduction de -10%).
|
|
|
|
### 11.2 Comment créer un Code Promo sur Stripe (Dashboard)
|
|
1. Connectez-vous à votre **Stripe Dashboard** (en mode test ou live selon votre cible).
|
|
2. Rendez-vous dans **Produits** (Products) → **Bons de réduction** (Coupons) → bouton **+ Nouveau**.
|
|
3. Remplissez les informations du Coupon :
|
|
- **Nom** : Le nom interne pour vous y retrouver (ex: `Lancement 50%`).
|
|
- **Type de réduction** : Pourcentage (ex: `50%`) ou Montant fixe (ex: `10 €`).
|
|
- **Durée** :
|
|
- *Une seule fois* (appliqué uniquement sur la première facture).
|
|
- *Plusieurs mois* (Spécifier le nombre de mois, ex: 3 mois).
|
|
- *Pour toujours* (appliqué à vie sur toutes les factures de l'abonnement).
|
|
4. Sous le bloc **Codes de promotion**, cochez **"Créer un code de promotion orienté client"** :
|
|
- **Code** : Saisissez le code en majuscules (ex: `LAUNCH50`).
|
|
- **Limites d'utilisation** (optionnel) :
|
|
- Nombre d'utilisations max (ex: limité aux 100 premiers utilisateurs).
|
|
- Date limite de validité (ex: valable uniquement jusqu'au 31 décembre).
|
|
- Limiter aux clients n'ayant jamais payé.
|
|
- Restriction à des plans spécifiques (ex: restreindre ce code promo uniquement au produit `Memento Pro`).
|
|
5. Cliquez sur **Créer le bon de réduction**.
|
|
|
|
### 11.3 Comment désactiver ou supprimer un Code Promo
|
|
1. Allez dans **Produits** → **Bons de réduction** → **Codes de promotion**.
|
|
2. Cliquez sur les `...` à côté du code promo concerné.
|
|
3. Sélectionnez **Désactiver** (Deactivate) : le code ne sera plus utilisable par aucun client, mais les clients en ayant déjà bénéficié conserveront leur réduction active selon la durée définie (ex. s'ils ont déjà eu les 3 mois, Stripe continue de l'appliquer jusqu'à la fin de la période).
|
|
4. Si vous souhaitez supprimer définitivement un coupon global et annuler la réduction pour tout le monde (y compris les abonnés actuels), allez dans **Bons de Réduction**, cliquez sur le coupon puis sur **Supprimer**.
|
|
|
|
### 11.4 Mode Test vs Production
|
|
* **En local / Test** : Créez vos codes de promotion dans Stripe en ayant activé le commutateur **Mode Test** (Test Mode). Les codes créés ici ne fonctionneront qu'avec vos clés d'API de test (`sk_test_...`).
|
|
* **En production / Live** : Désactivez le Mode Test sur Stripe pour passer en mode réel, et créez les coupons dans la section Live. Ils ne fonctionneront qu'avec vos clés d'API réelles (`sk_live_...`).
|
|
|