diff --git a/docs/specs/hosted.md b/docs/specs/hosted.md index 5343b0034..c825631a2 100644 --- a/docs/specs/hosted.md +++ b/docs/specs/hosted.md @@ -330,7 +330,7 @@ Hosted's Workers count what they serve in aggregate daily rows; no page or deskt | `pocket.signin` | none | a passkey sign-in mints a session | | `checkout.started` | `plan:ref` | checkout answers a URL | | `checkout.completed` | `plan:ref` | the webhook processes a completion (`completedCheckout`) | -| `subscription.canceled` | plan | the webhook processes a purchase's end | +| `subscription.canceled` | plan | the webhook processes a purchase's end, unless refunded | | `subscription.refunded` | plan | that end's recorded reason was `refund`, or it came within `REFUND_DAYS` | - **Never count a label off its event's list** (`METRIC_LABELS`): the write throws. Row contents and readers: `docs/specs/security-hosted.md` -> "Account boundary". diff --git a/docs/specs/pricing.md b/docs/specs/pricing.md index b62d17413..2ed05660a 100644 --- a/docs/specs/pricing.md +++ b/docs/specs/pricing.md @@ -55,7 +55,7 @@ Source of truth: `Hosted` in `website/src/pages/Hosted.tsx`; `fetchCohort` in `w - **Must use Stripe Billing, Stripe-hosted Checkout, and its customer portal through `@pgstencil/stripe`; DiffPlug is the seller and merchant of record**, responsible for refunds and applicable tax registration, collection, filing, and remittance; Stripe Tax calculates the tax. **Never receive or store full card numbers in Dormouse.** A founding lock is a per-cohort Price; cohort counts come from the billing provider's completed subscriptions. - **The entitlement is the account's subscription, read on the server on every voice and Relay request** (`docs/specs/hosted.md` -> "Entitlement"). No licence, no offline verification, and no grace past what the subscription grants; a lapsed member's voices fall back to the system voice and its Burrows to `not-entitled`. -- **Cohorts close by count, never by date**: completed purchases at the billing provider; a purchase ending within the 30-day refund window, as a full refund or finally reversed payment ends it ("Checkout"), returns its seat to its cohort. **Never reopen the ladder at a lower step** once a cohort has closed. **When a cohort closes the price rises one step and the counter resets to 100**, and **founding closes only when the ladder reaches list**: founding means bought at launch pricing, and the Hosted Relay shipping does not close it. +- **Cohorts close by count, never by date**: completed purchases at the billing provider; a purchase ending within the 30-day refund window, as a full refund or finally reversed payment ends it, returns its seat to its cohort. **Never reopen the ladder at a lower step** once a cohort has closed. **When a cohort closes the price rises one step and the counter resets to 100**, and **founding closes only when the ladder reaches list**: founding means bought at launch pricing, and the Hosted Relay shipping does not close it. - **Checkout honors the price it opened at.** Concurrent checkouts may oversell a cohort by a few seats; the overage is the customer's, and the next cohort still opens at a full 100. - **A full refund or a finally reversed payment ends the subscription it paid for**, so the next request is refused. A partial refund or billing correction never ends it, and an open dispute only suspends it until it closes. - **Checkout starts from a Hosted account**: `/checkout` on the account origin asks for sign-in first, so the subscription belongs to an account from its first event. @@ -123,10 +123,9 @@ What is built — the endpoint, what a request carries, the daily cap, and the f ### Renewal, cancellation, refund - **Every plan auto-renews; cancel any time; access runs to period end.** -- **Must offer a full refund within 30 days of the first Hosted payment or any yearly renewal**, including collected tax; monthly renewals, plan changes, and resubscriptions do not restart this voluntary first-payment guarantee. **Must preserve mandatory legal remedies.** A full refund revokes. +- **Must offer a full refund within 30 days of the first Hosted payment or any yearly renewal**, including collected tax; monthly renewals, plan changes, and resubscriptions do not restart this voluntary first-payment guarantee. **Must preserve mandatory legal remedies.** - **A failed founding renewal gets 30 days of grace before the lock is lost.** - **A subscription is personal and non-transferable.** -- **No trial**: the 30-day refund is the trial. ### Paid-launch requirements diff --git a/hosted/wrangler.jsonc b/hosted/wrangler.jsonc index 6d1974d53..d8f248830 100644 --- a/hosted/wrangler.jsonc +++ b/hosted/wrangler.jsonc @@ -68,8 +68,9 @@ } ], "triggers": { - // Billing's resync of subscriptions whose paid period has ended - // (`resyncBilling`); it reads nothing while billing is closed. + // Billing's periodic pass (`resyncBilling`): lapsed subscriptions, failed + // withdrawal and closure refunds, open disputes, notices, and price + // changes; it reads nothing while billing is closed. "crons": [ "*/10 * * * *" ] diff --git a/scripts/spec-word-budgets.json b/scripts/spec-word-budgets.json index edd5325cf..208af1cd8 100644 --- a/scripts/spec-word-budgets.json +++ b/scripts/spec-word-budgets.json @@ -12,7 +12,7 @@ "docs/specs/dor-tools-builtin.md": 1750, "docs/specs/dor-tools-lib.md": 350, "docs/specs/glossary.md": 2950, - "docs/specs/hosted.md": 6300, + "docs/specs/hosted.md": 6350, "docs/specs/layout.md": 7250, "docs/specs/mobile-terminal-ui.md": 1250, "docs/specs/mouse-and-clipboard.md": 4200,