Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to issue a refund and clear the account balance when downgrading a Stripe plan
# Michael Bianco <mike@suitesync.io>
# Description: Issue a refund and clear the account balance when downgrading a Stripe plan
# Usage:
#
# export STRIPE_KEY=sk_test
# gem install stripe
# ruby stripe_customized_plan_changes.rb
require 'stripe'
Stripe.api_key = ENV['STRIPE_KEY']
uid = Time.now.to_i
high_plan = Stripe::Plan.create(
amount: 200_00,
interval: 'month',
currency: 'usd',
name: 'A High Plan',
id: "high_#{uid}",
)
low_plan = Stripe::Plan.create(
amount: 100_00,
interval: 'month',
currency: 'usd',
name: 'A Low Plan',
id: "low_#{uid}",
)
# There's a bunch more options available to customize how subscriptions are created:
# https://gist.github.com/iloveitaly/c07975fe902a1c6259558c181d8602d4
customer = Stripe::Customer.create(email: "customer+#{uid}@example.com")
customer.sources.create(card: 'tok_visa')
subscription = customer.subscriptions.create(plan: high_plan.id)
# NOTE in this case the initial balance will always be empty; in the real-world the
# customer could have a balance from another subscription, etc
initial_account_balance = customer.account_balance * -1
# switch to a lower-cost plan
subscription.plan = low_plan.id
subscription.save
# normally an invoice would only be created at the beginning of the next billing cycle (next month)
# here we force an invoice to be created in order to simulate the beginning of the next billing cycle
invoice = Stripe::Invoice.create(customer: customer.id, subscription: subscription.id)
invoice.pay
customer.refresh
# Issue a refund for the unused time and clear the customer balance
# the unused time on the original payment for the higher-cost plan is pushed into the account balance
current_account_balance = customer.account_balance * -1
prorated_unused_time = current_account_balance - initial_account_balance
# find the previous invoice created for this subscription so we can issue a refund
last_invoice = customer.
invoices.
data.
reject { |i| i.id == invoice.id || i.subscription != subscription.id }.
max_by { |i| i.date }
charge = Stripe::Charge.retrieve(last_invoice.charge)
refund = charge.refunds.create(amount: prorated_unused_time)
# clear the account balance
customer.account_balance = initial_account_balance * -1
customer.save
puts "Customer: #{customer.id}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment