Reputation: 95
I have read in the documenation that the stripe has only one api for subscription update for both upgrade and downgrade.
I have 2 products to which user subscribe, Basic
and Plus
, both are paid.When I upgrade form Basic to Plus, I do the following:
It means at some point user is subscribed to two products in one subscription. What is the best way to handle it?
Now if user downgrades, my buisness logic is to do not cancel the current subscription immidietly. For example, if user wants to go from Plus to Basic. The Basic will start once Plus has finished. Heres how I am handling it currently:
cancel_at_period_end: true
trial period
, so user is charged once current subscription is endedNow this whole senerio is very strange for me. what is the best way to handle my upgrade/downgrade with the update api of stripe. I am using NodeJs
.
Thank you in advance
Upvotes: 8
Views: 15448
Reputation: 415
I am also struggling with the upgrading/downgrading of the stripe subscription. Currently, I am okay with the upgrading, cause I just update the subscription there and prorate on the next invoice. However, I am not sure why I am not able to downgrade successfully with the steps that @karbi provided. My code is as follows:
//* 2. Schedule the current subscription
let schedule = await stripe.subscriptionSchedules.create({ from_subscription: latestActiveSubscription.id })
const currPhase = schedule.phases[0]
//* 3. Update the schedule by adding second phase to downgrade to the new plan
schedule = await stripe.subscriptionSchedules.update(
schedule.id,
{
phases: [
currPhase,
{
items: [{ price: newSubscriptionPlan.stripePlanId, quantity: 1 }],
proration_behavior: 'none',
iterations: 1
}
]
}
)
However, this gave me an error where the phase[0][collection_method]
is missing:
You passed an empty string for 'phases[0][collection_method]'...
I saw the response from the schedule creating from the current subscription and saw that in the phases[0]
the collection_method = null
, but in the schedule itself, it was the correct one - charge_automatically
. Therefore, I decided to assign it to the phase before updating like currPhase.collection_method = schedule.collection_method
. Sadly, there was no success, because another error occurred:
If passing an array with explicit keys (e.g. 'foo[0]=a&foo[1]=b') instead of as an array (e.g. 'foo[]=a&foo[]=b'), the keys must be numeric and sequential starting from 0. You passed the keys '1', we expected to have a key with the value '0'.
Then, I got back to the documentation to check what are the update options and I updated the schedule as follows:
//* 3. Update the schedule by adding second phase to downgrade to the new plan
schedule = await stripe.subscriptionSchedules.update(
schedule.id,
{
phases: [
// currPhase,
{
items: [{ price: currPhase.items[0].price, quantity: 1 }],
start_date: currPhase.start_date,
end_date: currPhase.end_date,
proration_behavior: 'none'
},
{
items: [{ price: newSubscriptionPlan.stripePlanId, quantity: 1 }],
proration_behavior: 'none',
iterations: 1
}
]
}
)
Now, it looks like it works, but not sure if that is the correct way to do so. I will verify tomorrow if the schedule will automatically change the subscription plan.
UPDATE:
Little bit late update, but the above code works like a charm.
Upvotes: 1
Reputation: 2163
There's no need for the customer to have two separate Subscriptions - you can manage this with a single Subscription that is updated in different ways depending on whether it's an upgrade or a downgrade.
Downgrade Create a Subscription Schedule for the Subscription, which will allow you to schedules changes for a Subscription in the future. Schedules can get very complicated, so I'd highly suggest reading through all of Stripe's documentation and glancing through the Schedules API ref. The general flow for how you'd change the price of a Subscription at the end of the current billing cycle goes like this:
phases
). You'll pass in two phases during the update request - The first phase should be the existing current phase on the Subscription Schedule, and the second phase should represent the subscription once it's been downgraded by setting phases[1][iterations]: 1
, phases[1][items][0][price]
, and phases[1][items][0][quantity]
.Upgrade Stripe's documentation has great example of how to do this already here. To summarize it quickly, you'll want to retrieve the Subscription, grab the Subscription Item ID for the item you want to change, and make an update request by setting items[0].id
with the ID you retrieved and items[0].price
with the new price. Depending on whether or not you want prorations, you would also set proration_behavior
.
Upvotes: 9