# Todo Working checklist. Add sections per area. Tick boxes as you go. --- ## Stripe Spec: `docs/superpowers/specs/2026-04-23-stripe-subscription-lifecycle-design.md` Rules: `.claude/rules/payments.md` ### Pre-production (test mode first, then repeat in live mode) - [ ] **Stripe Dashboard — retry schedule.** Billing → Automations → Subscription retry rules. Switch Smart Retries → Custom. Retry on days 1, 3, 5. After final retry → *Cancel subscription*. - [ ] **Stripe Dashboard — customer emails.** Emails → Customer emails. Enable "Successful payments", "Failed payments", "Upcoming renewals". - [ ] **Stripe Dashboard — branding.** Settings → Branding. Upload FuelAlert logo, set primary colour to match app accent. - [ ] **Stripe Dashboard — Customer Portal.** Settings → Billing → Customer Portal. Allow plan changes across all 6 prices (basic/plus/pro × monthly/annual), cancellation at period end only, card updates, invoice history. Hide everything else. - [ ] **Stripe Dashboard — webhook endpoint.** Developers → Webhooks. Add endpoint at `{APP_URL}/stripe/webhook`. Subscribe to: `customer.subscription.created`, `customer.subscription.updated`, `customer.subscription.deleted`, `invoice.payment_succeeded`, `invoice.payment_failed`. Copy signing secret → production `.env` as `STRIPE_WEBHOOK_SECRET`. ### Production env + server - [ ] **`.env` keys** set on production: - `STRIPE_KEY=pk_live_...` - `STRIPE_SECRET=sk_live_...` - `STRIPE_WEBHOOK_SECRET=whsec_...` - `CASHIER_CURRENCY=gbp` - `QUEUE_CONNECTION=redis` - `STRIPE_PRICE_BASIC_MONTHLY`, `STRIPE_PRICE_BASIC_ANNUAL` - `STRIPE_PRICE_PLUS_MONTHLY`, `STRIPE_PRICE_PLUS_ANNUAL` - `STRIPE_PRICE_PRO_MONTHLY`, `STRIPE_PRICE_PRO_ANNUAL` - [ ] **Run `php artisan migrate`** — adds `users.grace_period_until`. - [ ] **Queue worker** consuming both queues: `--queue=notifications,default` (reminders go on the `notifications` queue). - [ ] **Redis persistence** (AOF or RDB) enabled — delayed jobs sit for 3–5 days. - [ ] `php artisan route:list --name=billing` — confirm 4 routes (checkout, portal, success, cancel). ### E2E QA (Stripe test mode) Requires the Dashboard + env tasks above done first. Stripe test cards: - `4242 4242 4242 4242` — success - `4000 0000 0000 0341` — renewal fails (use to test dunning) - [ ] Sign up on each paid tier × both cadences (6 combos) → confirm tier shows. - [ ] Upgrade basic → pro via Portal → confirm instant swap. - [ ] Downgrade pro → basic via Portal → confirm change scheduled for period end. - [ ] Cancel mid-period → features persist until period end → drop to free. - [ ] Use `4000 0000 0000 0341` + `stripe trigger invoice.payment_failed`: - Banner appears on dashboard with correct "by {date}" string. - Day-3 job is queued (visible via `php artisan queue:listen notifications`). - Day-5 job is queued. - Final Stripe retry fails → `customer.subscription.deleted` → user drops to free, WhatsApp + SMS prefs disabled, banner disappears. - [ ] Recover mid-grace (update card via Portal) → `invoice.payment_succeeded` clears grace, banner disappears, queued reminders silently no-op when they run. ---