Blocked subscription shapes
The list of Stripe subscription shapes Unchurn won’t auto-cancel. These route to a manual cancellation request instead — the customer’s intent is captured immediately, your team finishes the cancellation in Stripe.
For which dimensions block which retention offer (discount, pause, plan switch, trial extension), see per-offer eligibility. This page is the single answer to “why isn’t this subscription getting automated cancel?”
Shapes that route to manual cancellation
| Shape | What this looks like | Why we don’t auto-cancel | Stripe docs |
|---|---|---|---|
| Multi-item subscription | One subscription with more than one line item | A single “cancels on X date” message doesn’t fit when there are multiple items; their final-invoice semantics differ. | subscriptions overview |
| Schedule-attached subscription | The subscription has a Stripe subscription schedule | A direct scheduled cancel can be overwritten by the next schedule phase or conflict with the schedule’s end behavior. The safer path (releasing the schedule first, then cancelling) is on the roadmap. | subscription schedules |
| Cadence-attached subscription | Stripe v2 preview cadence billing | Cancel behavior on cadence-attached subscriptions is undocumented in Stripe’s public docs. | billing cadences |
| Billing pause set by another tool | The subscription’s billing was paused by something other than Unchurn | Pauses set by another tool may rely on a specific resume path; cancelling underneath is outside the supported set today. Pauses Unchurn set itself use the resume path instead. | pause-payment |
| Stripe-level paused subscription | The subscription is paused at the Stripe level | Stripe’s resume path can create a resumption invoice and leave the subscription paused if payment isn’t handled. Cancel semantics on a Stripe-paused subscription aren’t part of the supported set today. | pause-payment |
| Pending update queued | An out-of-band update is queued on the subscription | Pending updates can interleave unsafely with retention changes; the interaction is unverifiable from Stripe’s docs. | subscriptions overview |
| Past-due subscription | Status is past_due | Open invoices and dunning settings make “scheduled for period end” ambiguous. We don’t mutate dunning state automatically. | subscriptions overview |
| Unpaid subscription | Status is unpaid | Same dunning concern as past-due; access has typically already been cut by collection settings. | subscriptions overview |
| Incomplete subscription | Status is incomplete (Checkout-origin or otherwise) | Stripe explicitly forbids updating an incomplete subscription. The widget surfaces a manual request instead of failing the API call. | subscriptions overview |
| Already terminal | Status is canceled or incomplete_expired | No mutation is valid. The widget tells the customer the subscription is already ended instead of pretending to act. | subscriptions overview |
| Already scheduled to cancel | cancel_at_period_end is true, or cancel_at is set | Already cancelling. The widget shows the existing scheduled-cancel date; no new mutation, no new request. | subscriptions overview |
| Unrecognized future Stripe shape | A status or shape we haven’t seen in production | Unchurn routes unknown shapes to manual rather than calling Stripe on a state we can’t reason about. | subscriptions overview |
Plan-switch-specific blocks
In addition to the global rules above, plan switch enforces these checks against the target plan. See per-offer eligibility for the full table.
| Block | Why |
|---|---|
| Currency mismatch | Stripe rejects a mid-subscription currency change. |
| Non-monthly price on current or target | Plan switch only supports monthly interval (interval = month, interval_count = 1). Annual, weekly, or custom-count prices on either side block the switch. |
| Different tax treatment on the target | An “inclusive” → “exclusive” switch at the same headline price changes the amount actually paid. |
| Target plan archived | Stripe can’t move customers onto an inactive price. |
| Target isn’t strictly cheaper | Plan switch is downgrade-only — same-price or upgrades aren’t allowed. |
| Target not on the merchant’s approved downgrade list | Product names and metadata aren’t entitlement proof; each downgrade path must be explicitly approved. |
| Multi-currency price on target | Per-currency amounts can drift independently and invert the comparison in the customer’s settlement currency. |
See also
- Eligibility — the rationale for the manual-request lane.
- Per-offer eligibility — which dimensions block which retention offer.
- Manual cancellation request — the customer + merchant UX when automated cancel is blocked.