#mehdi_downgrade-pending

1 messages ยท Page 1 of 1 (latest)

tawdry solarBOT
#

๐Ÿ‘‹ 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/1240703932209037322

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

tiny mica
#

mehdi_downgrade-pending

brave plover
#

Rest of the cut text :
All those updates needs to be done via pending_if_incomplete, so that the changes aren't applied until the invoice generated has been paid.

We're having difficulties implementing this logic, and we couldn't find some open source projects to see examples of how we could implement it.

tiny mica
#

@brave plover why are you doing an Invoice during a downgrade since there's nothing to pay?

brave plover
#

Nope no invoice is being done on downgrade

#

Just the next phase of the subscription schedule gets updated

tiny mica
#

then why do you use pending_if_incomplete for this? You said

What we've tried is using pending if incomplete during downgrades

brave plover
#

Oh my bad my bad, I meant 'upgrades', I apologize

tiny mica
#

totally fine

#

Okay so what is the problem exactly? Sorry those can be tough to grasp and explain so it would help if you walked me through one exact concrete example and the related issue

brave plover
#

Thank you!

So the most important requirement is that the upgrades do not get applied until the payment is done.
For that we use pending_if_incomplete in payment_behavior option.

The second requirement is that the downgrades don't get applied until the next billing cycle.

Let's say the user have the premium plan and have bought 5 of the additional storage addon, which gives him an additional 5GB of storage.
Those updates (which are upgrades) should be immediately after the payment is validated, for that, we use pending if incomplete, which work flawlessly when no schedule exist.

For the downgrade part, let's say the user updates the additional storage addon from 5 to 2GB, we create a subscription schedule or update it's second phase if it already exists, so that the user can keep the 5GB of storage until the end of his current billing cycle.

The issues starts when we try to upgrade the addon storage (subscription item) while a downgrade for it is already scheduled.
So if we continu with our example, it would be upgrading the addon to 10GB while the 2GB downgrade is scheduled.
What happen is that the user pays the upgrade, and for a brief moment (5 seconds) the change is done correctly, then it gets canceled and the user get 5GB again.

This issue doesn't happen with cards like 4242 ... which doesn't require 3d secure, but it happens with this card for example 4000002760003184, which always requires it.

tiny mica
#

okay sorry was deep in another thread, let me read!

#

The issues starts when we try to upgrade the addon storage (subscription item) while a downgrade for it is already scheduled.
yeah the pending_if_incomplete flow is really specific and limited to a small use-case. It can't work with SubscriptionSchedules.
You basically would have to cancel the SubscriptionSchedule, do your upgrade and then re-put the SubscriptionSchedule (assuming they still want to downgrade later)

brave plover
#

No worries ๐Ÿ˜… Thank you again!

tiny mica
#

that's what I would do if I were you at least

light idolBOT
median breach
#

Hello ๐Ÿ‘‹ I'm the other dev working with Mehdi on this, so what we've found out is that canceling the schedule and re-creating another one it would risk having unwanted results and incrementing the complexity of the upgrade.

What we've found is that you could do normal upgrades to a scheduled subscription (Just like you would do normally to a subscription without schedules) and it works fine, it updates the current phase and leaves the next phases with the old values, so we change them in the webhook we receive from Stripe. This works just fine with the 4242 card, which works without 3DS like Mehdi said, but it doesn't work with cards that need 3DS authentication, because of the fact that it first attaches the invoice to the subscription as latest_invoice - which we receive a webhook for, but ignore - and then once the payment is completed we receive another webhook with the items in the previous_attributes key, this is how we know we changed the items. The issue is that in this case in which we have 3DS, we receive 2 calls having different updates to the items, so it's a bit chaotic, so we were wondering if there's a scenario to treat this, or we would have to deep compare the objects and previous_attributes & metadata to know what's going on?

Thanks!

tiny mica
#

๐Ÿ‘‹ I'm sorry you did lose me completely with that paragraph. Can you try and explain in details exactly what happens with both exact API request(s) and exact Event ids and what is confusing you in those?

median breach
#

Sure, imagine that we currently have a downgrade scheduled for next month, and the user wants to do an upgrade on the same item, for whatever reason, what we'll do is:

  1. Perform a normal request to update subscription item with proration_behavior=always_invoice and payment_behavior=pending_if_incomplete to bill it immediately.

  2. Once he's billed and the invoice is paid directly, without 3DS (Because the card is already in his account, so we did 3DS when adding it), the changes get applied to the current phase of the subscription schedule (So phase 0 in the array)

  3. We receive a customer.subscription.updated webhook saying that the items were changed in the subscription, so what we do is compare previous_attribute sent in the webhook with the object send, which contains the updated data.

  4. We apply those changes to the future phases (So phase 1 in the array) and save the schedule - This way we avoid the upgrade from changing in the future phase, if we don't do this step it'll downgrade automatically to how it was.

This works fine with cards that do not require aditional actions, however, when we are using cards that need aditional actions, we're in a pickle, because we won't be able to differentiate the items in the webhook calls.

So the main question in this situation is: How can I know that I have the correct customer.subscription.updated webhook call to apply the changes in its body to the future phases? Because I think right now we're not identifying correctly the webhooks and as a result it does weird things like get paid on a upgrade but revert it back as it updates the current phase of the subscription somehow...

If I give you some webhook IDs are you able to read them? just as an example on my testing Stripe account.

rare mica
#

๐Ÿ‘‹ hopping in here since koopajah has to head out soon - give me a few minutes to catch up

#

Ah I think I hear what you're saying - you rely on the customer.subscription.updated webhook to know what change needs to be applied forward to you subscription schedule phases

median breach
#

Yup, exactly

#

I think there's a change on how subscription schedules work on update between the API version 2019 and 2024, right?

rare mica
median breach
#

Hmm, I think it might be something like that, I'll see if I can find something in there and I'll work more around how I manage the schedules, I have a feel that they are the ones giving me trouble. Thanks for the info!

rare mica
#

It may also be that you're not properly considering how schedule phases are split when the underlying subscription is updated. If you add a subscription item mid-cycle, then the schedule's current phase will be immediately split into two so that it reflects the updated state - it's only the future phases that you'd need to be sure to update with the new item

median breach
#

Yup, that's what I'm doing, I'm retrieving the schedule attached to the subscription from Stripe, changing the future phases only (So the phases whose the start date is greater than now), update the items in there, and merge it with the past phases that remain untouched. But somehow the subscription schedule's current phase is not updated when retrieving it from Stripe, it has the data before the update, so it ends up reverting the changes I think when I save the subscription schedule...

I developed the logic with the API version on 2019 and now I'm with 2024, I'm afraid it has something to do because before it worked just fine - it's also true that I didn't test it with 3DS up to now, so idk really

rare mica
#

Yeah my guess would be that you're triggering the schedule update too early and you're accidentally using the customer.subscription.updated from before the latest invoice was paid so the current phase of the schedule didn't split yet

median breach
#

Yeah... I'm working through the webhooks for this so I don't have much room here, but thanks for the info ๐Ÿ˜„ I'll see how I can figure it out via trial & error

rare mica
#

๐Ÿ‘ feel free to send over an example schedule update request if you want me to take a closer look

median breach
#

Just FYI in case you need it in the future, I disabled all the updates in my webhook and all, Stripe does not update the current phase of subscription schedules when aditional_actions are required from the user to process the payment.

The payment intent goes through and the invoice is paid, but the change is applied until the next billing cycle, meanwhile if I do the exact same change with the exact same code with a card that goes through without aditional_actions, it'll apply the change to the current phase.

It's weird but I think I'll have to apply the change manually to the current phase to split it and apply the change and it should be good for now.

#

The prices on top with the current cycle and what's in it, and next invoice on the bottom with what's in it. This is without touching the schedule from my end, just processing the upgrade and that's it

#

And if we look at the bigger picture, we'll have a schedule that goes from 24 to 17 (which was the previous value), and the next invoice will bill 25 addons ๐Ÿ˜‚

rare mica
#

It's definitely odd that the pending update being applied doesn't split the current phase of the subscription schedule

median breach
#

Yup, my code was assuming it did, and so did I

rare mica
#

Yeah I'll flag this to the team to take a closer look, but in the mean time you'll likely need to build that into your logic ๐Ÿ˜ฆ

median breach
#

Yeah already did, it's working fine now ๐Ÿ˜„

#

Thanks for your amazing support @rare mica and @tiny mica !

rare mica
#

๐Ÿ‘