# 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.

---
