diff --git a/docs/billing.md b/docs/billing.md index a56e0d0..55cb2d9 100644 --- a/docs/billing.md +++ b/docs/billing.md @@ -235,6 +235,29 @@ screening; customers are converted to the $79/mo monitoring subscription after that first cycle (the standalone $948/yr of monitoring is no longer given away inside the bundle). +**Validation status (2026-06-18):** +- ✅ *Checkout half — proven against LIVE Stripe.* A dry-run created a real + `mode:subscription` Checkout Session with the exact production params + (recurring `price_data`, `unit_amount=7900`, `recurring.interval=month`, + `card`+`us_bank_account`, metadata) — Stripe returned `amount_total=7900`, + `type=recurring`, then the session was immediately **expired** (creating a + session never charges anyone; only a completed hosted page does). Net effect + on prod: zero. +- ✅ *Webhook subscription-id extraction* — `invoiceSubscriptionId()` unit tests + (31 in `api/tests/recurring-subscription.test.ts`) cover acacia (top-level) + AND dahlia (nested) invoice shapes, renewal-cycle gating, surcharge + suppression, recurring line-item build. +- ✅ *Worker renewal fulfillment* — `scripts/workers/services/test_npi_recurring.py` + (13 assertions) runs the real handler and asserts the `[Monthly cycle]` / + re-screen behaviour; passes locally + in the deployed workers container. +- ⏳ *Full end-to-end with a Stripe test clock* — NOT yet run. Requires + `STRIPE_TEST_SECRET_KEY` / `STRIPE_TEST_WEBHOOK_SECRET` in the server `.env` + (currently unset; prod is `NODE_ENV=production`). Once those exist: place a + test-card subscription, advance a billing cycle via a test clock, and confirm + the live `invoice.paid` (subscription_cycle) re-dispatches the screening + worker and a fresh certificate is issued. This is the last gap before a real + recurring charge should be marketed. + ### Formation Maintenance Bundles | Bundle | Price | Includes | Savings |