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