Issues previewing prorations

273 views
Skip to first unread message

Kyle Fox

unread,
May 30, 2017, 5:03:53 PM5/30/17
to Stripe API Discussion
I have run into issues calculating prorations for preview invoices for Plan changes that leads me to believe either (a) I'm doing something wrong, or (b) documentation should be improved.

The Previewing prorations documentation explains that prorations should be calculated like so:

# Calculate the proration cost:
current_prorations = invoice.lines.data.select { |ii| ii.period.start == proration_date }
cost = 0
current_prorations.each do |p|
  cost += p.amount
end

However, I have discovered that occasionally the period.start attribute of the preview invoice line items are a few seconds apart.

This occurs even when passing subscription_proration_date to Stripe::Invoice.upcoming().

As a result, the code snippet above (provided by Stripe) occasionally calculates the proration amount incorrectly.

Here's an example from my app (ignore the ugly/debug UI 😊). Each of these screenshots is generated by the exact same code. Sometimes it shows the correct amount, and if I repeatedly refresh the page, it sometimes shows the incorrect amount:
Furthermore — the code snippet above does not account for discounts or account balances. All of this combined means it's quite laborious to calculate the actual amount a customer will be billed — particularly when, as in my case, an invoice is immediately created after the plan change.

It would be nice if:
  • The code snippet in the documentation accounted for this scenario (i.e. allowed for a few seconds of variance in line items)
  • Better: the API returned consistent results 😊
  • Even better: the API allowed me to pass a flag specifying that I'm going to immediately generate an invoice. The resulting Invoice would then calculate the prorations and factor in discounts & account balance for me so that invoice.amount_due actually reflects what the invoice amount will be.
Best,
Kyle

Andrew Nelder

unread,
May 30, 2017, 7:36:19 PM5/30/17
to Stripe API Discussion
Hey Kyle,

Not to worry!

You're doing it "correctly" in that, you're doing what we recommend.  Furthermore, you're also correct in that I think our documentation on this could be improved!

There is a bug here, in that we should be respecting the value passed to the proration timestamp and never wavering from it.  We're currently not doing that on the Upcoming Invoice [1] API Endpoint and that's what is causing your issue.  There is a workaround though (in most cases).

Basically when you're doing this proration calculation, it's possible that those invoice items might be created a few seconds into the future (both potentially different timestamps).

They'll almost always be within within 15-30 seconds into the future though, so you could adjust that loop to account for a 15-30 second buffer after the timestamp you passed to get the correct calculations.  Alternatively, you can use a current timestamp buffered with 15-30 seconds in your initial request.  In most cases, these are viable solutions that will get you up and running; however, there is a use case where these solutions are inadequate and that's if you plan on pro-rating into the past and the *actual* proration calculation (made when updating the Subscription) was based on a completely different timestamp.  It's possible your numbers will be close but not exact.

Does that make sense?

Cheers,
Andrew

[1] https://stripe.com/docs/api#upcoming_invoice

--
You received this message because you are subscribed to the Google Groups "Stripe API Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss+unsubscribe@lists.stripe.com.
To post to this group, send email to api-d...@lists.stripe.com.
Visit this group at https://groups.google.com/a/lists.stripe.com/group/api-discuss/.

Kyle Fox

unread,
Jun 13, 2017, 3:08:40 PM6/13/17
to Stripe API Discussion
Thanks Andrew. It does make sense. I suppose I'll hack a workaround until that bug is fixed.

As another suggestion - it would be nice if the Upcoming Invoice API accepted a parameter indicating that an invoice will be immediately generated (manually) after making the change.

As you know, Stripe applies any prorations to the next invoice. So the preview invoice actually shows the prorations plus the subscription fee for the next billing period.

In my app, I manually generate an invoice after making the subscription change. It would be nice if I could say to the Preview API "Hey, I'm going to immediately invoice this subscription change, so don't add next billing cycle's charges."

Does that make sense?

Thanks,
Kyle.

To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss...@lists.stripe.com.

Kyle Fox

unread,
Jun 13, 2017, 4:41:38 PM6/13/17
to Stripe API Discussion
Just a follow up — here's a better method for finding current invoice items that doesn't require using a 15-30 second buffer:

# Select invoice items that apply to the current billing period only, i.e. ignore items from next invoice.
current_invoice_items = invoice.lines.select { |ii| ii.period.start < invoice.period_end }

Similarly, if you only want current prorations:

current_proration_items = invoice.lines.select { |ii| ii.proration? && ii.period.start < invoice.period_end }

Therefore, to calculate the net amount owing:

current_invoice_items.sum(&:amount)

and the final amount the customer will be charged (taking account balance into consideration):

current_invoice_items.sum(&:amount) + invoice.starting_balance
Reply all
Reply to author
Forward
0 new messages