Subscription Upgrades
Subscription upgrades, moving a subscriber from one term to another, are now available for all Stripe Billing managed subscriptions.
Upgrade model: Stripe subscription-first
Piano now uses Stripe's subscription-first model for all upgrades. This means:
-
The subscription plan change is applied to Stripe immediately when an upgrade is initiated, subscription remains the same in Stripe.
-
Payment is collected after the subscription change, not as a prerequisite to it.
-
If payment fails, the subscriber enters a grace period with Stripe Smart Retries. The subscription change is NOT rolled back.
-
All upgrade channels (My Account, Checkout, Publisher Dashboard, API, Action Manager) behave identically.
Note: This is a behavioral change from Piano billing, where immediate upgrades made via MyAccount, Dashboard and API resulted in a rollback (no charge, no change) but not Onsite Upgrades which already follow the subscription-first model. Publishers who rely on that rollback behavior should review their downstream integrations.
Supported upgrade types
-
Immediate upgrade (billing_timing=0): The plan change and payment happen at the moment of the upgrade request. Stripe creates a two-phase Subscription Schedule: Phase 1 ends immediately, and Phase 2 (new plan) starts with a prorated charge.
-
End-of-billing-cycle upgrade (billing_timing=1): The plan change is scheduled to take effect at the end of the current billing period. Stripe creates a Phase 1 (current plan, runs to period end) and Phase 2 (new plan, starts at period end).
-
Payment-to-payment and Payment-to-dynamic: Upgrades between payment term subscriptions and from payment to dynamic subscriptions are supported. Dynamic-to-payment and scheduled-to-payment upgrade offers are not supported and must be disabled before switching. A scheduled term charges the subscriber on a fixed schedule of dates and amounts that you define, rather than on a recurring billing period.
-
Same currency: Stripe subscription currency is immutable. Cross-currency upgrades are not supported.
-
Pending upgrades: Subscriptions with an already scheduled (deferred) upgrade will not be switched to Stripe Billing until that upgrade executes or is cancelled.
For the exact timing mechanics and proration math behind immediate vs. deferred upgrades, see Upgrade Types and Timing.
Proration and payment collection
Piano calculates all proration amounts before passing them to Stripe. The proration logic is unchanged from Piano billing.
Payment is collected off-session: there is no in-session payment step during the upgrade. Stripe charges the subscription's default payment method automatically, in case of failure starts Smart Retries, else Piano starts Passive Churn Prevention on BYOP subscriptions.
Payment failure handling
If an upgrade payment fails, behavior depends on the payment method type:
-
Stripe-native and BYOP synchronous methods: Grace period starts with Passive Churn Prevention on BYOP or Stripe Smart Retries attempt recovery for up to 8 retries over a configurable window on Stripe native methods. If all retries fail, the subscription follows the configured dunning policy. The subscriber retains upgraded plan access during the grace period.
-
BYOP asynchronous methods (direct debit, bank transfer): Payment failure results in immediate subscription cancellation. There is no grace period. Access is granted at upgrade time but revoked when the async failure is confirmed. This matches Piano billing behavior for BYOP async. See Non-Stripe Providers (BYOP).
Pending upgrade management
All lifecycle operations for deferred (end-of-billing-cycle) upgrades are supported:
|
Operation |
Who Can Trigger |
What It Does |
|---|---|---|
|
Suspend |
Subscriber or Admin |
Pauses a deferred upgrade. The current subscription expires at end of billing period if not resumed. |
|
Resume |
Subscriber or Admin |
Reactivates a suspended upgrade. Stripe schedule restored. Auto-renewal re-enabled. |
|
Cancel |
Admin only |
Cancels the deferred upgrade. Subscription returns to ACTIVE. No cancellation of the current subscription. |
|
Abort (auto) |
System (automatic) |
If a suspended upgrade reaches billing period end without being resumed, it auto-aborts. Subscription expires at the end of the period. |
Shared account upgrades
Upgrades for shared account (family/team) subscriptions are supported with no additional configuration required.
Supported features overview
|
Scenario |
Status |
|---|---|
|
Payment term → Payment term (upgrades and downgrades) |
✓ Supported |
|
Immediate upgrade with or without proration |
✓ Supported |
|
Deferred upgrade (end of billing period) |
✓ Supported |
|
Deferred upgrade with early access to new resource |
✓ Supported |
|
Upgrades for BYOP subscriptions |
✓ Supported |
|
Suspend / resume upgrade |
✓ Supported |
|
Upgrade cancellation (admin) |
✓ Supported |
|
Upgrades via My Account, Dashboard, API, on-site |
✓ All channels supported |
Upgrade behavior with asynchronous payments
When an upgrade is paid with an asynchronous payment method, Piano's webhooks, history events, and emails behave differently under the Stripe Billing integration than they did under Piano billing. Previously, Piano confirmed the upgrade as finished at the moment it was initiated, even though the payment was still processing. Now, Piano separates the initiation of the term change from the confirmation of payment.
At the moment of upgrade, Piano sends a new "initiated" webhook set, alongside the existing payment_pending.payment_pending:
-
term_change.term_change_initiated -
subscription_ended.term_change_initiated -
subscription_created.term_change_initiated -
access_revoked.term_change_initiated -
access_granted.term_change_initiated
These reflect that the term change has taken effect while payment is still processing.
Once payment succeeds, Piano sends term_change.term_change_finished and payment_completed.payment_completed to confirm completion.
If payment fails, behavior depends on whether a grace period is configured. Under Piano billing, a failed payment expired the subscription immediately, with no grace period available. Under the Stripe Billing integration, if a grace period is configured, Piano instead sends term_change.term_change_failure and term_change.term_change_grace_period_started, then falls back to the same webhook sequence used for synchronous-payment upgrades once the grace period resolves (through retry success or final failure).
This change also affects what users and publishers see directly:
-
History events: MyAccount and the Publisher Dashboard display new history events describing the pending/initiated upgrade state, for upgrades triggered from either MyAccount or the Publisher Dashboard.
-
Emails: If payment fails and a grace period is configured, users receive the standard "Subscription renewal failure" email rather than "Term change failure." Note that the grace-period paragraph within that email is intentionally suppressed in this case.