Enable flexible behavior for subscriptions
Use billing mode to control how prorations and invoices for subscriptions are calculated and orchestrated.
Currently, credit proration amounts are calculated based on the value of the subscription item’s current price, tax, quantity, and the last discounts used.
You can configure billing_
to enable a different proration logic that calculates credit prorations based on the original amount previously debited to a customer.
Öffentliche Vorschau
To enable the new proration calculation logic by configuring billing_
, you must upgrade your API version to to 2025-04-30.
or later.
The current behavior could lead to unexpected prorations when a customer’s tax rates change, debit prorations are disabled, or complex amounts off coupons are used. The improved proration logic calculates credit prorations based only on the original amount previously debited to a customer. When a customer makes a change to their subscription that results in a credit, the proration is calculated using the amount they were previously billed, regardless of subsequent changes made to the subscription. Stripe recommends using billing_
if the limitations of the public preview don’t apply to you.
Public preview limitations Public preview
During public preview, billing_
isn’t compatible with all of Stripe Billing’s functionality.
When billing_
is configured:
- Subscription Schedules are not supported.
- Usage-based billing is not supported.
- Automatic tax calculation is not supported.
- Trials are not supported.
- Quotes endpoints are not supported.
- You can’t reset the billing cycle anchor.
- You can’t create backdated subscriptions.
- You can’t pause payment collection on subscriptions.
If you use these features with billing_
, they return a 400 error code.
Configure billing mode Public preview
You can configure billing_
on specific subscriptions, and you can have multiple subscriptions with different billing_mode configurations. You can’t change the billing _
after you set it (this ensures consistent logic and behavior throughout the lifecycle of each subscription).
When you configure billing_
, it also updates subscription.trial_start to reflect the most recent trial start date.
Calculation logic with no prorations
In the following scenario, a 10 USD monthly subscription is upgraded to 20 USD with proration_
set to none
for 10 days. There is no previous debit to base it on. Later, the subscription is downgraded to 10 USD a month with proration_
set to always_
.
To set up this scenario, first you create a subscription for 10 USD/month on 2025-04-01:
The response includes the invoice that’s created for this subscription:
{ id: "sub_123", latest_invoice: { id: "in_123", total: 10_00, currency: "usd" } }
Then, on 2025-04-11, you upgrade the subscription to 20 USD/month without creating prorations:
You can see that the latest invoice is unchanged because proration_
is none
:
{ id: "sub_123", latest_invoice: { id: "in_123" } }
Finally, on 2025-04-21, you downgrade the subscription to 10 USD/month and create prorations:
The default proration calculation logic creates a credit proration based on the current price, even though the customer never paid the 20 USD/month rate. The latest invoice credits a third of the month for 20 USD (-6.67 USD), even though the customer never paid for the price_
price. It also debits a third of the month for 10 USD (3.33 USD).
The calculation logic enabled with billing_
creates a credit proration based on the last price billed for the subscription item. In this case, the latest invoice credits a third of a month for the 10 USD/month price billed on 2025-04-01 (3.33 USD) and debits a third of the month for the 10 USD price (3.33 USD). The credit and debit cancel out so the invoice total is 0 USD.
# Default behavior # billing_mode = legacy_prorations { id: "sub_123", latest_invoice: { id: "in_456", total: -3_34, currency: "usd" } }
# New behavior # billing_mode=flexible { id: "sub_123", latest_invoice: { id: "in_456", total: 0, currency: "usd" } }
Calculation logic for coupons applied to multiple subscription items
The amount_
coupon on the credit proration is weighted to prevent overbilling.
In the following scenario, a 5 USD coupon is unevenly allocated to a 25 USD monthly subscription for a 10 USD item and 20 USD item.
To set up this scenario, you create a subscription with multiple items and a coupon on 2025-02-01:
Which returns this response:
{ id: "sub_123", latest_invoice: { id: "in_123", total: 25_00, currency: "usd", lines: { data: [ { id: "ili_1", amount: 10_00, price: "price_10_monthly", discount_amounts: [{ discount: "di_a", amount: 1_66 }] }, { id: "ili_2", amount: 20_00, price: "price_20_monthly", discount_amounts: [{ discount: "di_a", amount: 3_34 }] }, ] } } }
To cancel the 10 USD/month subscription item using billing_
:
To cancel the same item using billing_
:
The default behavior distributes a 5 USD coupon to each item (2.5 USD each), cancelling the cheaper item (5 USD) and resulting in a refund of 2.5 USD. The total has been calculated with the formula -0.
The new behavior reflects the proportional discount applied to the canceled item, rather than potentially applying the full discount amount to the proration calculation. The total has been calculated using the formula -0.
.
# Default behavior # billing_mode = legacy_prorations { "id": "sub_123", "latest_invoice": { "id": "in_456", "total": -250, "currency": "usd" } }
# New behavior # billing_mode = flexible { "id": "sub_123", "latest_invoice": { "id": "in_789", "total": -417, "currency": "usd" } }