Skip to content

Instantly share code, notes, and snippets.

@risafj
Last active September 6, 2019 00:19

Revisions

  1. risafj revised this gist Sep 6, 2019. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions stripe_test.rb
    Original file line number Diff line number Diff line change
    @@ -83,11 +83,11 @@ class StripeTest < ActiveSupport::TestCase
    )

    # Plan.second is the upgraded plan - we're making sure the customer was upgraded.
    assert Plan.second.stripe_plan_id = Stripe::Customer.retrieve(User.first.stripe_customer_id).subscriptions.data[0].items.data[0].plan.id
    assert_equal Plan.second.stripe_plan_id, Stripe::Customer.retrieve(User.first.stripe_customer_id).subscriptions.data[0].items.data[0].plan.id

    # Check that the billing cycle hasn't changed.
    # Note: This doesn't work if the subscription period changed, e.g. if a monthly sub was changed to an annual one.
    assert current_period_end_date = customer.subscriptions.data.first.current_period_end
    assert_equal current_period_end_date, customer.subscriptions.data.first.current_period_end

    # Check that the next invoice just charges for the upcoming month (no proration).
    assert_equal 1000, Stripe::Invoice.upcoming(customer: customer).amount_due
  2. risafj revised this gist Sep 6, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion stripe_test.rb
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@ class StripeTest < ActiveSupport::TestCase
    )

    # Making sure they're on the cheap plan.
    assert Plan.first.stripe_plan_id = Stripe::Customer.retrieve(User.first.stripe_customer_id).subscriptions.data[0].items.data[0].plan.id
    assert_equal Plan.first.stripe_plan_id, Stripe::Customer.retrieve(User.first.stripe_customer_id).subscriptions.data[0].items.data[0].plan.id

    # To get the proration amount, simulate what happens if this user upgraded now.
    invoice_items = [{
  3. risafj revised this gist Sep 5, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion stripe_test.rb
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@ class StripeTest < ActiveSupport::TestCase
    proration_date = Time.now.to_i
    customer = Stripe::Customer.retrieve(User.first.stripe_customer_id)
    subscription = customer.subscriptions.data.first
    current_period_end_date = customer.subscriptions.data.first.current_period_end
    current_period_end_date = subscription.current_period_end

    # Do this to ensure the user is actually on the cheap plan (Plan.first).
    # Otherwise, you won't be able to run this test multiple times.
  4. risafj renamed this gist May 3, 2019. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. risafj created this gist May 3, 2019.
    95 changes: 95 additions & 0 deletions stripe_test
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,95 @@
    require 'test_helper'

    class StripeTest < ActiveSupport::TestCase

    test 'should bill customer who wants to upgrade and apply upgrade once invoice is paid' do
    proration_date = Time.now.to_i
    customer = Stripe::Customer.retrieve(User.first.stripe_customer_id)
    subscription = customer.subscriptions.data.first
    current_period_end_date = customer.subscriptions.data.first.current_period_end

    # Do this to ensure the user is actually on the cheap plan (Plan.first).
    # Otherwise, you won't be able to run this test multiple times.
    Stripe::Subscription.update(
    subscription.id,
    cancel_at_period_end: false,
    prorate: false,
    items: [
    {
    id: subscription.items.data[0].id,
    plan: Plan.first.stripe_plan_id
    }
    ]
    )

    # Making sure they're on the cheap plan.
    assert Plan.first.stripe_plan_id = Stripe::Customer.retrieve(User.first.stripe_customer_id).subscriptions.data[0].items.data[0].plan.id

    # To get the proration amount, simulate what happens if this user upgraded now.
    invoice_items = [{
    id: subscription.items.data[0].id, # This returns the subscription item id, which is different from the subscription id.
    plan: Plan.second.stripe_plan_id
    }]

    invoice = Stripe::Invoice.upcoming(
    customer: customer.id,
    subscription: subscription.id,
    subscription_items: invoice_items,
    subscription_proration_date: proration_date
    )

    # invoice.lines.data.count returns 3.
    # First item is '-100' - i.e. the amount for the days on cheap plan that wasn't used.
    # Second item is '999' - i.e. the amount that needs to be paid for the remainder of the month for the upgraded plan.
    # Third item is '1000' - i.e. the normal amount for the next billing cycle.

    # Get all items with proration date as the start date.
    # (Excluding the third item, whose start date is the beginning of the next billing cycle.)
    current_prorations = invoice.lines.data.select { |ii| ii.period.start == proration_date }
    proration_amount = current_prorations.each.pluck(:amount).inject(:+)

    # Proration amount should be within this range because the cheap plan is JPY 100, the upgraded plan is JPY 1000.
    assert_operator proration_amount, :<=, 900
    assert_operator proration_amount, :>=, 0

    # Create an one-off invoice item, and then an actual invoice.
    Stripe::InvoiceItem.create(
    customer: customer.id,
    amount: proration_amount,
    currency: 'jpy',
    description: 'proration cost'
    )

    proration_invoice = Stripe::Invoice.create(
    customer: customer.id,
    auto_advance: false # If set to 'true', this draft is auto-finalized after ~1 hour.
    )

    # Finalization just means the invoice is ready to be paid (not actually paid yet).
    Stripe::Invoice.finalize_invoice(proration_invoice.id)
    assert Stripe::Invoice.pay(proration_invoice.id).paid?

    # If the invoice was paid successfully, upgrade the user with proration disabled.
    Stripe::Subscription.update(
    subscription.id,
    cancel_at_period_end: false,
    prorate: false,
    items: [
    {
    id: subscription.items.data[0].id,
    plan: Plan.second.stripe_plan_id
    }
    ]
    )

    # Plan.second is the upgraded plan - we're making sure the customer was upgraded.
    assert Plan.second.stripe_plan_id = Stripe::Customer.retrieve(User.first.stripe_customer_id).subscriptions.data[0].items.data[0].plan.id

    # Check that the billing cycle hasn't changed.
    # Note: This doesn't work if the subscription period changed, e.g. if a monthly sub was changed to an annual one.
    assert current_period_end_date = customer.subscriptions.data.first.current_period_end

    # Check that the next invoice just charges for the upcoming month (no proration).
    assert_equal 1000, Stripe::Invoice.upcoming(customer: customer).amount_due
    end
    end