Skip to content

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
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.