I want to downgrade a customer at the end of the current period. When that happens. I am aware of the method of setting a trial end to the current period end and setting proration_behavior
to none
, and finally setting up a webhook to listen to subscription.deleted
and then create the new subscription 1 2. I'm trying to find a way not to use webhooks so Stripe handles the switch on their side.
I think this is somehow achievable using subscription schedules.
I have in mind the following, but I haven't yet tried, and I'd like to get opinions first:
// create schedule if it doesn't exist
let schedule: Stripe.SubscriptionSchedule;
if (!stripeSubscription.schedule) {
schedule = await this.stripe.subscriptionSchedules.create({
from_subscription: stripeSubscription.id,
});
} else {
schedule = await this.stripe.subscriptionSchedules.retrieve(stripeSubscription.id);
}
await this.stripe.subscriptionSchedules.update(schedule.id, {
end_behavior: 'release',
phases: [
{
plans: [{plan: stripeSubscription.items.data[0].plan.id}],
end_date: stripeSubscription.current_period_end,
},
{
proration_behavior: 'none',
collection_method: 'charge_automatically',
plans: [{plan: replacementPlanId}],
end_date: stripeSubscription.current_period_end
},
],
});
The above would create a schedule if it doesn't exist and then update that schedule to downgrade the plan. I am not sure whether the second phase end would actually work, I may need to add a day to be sure. Or just don't set anything and let the schedule happen, but I'm wondering in that case if the first phase will be deleted when it ends, other wise the next time the customer switches plan again, it may omit to include the new plan in the array. I could go around this by doing the following:
phases: [
...schedule.phases.filter(phase => phase.end_date > Date.now() / 1000).map((phase, index, array) => {
if (array && array.length -1 === index && !phase.end_date) {
phase.end_date = stripeSubscription.current_period_end;
}
return {
plans: phase.plans,
end_date: phase.end_date,
};
}),
{
proration_behavior: 'none',
collection_method: 'charge_automatically',
plans: [{plan: replacementPlanId}],
end_date: stripeSubscription.current_period_end,
},
],```