Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iloveitaly/2eef862d999ee7b0cf6a2cc12ca6586d to your computer and use it in GitHub Desktop.
Save iloveitaly/2eef862d999ee7b0cf6a2cc12ca6586d to your computer and use it in GitHub Desktop.
Example of using Stripe Subscriptions to handle usage based billing for recurring payments
# Mike Bianco <>
# Description: Example of using Stripe's subscription billing to add usage based billing
# information to the customer's recurring invoice
require 'stripe'
require 'sinatra'
Stripe.api_key = ENV['STRIPE_KEY']
# This example uses sinatra to listen for webhooks. You can easily use rails, or any other framework/language.
# Listen to Stripe events using webhooks
# -
# -
# In order to test this example out, you'll need to bind Stripe's webhooks to this local server:
# 1. Create a server to forward requests locally: `ngrok http 8081`
# 2. Setup the resulting ngrok domain in Stripe:
# 3. Set your Stripe key: `export STRIPE_KEY=sk_test`
# 4. Run `ruby stripe_usage_based_billing_with_subscriptions.rb` to start the local server
# 5. Visit http://localhost:8081/example to trigger an example
# set port & host explicitly to match ngrok so Stripe can send us webhooks
set :port, 8081
set :bind, 'localhost'
def generate_example_plan
plan = (Stripe::Plan.retrieve('example-usage-plan') rescue nil)
return plan if plan
id: 'example-usage-plan',
name: 'Example Usage Based Billing Plan',
amount: 10_00,
interval: 'month',
currency: 'usd',
post "/" do
event_json = JSON.parse(
# invoice.created is fired an hour or so before the invoice is paid
if event_json['type'] == 'invoice.created'
invoice_id = event_json['data']['object']['id']
customer_id = event_json['data']['object']['customer']
# initial invoices are always paid immediately; we only want to run usage based billing
# after the initial billing period
is_invoice_paid = event_json['data']['object']['paid']
if is_invoice_paid
status 200
puts "adding invoice item to invoice: #{invoice_id}"
# the line item can be mapped to a NetSuite item based on the name, or a direct
# reference to a NetSuite item:
invoice_item = Stripe::InvoiceItem.create(
customer: customer_id,
invoice: invoice_id,
amount: (rand * 100).round,
currency: 'usd',
description: 'Usage Based Billing',
# add custom information about the charge
# metadata: { }
status 200
get '/example' do
plan = generate_example_plan
customer = Stripe::Customer.create
customer.sources.create(source: 'tok_visa')
trial_end: + 5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment