#NEWJOSSY

1 messages · Page 1 of 1 (latest)

white wyvernBOT
olive rivet
#

Hi! Let me help you with this.

hardy juniper
#

Hello

olive rivet
#

What do you want to change exactly?

hardy juniper
#

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

olive rivet
hardy juniper
#

What is iterations in this schedule ?

olive rivet
#

If your price is monthly, iterations: 1 is one month.

hardy juniper
#

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?

white wyvernBOT
olive rivet
#

Yes. You can create a Subscription Schedule with 1 phase, 1 price (the annual one), starting at the end of the current billing period.

hardy juniper
#

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

olive rivet
#

But you specify the Phase here. Or did you mean "iterations"?

hardy juniper
#

I think I make it work

#

made*

#

will it automatically cancel standart month subscription ?

olive rivet
#

It seems like there're 2 subscriptions now

olive rivet
#

So it won't cancel it

hardy juniper
#

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?

dusty fable
#

Yes that will create a schedule that works with that existing subscription

hardy juniper
#

Ok, thank you a lot guys 🙂

#

It's actually not working ((

dusty fable
#

Thank you for confirming. Can you send me the ID of that schedule/subscription?

hardy juniper
#

One second

#

PriceId for Standard annual subscription - price_1MLnz0KwhjmH7xPxs8ZFMtRy
SubscriptionId of Standard monthly subscription - sub_1MsnXFKwhjmH7xPxJRJ3gA2c

#

customerId - cus_Ne5f0kdO5OV3xe

dusty fable
#

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

hardy juniper
#

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

dusty fable
#

Sorry and then the second call would be updating the schedule from the first call

hardy juniper
#

`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 ?

dusty fable
#

Looks right enough to try to me

hardy juniper
#

It does not work either

#

I cannot specify start date with FromSubscription

#

And on Update startDate required but SubscriptionScheduleUpdateOptions has not such property

dusty fable
#

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

#

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

hardy juniper
#

How complete code would look like, I just can't understand

dusty fable
#

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?

hardy juniper
#

The first price in update is the price of old subscription? Monthly Standard? And second one it the price of annual subscription ?

dusty fable
#

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

hardy juniper
#

Okay and the first call is for creating schedule and it is ?

SubscriptionScheduleCreateOptions createOptions = new() { FromSubscription = oldSubscriptionId, };

dusty fable
#

Yep

hardy juniper
#

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

dusty fable
#

I think that that means you need to include the start date of your current first phase again when you make that call

hardy juniper
dusty fable
#

I meant the update call

#

Because that is the one you got the start date error from right?

hardy juniper
#

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 },
},
},
},
};

dusty fable
#

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

hardy juniper
#

I don't call create once more time

#

I only call that one time to create Schedule with FromSubscription

dusty fable
#

I mean like you running your code twice

dusty fable
# hardy juniper

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

hardy juniper
#

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

dusty fable
hardy juniper
#

0HMPKAA2UPHNN:0000001B this ?

#

req_SxZb7YDHCTHcTN or this >

#

?

dusty fable
#

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

hardy juniper
#

This is the last record I see in logs in Stripe dashboard

#

yeah, now Im getting this error

dusty fable
#

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

hardy juniper
#

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

dusty fable
#

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

hardy juniper
#

StartDate = schedule.CurrentPhase.StartDate ?

dusty fable
#

Yep I think that should work

hardy juniper
#

where schedule is
SubscriptionScheduleCreateOptions createOptions = new()
{
FromSubscription = oldSubscription.Id,
};

#

ok

dusty fable
#

Yep yep the schedule from that create call

hardy juniper
#

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

dusty fable
#

Woohoo! Glad that worked! Thanks for hanging in there with me as well