How to issue a refund and clear the account balance when downgrading a Stripe plan
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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