#evan_api
1 messages ¡ Page 1 of 1 (latest)
đ Welcome to your new thread!
â˛ď¸ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
âąď¸ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
đ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1310874733205520398
đ Have more to share? Add more details, code, screenshots, videos, etc. below.
this is how am creating the subscripition scheduler
const createSubscriptionScheduler = async (
user,
newSubscriptionPlan,
providerSubscription,
newProviderPlan,
providerCouponId = null,
dbDiscountId = null
) => {
let scheduleId = providerSubscription.schedule
let schedule = null
if (!scheduleId) {
schedule = await stripeGatewayClient.subscriptionSchedules.create({
from_subscription: providerSubscription.id,
})
scheduleId = schedule.id
}
schedule =
await stripeGatewayClient.subscriptionSchedules.retrieve(scheduleId)
const defaultPhase = schedule.phases[0]
const secondPhase = {
items: [
{
price: newProviderPlan.id,
},
],
start_date: defaultPhase.end_date,
metadata: {
subscriptionPlanId: newSubscriptionPlan.id,
userId: user.id,
discountId: SYSTEM_UUID,
},
}
if (providerCouponId) {
secondPhase.coupon = providerCouponId
secondPhase.metadata.discountId = dbDiscountId
}
await stripeGatewayClient.subscriptionSchedules.update(scheduleId, {
end_behavior: 'release',
phases: [
{
items: defaultPhase.items,
start_date: defaultPhase.start_date,
end_date: defaultPhase.end_date,
metadata: defaultPhase.metadata,
currency: defaultPhase.currency,
},
secondPhase,
],
})
return providerSubscription
}
after the subscription_scheduler has kicked in and downgraded the subscription as expected, if user tries to cancel the subscription, they get attached error above,
here is my cancelSubscription function:
const cancelProviderSubscription = async (providerSubscriptionId) => {
try {
const updatedProviderSubscription =
await stripeGatewayClient.subscriptions.update(providerSubscriptionId, {
cancel_at_period_end: true,
})
if (!updatedProviderSubscription) return null
return {
status: updatedProviderSubscription.status.toUpperCase(),
intervalEndCancel: true,
}
} catch (ex) {
throw new SubscriptionsProviderError(transformStripeError(ex))
}
}
The subscription is managed by the subscription schedule `sub_sched_1QFwX0D9sYh65PYtF8xw3tCh`, and updating any cancelation behavior directly is not allowed. Please update the schedule instead.
I am assuming the end_behavior param should release the scheduler from the subscription (subscription should not be managed by sched anymore), what am I missing here?
await stripeGatewayClient.subscriptionSchedules.update(scheduleId, {
end_behavior: 'release',
phases: [
{
items: defaultPhase.items,
start_date: defaultPhase.start_date,
end_date: defaultPhase.end_date,
metadata: defaultPhase.metadata,
currency: defaultPhase.currency,
},
secondPhase,
],
})
You can cancel the subscription schedule. https://docs.stripe.com/api/subscription_schedules/cancel and it will also cancel the associated the subscription
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
I see, then what is end_behavior :''release" here ?
As i assumed this will detach the subscription scheduler from the subscription after the second phase is excuted..
Yes you are right. If you set it to cancel, then the schedule will cancel the subscription upon release
Okay so as far as I understood, the end_behavior should be set to release as I do not want the subscription to be cancelled right after they are downgraded when the second phase executes (Downgrade actually occurs).
Yet, although I have set the end_behavior to release the subscription somehow keeps being managed by the subscription scheduler that was released ..
if this is the case, If I have to cancel a subscription after the downgrade..
I need to check if a subscription has a scheduleId, if yes, cancel the schedule, if no, do normal update subscriptions.update(providerSubscriptionId, { cancel_at_period_end: true, })
Am I correct here? The only confusion I have is why we have the subscription being managed by scheduler even tho it was set to released...
below text from stripe doc
release will end the subscription schedule and keep the underlying subscription running.
if this is the case, am still not sure why I get The subscription is managed by the subscription schedule sub_sched_1QFwX0D9sYh65PYtF8xw3tCh, and updating any cancelation behavior directly is not allowed. Please update the schedule instead. when canceling the subscription.
Did you release the subscription schedule before calling the subscription update API?
I just checked the schedule and it's still attached to a subscription.
events?related_object=sub_1QDpYWD9sYh65PYtIWeIkZXK
the following event creates the scheduler evt_1QFwX0D9sYh65PYtfpEFXRkU with end_behavior : realease
Yes, but it's still attached to the subscription when you made the request to update the subscription.
Yeah that's the thing, so, if you check the next event
evt_1QP4KqD9sYh65PYt3yzgl7vv
Which does the downgrade according to the scheduler ..
after that event I am expecting the scheduler to be detached from the subscription
After this downgrade operation happened,
I can see evt_1QP5KQD9sYh65PYtOWFE9JHd
which updates scheduler
Not really, I don't see you specified an end_date to end the schedule.
"released_at": null,
"released_subscription": null,
"renewal_behavior": "release",
"renewal_interval": null,
"status": "active",
"subscription": "sub_1QDpYWD9sYh65PYtIWeIkZXK",
You specified end_behaivour, but you didn't specify when to end
Okay
But the second phase has start_date and end_date?
const createSubscriptionScheduler = async (
user,
newSubscriptionPlan,
providerSubscription,
newProviderPlan,
providerCouponId = null,
dbDiscountId = null
) => {
let scheduleId = providerSubscription.schedule
let schedule = null
if (!scheduleId) {
schedule = await stripeGatewayClient.subscriptionSchedules.create({
from_subscription: providerSubscription.id,
})
scheduleId = schedule.id
}
schedule =
await stripeGatewayClient.subscriptionSchedules.retrieve(scheduleId)
const defaultPhase = schedule.phases[0]
const secondPhase = {
items: [
{
price: newProviderPlan.id,
},
],
start_date: defaultPhase.end_date,
metadata: {
subscriptionPlanId: newSubscriptionPlan.id,
userId: user.id,
discountId: SYSTEM_UUID,
},
}
if (providerCouponId) {
secondPhase.coupon = providerCouponId
secondPhase.metadata.discountId = dbDiscountId
}
await stripeGatewayClient.subscriptionSchedules.update(scheduleId, {
end_behavior: 'release',
phases: [
{
items: defaultPhase.items,
start_date: defaultPhase.start_date,
end_date: defaultPhase.end_date,
metadata: defaultPhase.metadata,
currency: defaultPhase.currency,
},
secondPhase,
],
})
return providerSubscription
}
No, I don't see an end_date on the 2nd phase.
My mistake, there's a end_date, which is 1735140964 2024-12-25 15:36:04 UTC
So this schedue will end on 25 Dec
I see
Got it
So for these subscriptions, that are in this state..
And If I want to cancel their subscription, instead of calling
await stripeGatewayClient.subscriptions.update(providerSubscriptionId, {
cancel_at_period_end: true,
})
I should be canceling the scheduler only
Yes you are right
Alright thanks for the help, appreciate it