#NEWJOSSY
1 messages · Page 1 of 1 (latest)
Hi! Let me help you with this.
Hello
What do you want to change exactly?
I want to change billing cycle for the user on his next payment date
My exact case: User bought a subscription on 15th of March and has next payment date on 15-th of April. He requested to change his billing cycle to annual. I want to change his billing cycle on the next payment date on 15-th of April and pay the price for annual subscription
I understand. You can use Subscription Schedules with one phase that starts at the end of this month: https://stripe.com/docs/billing/subscriptions/subscription-schedules
You will probably need to use from_subscription attribute: https://stripe.com/docs/billing/subscriptions/subscription-schedules#managing:~:text=Creating a schedule this way uses attributes on the subscription to set attributes on the schedule.
What is iterations in this schedule ?
If your price is monthly, iterations: 1 is one month.
Okay, if I have subscription with annual billing cycle and I want to move customer on it?
Like user paid for monthly Standard subscription and we have Standard annual subscription, can I move him onto this subscription with his next_payment_date?
Yes. You can create a Subscription Schedule with 1 phase, 1 price (the annual one), starting at the end of the current billing period.
Ok, what if don't specify the phase ?
Like leave it unassigned
var options = new SubscriptionScheduleCreateOptions { Customer = user.StripeCustomerId, StartDate = space.NextPaymentDate, EndBehavior = "release", Phases = new List<SubscriptionSchedulePhaseOptions> { new SubscriptionSchedulePhaseOptions { Items = new List<SubscriptionSchedulePhaseItemOptions> { new SubscriptionSchedulePhaseItemOptions { Price = subscription.Items.Data[0].Id }, }, }, }, }; var service = new SubscriptionScheduleService(); service.Create(options);
like this
But you specify the Phase here. Or did you mean "iterations"?
I think I make it work
made*
will it automatically cancel standart month subscription ?
It seems like there're 2 subscriptions now
You forgot to add FromSubscription, so now the old one is not connected to the new one.
So it won't cancel it
SubscriptionScheduleCreateOptions options = new SubscriptionScheduleCreateOptions { StartDate = space.NextPaymentDate, EndBehavior = "release", FromSubscription = user.StripeCustomerId, Phases = new List<SubscriptionSchedulePhaseOptions> { new SubscriptionSchedulePhaseOptions { Items = new List<SubscriptionSchedulePhaseItemOptions> { new SubscriptionSchedulePhaseItemOptions { Price = priceId, }, }, }, }, };
and now it will be related to the existing subscription?
Yes that will create a schedule that works with that existing subscription
Thank you for confirming. Can you send me the ID of that schedule/subscription?
One second
PriceId for Standard annual subscription - price_1MLnz0KwhjmH7xPxs8ZFMtRy
SubscriptionId of Standard monthly subscription - sub_1MsnXFKwhjmH7xPxJRJ3gA2c
customerId - cus_Ne5f0kdO5OV3xe
Oh apologies I see the error now in that screenshot. So you need to make one call that creates the schedule from the subscription and then another one that adds your phases and whatnot
Like this ?
`SubscriptionScheduleCreateOptions options = new SubscriptionScheduleCreateOptions
{
EndBehavior = "release",
FromSubscription = oldSubscriptionId,
};
SubscriptionScheduleService service = new SubscriptionScheduleService();
await service.CreateAsync(options);
SubscriptionScheduleCreateOptions subscriptionScheduleCreateOptions = new SubscriptionScheduleCreateOptions
{
Customer = user.StripeCustomerId,
StartDate = space.NextPaymentDate,
EndBehavior = "release",
Phases = new List<SubscriptionSchedulePhaseOptions>
{
new SubscriptionSchedulePhaseOptions
{
Items = new List<SubscriptionSchedulePhaseItemOptions>
{
new SubscriptionSchedulePhaseItemOptions
{
Price = newSubscriptionPriceId,
},
},
},
},
};
await service.CreateAsync(subscriptionScheduleCreateOptions);`
I tested already and looks like nothing changed
Sorry and then the second call would be updating the schedule from the first call
`SubscriptionScheduleCreateOptions options = new SubscriptionScheduleCreateOptions
{
FromSubscription = oldSubscriptionId,
};
SubscriptionScheduleService service = new SubscriptionScheduleService();
await service.CreateAsync(options);
SubscriptionScheduleUpdateOptions updateOptions = new()
{
EndBehavior = "release",
Phases = new List<SubscriptionSchedulePhaseOptions>
{
new SubscriptionSchedulePhaseOptions
{
Items = new List<SubscriptionSchedulePhaseItemOptions>
{
new SubscriptionSchedulePhaseItemOptions
{
Price = newSubscriptionPriceId,
},
},
},
},
};`
Like this ?
Looks right enough to try to me
It does not work either
I cannot specify start date with FromSubscription
And on Update startDate required but SubscriptionScheduleUpdateOptions has not such property
Gotcha sorry I lost track of the overall ask. You want this subscription to finish its current phase and then transition to this yearly price. So after you create this subscription schedule from the existing subscription, you will want to do the update call but include two phases: the first phase should be a copy of the existing one with the addition of iterations=1 https://stripe.com/docs/api/subscription_schedules/update#update_subscription_schedule-phases-iterations
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
That tells Stripe to transition to the next phase after this cycle
Then you include the next phase with your yearly price. It actually doesn't need a start date here, the iterations setting in the previous phase will take care of that
How complete code would look like, I just can't understand
The update call would look something like this
{
Phases = new List<SubscriptionSchedulePhaseOptions>
{
new SubscriptionSchedulePhaseOptions
{
Iterations = 1,
Items = new List<SubscriptionSchedulePhaseItemOptions>
{
new SubscriptionSchedulePhaseItemOptions { Price = "price_1234" },
},
},
new SubscriptionSchedulePhaseOptions
{
Items = new List<SubscriptionSchedulePhaseItemOptions>
{
new SubscriptionSchedulePhaseItemOptions { Price = "price_4567" },
},
},
},
};```
Is there something specific about that call that you are having trouble with?
The first price in update is the price of old subscription? Monthly Standard? And second one it the price of annual subscription ?
Correct, the first phase in the schedule is the current one. So include the current price, second one is the one you want to change to
Okay and the first call is for creating schedule and it is ?
SubscriptionScheduleCreateOptions createOptions = new() { FromSubscription = oldSubscriptionId, };
Yep
Ok, one sec, i'll try it
There still an error even with iterations
`SubscriptionScheduleCreateOptions createOptions = new()
{
FromSubscription = oldSubscription.Id,
};
SubscriptionScheduleService service = new SubscriptionScheduleService();
var schedule = await service.CreateAsync(createOptions);
var updateOptions = new SubscriptionScheduleUpdateOptions
{
Phases = new List<SubscriptionSchedulePhaseOptions>
{
new SubscriptionSchedulePhaseOptions
{
Iterations = 1,
Items = new List<SubscriptionSchedulePhaseItemOptions>
{
new SubscriptionSchedulePhaseItemOptions { Price = oldSubscription.Items.Data[0].Price.Id },
},
},
new SubscriptionSchedulePhaseOptions
{
Items = new List<SubscriptionSchedulePhaseItemOptions>
{
new SubscriptionSchedulePhaseItemOptions { Price = newSubscriptionPriceId },
},
},
},
};
await service.UpdateAsync(schedule.Id, updateOptions);`
this is my code
I think that that means you need to include the start date of your current first phase again when you make that call
I meant the update call
Because that is the one you got the start date error from right?
Yes, I assigned value to start date in the first phase in update call
var updateOptions = new SubscriptionScheduleUpdateOptions
{
Phases = new List<SubscriptionSchedulePhaseOptions>
{
new SubscriptionSchedulePhaseOptions
{
Iterations = 1,
StartDate = space.NextPaymentDate,
Items = new List<SubscriptionSchedulePhaseItemOptions>
{
new SubscriptionSchedulePhaseItemOptions { Price = oldSubscription.Items.Data[0].Price.Id },
},
},
new SubscriptionSchedulePhaseOptions
{
Items = new List<SubscriptionSchedulePhaseItemOptions>
{
new SubscriptionSchedulePhaseItemOptions { Price = newSubscriptionPriceId },
},
},
},
};
You are getting that error because the create call is also getting run again
And you can't create a schedule on a subscription that already has a schedule
I don't call create once more time
I only call that one time to create Schedule with FromSubscription
I mean like you running your code twice
Like it is in your code once but if it is run twice then the API will try to create that schedule again and that is what this error was
I am making call from front end only one time
Ok, I will now try to clear cache and try again
I cleared cache
Created new user
And it still giving me that error
Can you print out the request ID after you get that error and send it here? https://stripe.com/docs/api/request_ids
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
The second one, thank you
So the error that I see on that request is "You can not modify the start date of the current phase"
Basically, when you create that schedule with the first call, the schedule will have one phase. You need to copy that exact timestamp and use it as the start_date of the first phase in your next call
This is the last record I see in logs in Stripe dashboard
yeah, now Im getting this error
Right, which is why I asked you to print out the ID with the method from the doc. Grabbing the latest log line might not get the right request ID. It is fine to go through your dashboard logs but you need to make sure that it is the right request
so how can I fix that ?
var updateOptions = new SubscriptionScheduleUpdateOptions { Phases = new List<SubscriptionSchedulePhaseOptions> { new SubscriptionSchedulePhaseOptions { Iterations = 1, StartDate = space.NextPaymentDate, Items = new List<SubscriptionSchedulePhaseItemOptions> { new SubscriptionSchedulePhaseItemOptions { Price = oldSubscription.Items.Data[0].Price.Id }, }, }, new SubscriptionSchedulePhaseOptions { Items = new List<SubscriptionSchedulePhaseItemOptions> { new SubscriptionSchedulePhaseItemOptions { Price = newSubscriptionPriceId }, }, }, }, };
this is my current version of the code
Instead of StartDate = space.NextPaymentDate use the start date of the first phase on the subscription schedule that you just created
That will fix the error from req_SxZb7YDHCTHcTN
StartDate = schedule.CurrentPhase.StartDate ?
Yep I think that should work
where schedule is
SubscriptionScheduleCreateOptions createOptions = new()
{
FromSubscription = oldSubscription.Id,
};
ok
Yep yep the schedule from that create call
Gosh
Thanks God
Thank you a lot ))
If I could rate your support I would rate 10000/10
It works fine now, thanks once more time
Woohoo! Glad that worked! Thanks for hanging in there with me as well