Skip to content

Portal: let members pause the subscription instead of cancelling (top churn reason: unused) #204

Open

Description

@sre-helmcode

Why

unused is the second largest cancellation reason in the live data (162 all-time; 15 of the 63 members with a cancellation already scheduled on nan_member), and the free-text comments say it explicitly: "no lo estoy usando lo suficiente", "me tomaré un descanso", "volveré en unos meses", "no voy a poder exprimirlo en próximos 2-3 meses".

For those members the product is not the problem and the price is not the problem: they need it to stop billing for a while. Today the only exit is cancel, and coming back means a fresh Checkout.

The Stripe Customer Portal already supports pause; it is simply switched off in the account's default configuration:

features.subscription_pause.enabled = false   (bpc_1Lv35lBF7qtPjBKwspNmYQ9v, read 2026-10-19)

What

Enable pause in the Customer Portal configuration, and decide what a paused subscription means for us rather than flipping the toggle blind:

  1. Portal config: subscription_pause.enabled = true. One API call, no deploy.
  2. Billing semantics: Stripe pauses invoicing. Choose the behavior (keep the subscription as-is and resume where it left off, vs void the open invoice). A pause must not extend paid access it did not pay for, and must not leave a hole in entitlements.
  3. Entitlements: cloud-api reads entitlement live from Postgres (handlers.ResolveOwner), and Stripe sends customer.subscription.paused / .resumed. Decide whether a paused member keeps Discord access (probably yes, it is the retention hook) and loses inference (probably yes, no billing). Keep it out of churned: a paused member is not churn and must not trigger teardown (revoke.Service).
  4. Lifecycle: make sure the reconciler and the MRR metrics treat paused as paused, not as active payment and not as churn.

Acceptance

  • A member can pause from the portal, and cannot pause and keep inference for free.
  • Discord access survives the pause; inference keys stop working while paused and come back on resume (or the opposite decision is written down, with the reason).
  • member_events records the pause and the resume with an actor, and the MRR dashboard separates paused from active and from churned.
  • The cancellation win-back flow can point to pause as the alternative.

Notes

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

Metadata

Metadata

Assignees

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