Stripe - Upgrading a subscription synchronously (immediately charge for a proration without webhooks)
Tags: ruby, rails, stripe, subscriptions
Published: 2019-05-03 13:13:19

---
title: Stripe - Upgrading a subscription synchronously (immediately charge for a proration without webhooks)
published: true
description: 
tags: ruby, rails, stripe, subscriptions
---

I was doing some research on how upgrading subscriptions works on [Stripe](https://stripe.com/). Stripe's default system is to charge the customer for the proration cost in their next invoice, along with the fee for the upcoming billing cycle ([docs](https://stripe.com/docs/billing/subscriptions/prorations)).

For example, if I upgraded my subscription to some service from the standard plan ($5/month) to the premium plan ($10/month) at the midpoint of my billing cycle, my invoice on the first of the next month would be something like $12.50. $10 for the charge for the next month, $5 for the premium plan portion I started using half a month ago, and $2.50 refund for the unused portion of the standard plan after the upgrade.

But this billing system could be confusing for customers, and I wanted to see if there was a way to charge customers immediately for the proration ($2.50 in our example above). There was no `prorate_now` flag or anything, but it could be done manually. Here are the high level steps and a gist to walk you through it. The code will most likely require customization for your use case.

Note: I used Stripe's test environment for this as the docs suggest.

# Prerequisites
* Add the `stripe` gem to your Rails app by adding the line below to your `Gemfile` and running `bundle`.

```ruby
gem 'stripe'
```

* Assign your Stripe publishable and secret keys to environment variables, and create `config/initializers/stripe.rb` (you can get your keys from the Stripe dashboard):

```ruby
Rails.configuration.stripe = {
  publishable_key: ENV['STRIPE_PUBLISHABLE_KEY'],
  secret_key:      ENV['STRIPE_SECRET_KEY']
  }
  
Stripe.api_key = Rails.configuration.stripe[:secret_key]
```

* In the Stripe test environment, you need to create at least one [product](https://stripe.com/docs/api/service_products/create), two [plans](https://stripe.com/docs/api/plans/create), and a [customer](acreate) who is subscribed to the lower tier plan. These can be created from the Stripe dashboard, or by sending requests to their API; I've linked the relevant docs for making API requests in the previous sentence.

* The customer also needs to have a credit card so they can be charged (not a real one, but a mock card for testing purposes). If you created the customer via the API, a mock card was probably auto-created for you. You can make sure of this by going to the dashboard and checking that customer's details.

# High level steps
1. Create a preview invoice, which simulates what a customer's next invoice would look like if they upgraded now
2. Calculate the proration cost from the preview invoice
3. Create a new one-off invoice with that amount
4. Charge the customer immediately
5. Check if the invoice has been paid, then upgrade the customer with proration disabled (otherwise, they will be charged twice for the upgrade!)

Note: Creating a preview invoice does not create an actual invoice, so you don't have to worry about billing the customer accidentally (explained in the [docs](https://stripe.com/docs/api/invoices/upcoming)).

# Gist as a proof of concept
The test below follows the steps I described above. The customer is subscribed to my cheaper plan, which costs JPY 100 per month, but they want to upgrade to the plan that costs JPY 1,000, so we charge them for the difference before upgrading them. I also have a `User` model and a `Plan` model in my Rails app (which correspond to customer and plan respectively in Stripe) that I occasionally refer to in my test.

And now for the actual code:
{% gist https://gist.github.com/risafj/c5b53e0d4ecc6e4c453d7c4b6887b559 %}


I will also link the relevant parts of the Stripe docs, because I personally found it a chore to sift through the detailed but scattered docs.

Read about...
* creating a preview invoice and calculating the proration cost [here](https://stripe.com/docs/billing/subscriptions/prorations#previewing-proration)
* creating an one-off invoice [here] (https://stripe.com/docs/billing/invoices/one-off)
* synchronously paying an invoice [here](https://stripe.com/docs/api/invoices/pay)
* checking if an invoice was paid successfully [here](https://stripe.com/docs/api/invoices/object#invoice_object-paid)
* upgrading a customer with proration disabled [here](https://stripe.com/docs/billing/subscriptions/upgrading-downgrading)

Please let me know in the comments if any part of the code is unclear, or if there are alternative ways to do this. Thank you!