Canovice
Canovice

Reputation: 10441

In Stripe API (node js), how to upgrade subscription without billing until end of the current billing period

We have two subscription options / prices on our website, one for $20 per month, and one for $50 per 3 months. We want users to be able to toggle between options. We have created the following route for this:

router.post('/update_payment_schedule', async function (req, res) {
    try {
        // grab userId and request body
        const { subscription, priceKey } = req.body;

        // items: [{ price: stripePriceKeys[priceKey] }],
        const newSubscription = await stripe.subscriptions.update(subscription.id, {
            cancel_at_period_end: false,
            proration_behavior: 'create_prorations',
            items: [{
                id: subscription.items.data[0].id,
                price: stripePriceKeys[priceKey]
            }]
        });

        console.log('success? SUCCESS!!!');
        return res.status(200).json({ newSubscription });
    } catch (err) {
        Sentry.captureException(err);
        console.log('err: ', err);
        return res.status(500).json({ statusCode: 500, message: err.message });
    }
});

According to https://stripe.com/docs/billing/subscriptions/upgrade-downgrade - "If the prices have different billing periods, the new price is billed at the new interval, starting on the day of the change. For example, switching a customer from one monthly subscription to another does not change the billing dates. However, switching a customer from a monthly subscription to a yearly subscription moves the billing date to the date of the switch." After testing this endpoint, that is exactly what happens.

We (currently) have a strong preference towards not billing at the new price until the end of the current billing period. So, if a user is 14 days into a 1 month at $20 subscription, and they switch to $50 for 3 months, they do not get billed $50 until the end of the current 1 month.

Is this possible?

Upvotes: 0

Views: 573

Answers (2)

Canovice
Canovice

Reputation: 10441

const newSubscription = await stripe.subscriptions.update(subscription.id, {
    trial_end: subscription.current_period_end,
    proration_behavior: 'none',
    items: [{
        id: subscription.items.data[0].id, // this is a subscription item Id
        price: stripePriceKeys[priceKey]
    }]
});

Not sure if there are any issues with the above solution, motivated by bismark's comment, but this is what we have tentatively settled on.

Upvotes: 0

bismarck
bismarck

Reputation: 712

The easiest way to accomplish this is to use a trial period to move the billing cycle anchor here to your preferred date (in your example, the 1st of the following month). You can do that via setting trial_end on your update request.

Upvotes: 1

Related Questions