Files
dictia-public/config/env.stripe.example
Allison 1c4cafaf69 refactor(pricing): refonte v7.0 — 3 Cloud (Basic 189$/Essentiel 349$/Pro 549$) + DictIA Local (5998$ An1) + Pro+ soumission
Remplace l'ancien pricing (DictIA 8 / 16 / Cloud) par la nouvelle structure
canonique v7.0 : 4 forfaits + 1 sentinel quote-only.

Changements clés :
- pricing_card.html : signature étendue (badge, recommended, capacity_audio,
  capacity_storage, gpu, yearly_renewal, cta_label) + format prix server-side
  avec NBSP OQLF (5998 -> 5 998 $)
- _pricing_tiers.html : 4 cards (Cloud Basic 189$, Cloud Essentiel 349$,
  Cloud Pro 549$+485$ RECOMMANDÉ, DictIA Local 5998$ An1) + chip Pro+
  soumission -> /contact?pro-plus=1
- plans.py : refonte complète avec yearly_renewal_env (DictIA Local An 2+ =
  500$/an) + is_quote_only sentinel (Pro+ -> redirect /contact, jamais Stripe)
- routes.py : Pro+ intercepté avant le flow Stripe Checkout
- env.stripe.example : nouveau naming STRIPE_CLOUD_BASIC|ESSENTIEL|PRO_*
  + STRIPE_DICTIA_LOCAL_SETUP/RENEWAL_YEARLY
- tarifs.html : header "Quatre forfaits", matrice comparative 4 colonnes,
  FAQ enrichie (7 questions incluant DictIA Local + onboarding Pro + Pro+)
- fonctionnalites.html : section Architecture refondue (4 cards v7.0)
- landing.html : ROI footnote + cycle "189$" + wave "189$/mois" actualisés
- roi_calculator.js : recalibrage sur Cloud ESSENTIEL 349$ × 12 = 4188$/an
- routes.py marketing : FAQ "DictIA 8 et 16" -> "DictIA LOCAL"
- contact.html : "déploiements DictIA 16" -> "Cloud PRO" + "DictIA LOCAL"

Tests :
- test_marketing_landing_template.py : assertions prix v7.0 (189/349/549/5998),
  4 slugs (cloud-basic, cloud-essentiel, cloud-pro, dictia-local), Pro+ chip,
  capacity chips, RECOMMANDÉ sur Cloud PRO
- test_marketing_secondary_pages.py : 4 cards + Pro+ chip + matrice 4 col +
  FAQ 7 questions
- test_stripe_checkout.py : env vars v7.0, slugs cloud-basic/cloud-pro/
  dictia-local + nouveau test pro-plus -> /contact + tests setup pour Cloud PRO
  et DictIA Local
- test_stripe_webhook.py : plan_slug metadata cloud-basic

Status : 28/28 Stripe checkout + 17/17 webhook + 93/98 marketing pass
(les 5 marketing failures sont pré-existantes, non liées au pricing :
test_landing_has_main_nav et test_footer_links_complete = /blog manquant ;
test_trust_bar_has_eyebrow_factual_phrasing + 2 tests conformite =
casing eyebrow + entité é — vérifié par git stash baseline).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 21:06:12 -04:00

88 lines
4.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
###############################################################################
# Stripe — Checkout + Subscriptions (B-2.7 / B-2.8) — v7.0 pricing
###############################################################################
#
# Required for the /checkout/<plan> flow and the /webhooks/stripe receiver.
# The application will boot without these — billing routes will redirect to
# /tarifs with a "contact info@dictia.ca" message until the keys are set.
#
# Get these from https://dashboard.stripe.com (CAD account)
# - Use sk_test_/pk_test_/whsec_test_ keys against the Stripe test mode for
# pre-prod. Switch to live keys ONLY after end-to-end CAD/TVQ rehearsal.
# STRIPE_SECRET_KEY=sk_test_... # or sk_live_...
# STRIPE_PUBLISHABLE_KEY=pk_test_... # used client-side; not strictly needed for hosted Checkout
# STRIPE_WEBHOOK_SECRET=whsec_... # for B-2.8 webhook signature verification
###############################################################################
# Price IDs — v7.0 (Cloud Basic / Essentiel / Pro + DictIA Local)
###############################################################################
#
# Format: price_xxxxxxxxxxxxxxxxxxxxxxxxxx
# Naming convention in this codebase: STRIPE_<PLAN>_<TYPE>
# PLAN = CLOUD_BASIC | CLOUD_ESSENTIEL | CLOUD_PRO | DICTIA_LOCAL
# TYPE = SETUP (one-time) | MONTHLY | YEARLY | RENEWAL_YEARLY (DictIA Local An 2+)
#
# Yearly Price = Monthly Price × 12 × 0.85 (15 % discount). Configure both
# Prices in the Stripe Dashboard for each Cloud plan.
# Pro+ is quote-only — NO Stripe Price IDs (the route redirects to /contact).
# Cloud BASIC : 189 $/mo (no setup) — solopreneur, petite équipe, ~165 h audio/mo
# STRIPE_CLOUD_BASIC_MONTHLY=price_xxx
# STRIPE_CLOUD_BASIC_YEARLY=price_xxx
# Cloud ESSENTIEL : 349 $/mo (no setup) — cabinet en croissance, ~330 h audio/mo
# STRIPE_CLOUD_ESSENTIEL_MONTHLY=price_xxx
# STRIPE_CLOUD_ESSENTIEL_YEARLY=price_xxx
# Cloud PRO : 549 $/mo + 485 $ onboarding (one-time) — usage intensif, ~660 h audio/mo
# STRIPE_CLOUD_PRO_SETUP=price_xxx
# STRIPE_CLOUD_PRO_MONTHLY=price_xxx
# STRIPE_CLOUD_PRO_YEARLY=price_xxx
# DictIA LOCAL : 5 998 $ An 1 (one-time matériel + 1ère année logiciel) puis 500 $/an dès An 2
# STRIPE_DICTIA_LOCAL_SETUP=price_xxx
# STRIPE_DICTIA_LOCAL_RENEWAL_YEARLY=price_xxx
###############################################################################
# Required Stripe Dashboard configuration
###############################################################################
#
# 1. Activate CAD currency on the account (Settings → Account → Currencies).
#
# 2. Enable Stripe Tax with TPS (5 %) and TVQ (9.975 %) for Quebec
# (Tax → Settings → Tax registrations → Canada → Quebec).
# All Checkout Sessions are created with `automatic_tax: { enabled: true }`
# and `billing_address_collection: required` so Stripe computes taxes.
#
# 3. Enable Apple Pay + Google Pay
# (Settings → Payment methods → Apple Pay, Google Pay).
# Apple Pay requires verifying the dictia.ca domain via the Stripe-hosted
# `.well-known/apple-developer-merchantid-domain-association` file.
#
# 4. For each Cloud plan, create:
# - One recurring monthly Price (CAD, billing_scheme=per_unit)
# - One recurring yearly Price (CAD, = monthly × 12 × 0.85)
# For Cloud PRO, also create a one-time Price for the 485 $ setup fee.
# For DictIA LOCAL, create:
# - One one-time Price for 5 998 $ (An 1 — matériel + logiciel)
# - One recurring yearly Price for 500 $ (renewal — MAJ + support dès An 2)
#
# 5. Create a webhook endpoint (B-2.8) pointing at
# https://your-domain.example/checkout/webhooks/stripe
# (the route lives under the /checkout/* prefix; CSRF-exempt; signature-
# verified via STRIPE_WEBHOOK_SECRET below).
#
# Subscribe at minimum to these 5 events (the only ones the handler
# processes; all others are acknowledged with 200 + ignored):
# - checkout.session.completed (creates Subscription row, sets
# User.subscription_status='active')
# - customer.subscription.updated (status / current_period_end sync)
# - customer.subscription.deleted (marks status='canceled')
# - invoice.payment_succeeded (renewal touch; recovers past_due)
# - invoice.payment_failed (marks status='past_due')
#
# Copy the signing secret (whsec_...) into STRIPE_WEBHOOK_SECRET above.
# Without that secret, the webhook endpoint returns 400 invalid_signature
# on every delivery (Stripe will retry for up to 30 days).