Skip to content

Release gate: Hosted billing must fulfill the subscription terms #1074

Description

@nedtwigg

Paid Hosted must behave as the published subscription terms promise before real purchases are enabled. This issue is the release acceptance gate across the billing PR stack; it does not require all implementation to land in one PR.

Policy baseline: #997, especially website/src/pages/Terms.tsx and docs/specs/pricing.md → “Paid-launch requirements.” Implementation in flight: #1001 (billing), #999 and #1000 (managed voice/sign-in), and #998 (purchase entry points).

Check each box only when the integrated release candidate has evidence: link the implementing PR/commit and the automated test, Stripe sandbox result, or verified operator procedure. Unchecked means unverified, not necessarily unimplemented. Manual support/refund operations are acceptable where the terms allow them, provided the procedure has an owner, can meet the promised deadline, and has been exercised. Passing this issue clears the billing/consumer-flow gate only; separate privacy, tax, and security launch requirements remain in their owning specs.

Checkout and agreement

  • Confirm production uses Stripe Billing/Checkout with DiffPlug LLC as seller, consistent with Privacy and Terms for paid Hosted #997. Remove any remaining Managed Payments configuration and update stale descriptions: Hosted billing: checkout, subscription entitlement, founding cohorts #1001 currently describes “Managed Payments on.”
  • Before purchase, show the selected plan, USD price, billing interval, total including any tax charged, automatic renewal, cancellation method, refund conditions, and material usage limits; verify monthly, yearly, and founding offers against the published page and terms.
  • Obtain affirmative agreement to the applicable version of the terms and express consent to automatic renewal before charging. Retain the account/order, accepted version, the offered price and usage limits from the Hosted page, timestamp, and evidence of the consent presented and given; a footer link alone is insufficient.
  • Send a durable purchase confirmation containing the agreed subscription information, cancellation/refund instructions, and applicable withdrawal information/model form. Preserve the actual accepted terms rather than relying only on a link whose contents can change. Verify delivery to the checkout email for accounts without a sign-in email.
  • Ensure the managed-voice customer provisions are accepted before managed voice access, including existing accounts that later subscribe; archive the incorporated provider requirements with the accepted version.

Cancellation and account closure

  • Provide direct online cancellation from the account's billing controls without retention hurdles; clearly distinguish stopping renewal from ending access immediately. Verify cancellation stops future charges and preserves access through the paid period.
  • Exercise support cancellation for a customer who cannot sign in or access the portal. Verify ownership using an alternative process without requiring account recovery, and confirm cancellation to the customer.
  • Account closure cancels future renewals and explains access end/refund eligibility before closure. Exercise closure with an active subscription and verify Stripe will not renew it.

Refunds and statutory withdrawal

  • Exercise the voluntary full refund within 30 days of the first subscription payment and each annual renewal, including collected tax. Monthly renewals are outside this voluntary guarantee; plan changes and resubscription do not restart the first-payment window. Preserve any separate statutory rights.
  • A full refund under the voluntary guarantee immediately ends the subscription and paid entitlement and returns a founding seat as promised. Verify the operator/API procedure updates Stripe and Dormouse consistently, including delayed or retried webhooks; a refund alone must not leave renewal active.
  • Disclose the EEA/UK consumer's initial 14-day withdrawal right and optional model form before purchase and in the durable confirmation. Accept an unambiguous email/postal notice without requiring a reason, a particular form, or account recovery.
  • Provide a prominent “Withdraw from contract” function on the billing page throughout the statutory withdrawal period, distinct from ordinary cancellation. Let the customer identify the contract and confirm submission; send a durable acknowledgement containing the statement and submission date/time. Disclose where to find it before purchase and in the confirmation.
  • Exercise withdrawal end to end: stop the contract/access and renewal, refund all subscription payments including collected tax within 14 days of receiving notice, impose no fee or deduction for use, and use the original payment method unless otherwise expressly agreed. Immediate use must not waive the promised right.
  • Exercise an unused-period refund, including corresponding collected tax, for permanent discontinuation, termination unrelated to customer breach, a material service reduction, or rejection of a material terms change during a prepaid period. The 30-day voluntary window must not block these refunds.

Notices and changes

  • Route subscription notices to the current checkout/billing email, including provider-only accounts without a sign-in email. Route other account notices to the account contact email or show them at sign-in when none exists. Verify updates and record when notices are sent or presented; an undisplayed notice does not start a notice period. Preserve additional legally required notice and consent processes.

  • Apply the replacement terms to new accounts on acceptance. For existing accounts, give notice of the actual effective date at least 30 days in advance unless they expressly accept sooner, and obtain renewed agreement where required. Preserve the previous agreement until replacement applies. Publishing a page or its last-updated date alone must not retroactively replace an agreement.

  • Configure and verify the notices required in launch jurisdictions, with an identified owner and delivery evidence. Include California annual-term renewal notices 15–45 days before renewal, fee-change notices 7–30 days before effectiveness, and annual reminders for monthly subscriptions, with cancellation instructions. These examples are not an exhaustive worldwide notice matrix.

  • Verify the promised minimum 30-day notice for discontinuation, material reductions, and material terms changes, with the stated urgent legal/security exception, the applicable unused-period refund, and renewed agreement where required. Do not apply terms changes retroactively to disputes.

  • Price changes take effect only at a future renewal after applicable notice and never override a founder's locked base USD price. Confirm checkout, invoices, account UI, and notices consistently distinguish the base price from tax.

Payment failure and founding plans

  • Verify a partial refund or billing correction alone leaves the subscription and entitlement intact. Full refunds under the guarantee still end the subscription as described above.

  • Exercise payment-dispute/chargeback handling separately from refunds: distinguish temporary suspension from termination, notify the customer and provide a contact path, restore remaining paid access and the prior founding price if suspension was mistaken or payment is restored, and handle a final reversal without future unintended renewals. Preserve dispute rights and refunds owed; verify retried/out-of-order events.

  • Verify failed-payment behavior against the terms: paid features stop until payment succeeds, local Dormouse remains usable, and managed voice falls back to the system voice. Preserve access to billing/cancellation for lapsed subscribers.

  • Exercise founding-price retention: 30 days to cure a failed founding renewal preserves the locked price, not paid access; cancellation after the paid period or failure to cure loses the lock as stated. Provider migration or DiffPlug-caused payment failure must preserve the lock and offer a reasonable chance to restore payment.

Integrated release sign-off

  • Run the applicable purchase, renewal, cancellation, refund, withdrawal, and payment-failure scenarios against Stripe sandbox with real test credentials and the release-candidate app, beyond StripeDev mocks. Include duplicate/delayed webhook delivery and confirm no double refund or renewal after cancellation.
  • Verify billing/support emails are monitored and the cancellation, refund, closure, and withdrawal procedures have a named operator and response timing sufficient to meet the promises above.
  • Reconcile the final website offer, checkout, Stripe settings, account UI, emails, and terms; archive the final accepted policy versions and offered limits, record actual publication and applicability dates, and verify the notice/acceptance transition for existing accounts. Keep disclosures of unshipped practices conditional. Recheck affected boxes if the terms or implementation changes.
  • Record the release commit, Stripe configuration checked, evidence links, date, and release approver in a closing comment. Enable production purchases only after this issue is satisfied and the separate release gates are cleared; merging an individual billing PR does not close this gate.

Activity

  1. dormouse-bot commented on Oct 8, 2026

    @dormouse-bot
    Collaborator

    No triage action needed on the gate itself. One concrete pointer for the first box: on #1001's head (cc2075a), Managed Payments is still wired in code as well as in the PR description, and #997's merchant-of-record wording hasn't reached that branch yet:

    That README also has the only refund procedure written down so far: refund from the dashboard, then cancel immediately (L217). That could serve as the starting point for the "full refund ends the subscription" box. It is still manual and has not been exercised.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions