skip to Main Content

I’m using stripe for payment in my react and nodejs app. The scenario is like this:

Suppose a customer buys 1 quantity of my plan on Oct 1 (my plans have quantities).

Now, on 15 Oct, the customer decides to switch from 1 quantity to 5 quantities. Now I want to charge the customer for the new 5 quantities right now (since customer has already paid for 1). Update the subscription to prev+new quantity, i.e, 1+5=6 quantity.

Now I want the subscription to count 6 quantities and go for the remaining days as 6 quantity. Next month, the plan automatically starts with 6 quantity for the customer

What I have tried is to update the subscription like this:

const updateSubscriptionFunc = (subscriptionId, newTotalQuantity) => {
    return new Promise(async (resolve, reject) => {
        try {
            console.log("entered in update subascription", subscriptionId, newTotalQuantity)
            let subscription = await stripe.subscriptions.retrieve(
                subscriptionId
            );
            // console.log(subscription.items.data)
            // console.log("subscriptionitem id",subscription.items.data[0].id)
            const subscriptionItem = await stripe.subscriptionItems.update(
                subscription.items.data[0].id, { quantity: newTotalQuantity }
            )
            console.log("subscription item", subscriptionItem)

            subscription = await stripe.subscriptions.update(
                subscriptionId, { proration_behavior: "always_invoice" }
            );
            console.log("subscription", subscription)
            resolve()
        } catch (err) {
            reject(err)
        }
    })
}

2

Answers


  1. You’re calling a Subscription Item update for the quantity change, then a Subscription update with proration_behavior.
    This is redundant, but also, proration_behavior only applies to the call it’s in, so it’s not affecting the quantity change at all.

    Because you don’t set proration_behavior in your Subscription Item update, it’s defaulting to create_prorations for that call, which is not what you want.
    In your Subscription update, you do set proration_behavior:'always_invoice', but since there’s no quantity update in that call, there are no prorations.

    Here is what I would do (only this, no item update):

    subscription = await stripe.subscriptions.update(
       subscriptionId, { 
       items:[
          {id:subscription.items.data[0].id, quantity:newTotalQyantity}
       ],
       proration_behavior: "always_invoice" 
    });
    

    It’s my personal preference, now you could get the same result with the SubscriptionItem update (and no sub update):

    const subscriptionItem = await stripe.subscriptionItems.update(
       subscription.items.data[0].id, {
       quantity:newTotalQuantity,
       proration_behavior:'always_invoice'
    });
    

    I prefer making all changes at Subscription-level and not at SubscriptionItem-level, because I find it much easier to keep control over, and to troubleshoot if something goes wrong.

    This will send an Invoice right then for the prorations generated from the update, but keep your Subscription billing at the same date.

    Login or Signup to reply.
  2. your code looks good to me, and this is exactly what Stripe document says about updating a subscription item directly.

    You can set proration_behavior to always_invoice if you want to invoice the customer immediately, or create_prorations to include the prorations in the upcoming invoice.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search