#lee_unexpected

1 messages ยท Page 1 of 1 (latest)

sacred kayakBOT
#

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

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

desert raft
#

Hi there - do you have a specific example that you can point to?

jade kestrel
#

Meaning like a subscription that is in this state?

desert raft
#

Yes please

jade kestrel
#

One moment please ๐Ÿ˜„

#

I believe this one is a good example. I can find others if necessary sub_1OFTrpIPXEWXQ8DiAyhAecKS

#

If you inspect the subscription you'll see it has a schedule still and the schedule is active but the final phase start date has passed I believe

#

We use schedules to downgrade plans at the end of the current billing period but we periodically encounter these situations where the user wants to upgrade again and can't because the schedule is still attached

desert raft
#

okay give me a few minutes to step through what's happening with the Subscription/Schedule

jade kestrel
#

Here's a snippet from our codebase for how we generate these downgrade schedules if it helps:

     schedule = Stripe::SubscriptionSchedule.create(
        { from_subscription: subscription.remote_subscription_id },
        Billing::Stripe.creds
      )

      first_phase = schedule.phases.first
      Stripe::SubscriptionSchedule.update(
        schedule.id,
        {
          metadata: { user_requested: true },
          phases: [
            {
              start_date: first_phase.start_date,
              end_date: first_phase.end_date,
              trial_end: first_phase.trial_end,
              items: [
                { price: first_phase.items.first.price, quantity: 1 }
              ]
            },
            {
              items: [
                { price: new_price.stripe_price_id, quantity: 1 }
              ],
              iterations: 1
            }
          ]
        },
        Billing::Stripe.creds
      )
desert raft
#

That's okay - I have logs of what your requests look like

#

which are in language-agnostic format and easier to read on my end

jade kestrel
#

Basically use the subscription schedule create from subscription api to attach a new schedule to a subscription. Then we add a phase with no start or end date for price they are changing to

#

Looking at the schedule it actually looks like that phase might be getting assigned an end date that matches the end of the next billing cycle

#

So the schedule hasn't technically ended yet.

desert raft
#

Exactly. The last update on sub_sched_1Sb5RvIPXEWXQ8DiCYLUXtNP is this request: https://dashboard.stripe.com/acct_1MHtazIPXEWXQ8Di/logs/req_EfjHVC3b4RN9iE

This request defines two phases on the Schedule, the first starts at 2025-12-05 00:00:00 and ends at
2026-01-05 00:00:00 (times UTC), and then a second phase which lasts for one iteration of price_1OhnfJIPXEWXQ8Di4grcrkMp, which is one month

#

It seems like you think you're only adding one phase to the schedule

jade kestrel
#

Note the post body when we update that schedule to add the second phase:

{
  "metadata": {
    "user_requested": "true"
  },
  "phases": {
    "0": {
      "end_date": "1767571200",
      "items": {
        "0": {
          "price": "price_1OhnjcIPXEWXQ8DivQFrCFpN",
          "quantity": "1"
        }
      },
      "start_date": "1764892800"
    },
    "1": {
      "items": {
        "0": {
          "price": "price_1OhnfJIPXEWXQ8Di4grcrkMp",
          "quantity": "1"
        }
      },
      "iterations": "1"
    }
  }
}
desert raft
#

maybe a better question is what do you want to happen when you make this update?

jade kestrel
#

We don't specify a start or end date for that phase. My expectation would be that it would automatically be released as soon as that phase begins. ie make the change to the sub and immediately release the schedule. Do I just need to specify a brief window for start/end date there and make sure the subscription schedule is set to release at the end?

desert raft
#

I don't completely follow - do you mean the second phase, where you pass "iterations: 1"?

jade kestrel
#

yeah, correct. In my mind I'd want the schedule to be relased as soon as that phase starts.

#

Or maybe if that's what I want I should be specifying something differently there, eg an explicit start/end date?

desert raft
#

Okay, I think that's a misunderstanding of the nomenclature; "release" in the context of Subscription schedule means that all the phases have ended. So the release on this Subscription Schedule will happen when phase 1 is over, or on Feb 5 2026, then you'll get a webhook event.

Supplying start and end dates is roughly the same thing as using iterations - iterations is just a simpler approach because you don't have to be so precise and it is easier to avoid prorations.

#

That's to say, a Sub Schedule releasing means that there are no future updates to the subscription and all its phases are over, and then you are left with a regular Subscription

jade kestrel
#

right, so in this case. could I have set a start date of 1767571200 for the phase indexed 1 in the example above (removing iterations) and an end date of 1767571200 Or is there some minimum amount of time required for a subscription phase.

#

ie I just want to schedule the change to occur at the renewal but not have the schedule stick around after that

desert raft
#

I'm not sure what the minimum is - certainly I think you could do a very short phase, or perhaps a short phase with a 100% discount and then let the schedule release - the trouble is that that phase is going to result in an Invoice and your billing cycle anchor is going to be moved. For example, lets suppose you add a 1-hour phase on January 5 and change the price in that phase. You'll still have an Invoice for that phase, which will have a value. You could make it free, but you'd still have to live with the billing cycle anchor being moved by 1 hour, if that matters to you.

#

So the reason you don't want the schedule to exist for the final phase is something related to further updates your customers want to make?

sacred kayakBOT
jade kestrel
#

More or less. For example the upcoming invoice api and subscription update APIs don't completely work (eg you can't change or preview changes for line item updates) when you have a schedule attached to the subscription.

So if a customer performs a downgrade like we've done that subsequent billing cycle they can't make changes unless we manually release the subscription schedule.

neat fractal
#

Hi there,
I took over for my colleague who had to step away.

#

subscription update APIs don't completely work
That is expected behavior when using subscription schedules. Instead of updating the subscription directly, we recommend updating the schedule instead.
We explicitly call out how to upgrade or downgrade a subscription that is attached to a subscription schedule in our documentation.
Downgrade: https://docs.stripe.com/billing/subscriptions/subscription-schedules#downgrading-subscriptions
Upgrade: https://docs.stripe.com/billing/subscriptions/subscription-schedules#upgrading-subscriptions