Normally when a customer upgrades their subscription Stripe will tack on a proration amount to their next invoice. They'll be able to use the upgraded service without actually paying for it. What if you want to prorate the customer's subscription right away? That is, you don't want to wait until the next billing cycle to start, you want to collect the proration amount from them immediately.
With Stripe's new ability to preview subscription updates this becomes pretty easy. First, get the preview amount like in the previous post:
upcoming = Stripe::Invoice.upcoming( customer: customer_id, subscription: subscription_id, subscription_plan: 'monthly_25' ) proration_amount = upcoming.lines.last.amount
Now that you have the amount, you can easily create a new invoice, immediately pay it, and upgrade the customer without proration:
customer = Stripe::Customer.retrieve(customer_id) sub = customer.subscriptions.retrieve(subscription_id) item = Stripe::InvoiceItem.create( customer: customer_id, subscription: subscription_id, amount: proration_amount ) invoice = Stripe::Invoice.create( customer: customer_id, subscription: subscription_id ) invoice = invoice.pay if invoice.paid sub.plan = 'monthly_25' sub.prorate = false sub.save else invoice.closed = true invoice.save end
The logic around the
paid attribute above is important, because if the payment fails for some reason you don't want to upgrade the subscription, and you also don't want that invoice to retry automatically. This logic ensures that a customer who's payment fails won't get extra free services while Stripe's automatic retries are happening.
Get a free five part email course all about Stripe and Rails, including the first three chapters of Mastering Modern Payments.No spam. Unsubscribe at any time.