Functional Weave
Code in Rust

subscriptions.proration@1.0.0

README.md

2,225 bytes · view raw

# subscriptions.proration

What Stripe calls "create prorations": when a customer changes plan part of the
way through a billing period, they get a credit for the time they have paid
for and will no longer use on the old plan, and a charge for the rest of the
period on the new one. Stripe's own example: moving from a 10 USD to a 20 USD
monthly plan halfway through is a 5 USD credit and a 10 USD charge, 5 USD net.

    credit = -(oldPrice x remainingDays / totalDays)
    charge =   newPrice x remainingDays / totalDays

The two lines are returned separately because they are printed separately
("Unused time on Basic", "Remaining time on Pro"), and each is rounded once, by
the `mode` the caller chooses, using math.round-div on the exact fraction. The
mode applies to each line's size, so `up` rounds the credit and the charge
both away from zero. `net` is the sum of the two rounded lines, which is what
the invoice will add up to; it is not re-rounded from the exact difference.

Days, not seconds. Stripe prorates to the second by default; this capability
works on calendar dates, which is what most invoices print and what can be
reproduced by hand. The period is half-open: `periodStart` is its first day
and `periodEnd` is the first day of the next period (Stripe's
`current_period_end`), so a January period is 2026-01-01 to 2026-02-01, 31
days. A change on `periodStart` re-prices the whole period, and a change on
`periodEnd` re-prices nothing (both lines are zero).

The prices are full-period prices as billed, after any recurring discount -
Stripe likewise prorates from the discounted price. If the old and new plans
have different intervals (monthly to annual) this is the wrong tool: that
change usually starts a new billing period instead, so it is a credit for the
old plan's unused time (finance.proration) and a full charge for the new one.

Errors: a period whose end is not after its start, a change date outside the
period, prices in different currencies, and an unknown rounding mode.
finance.proration is the related split of one amount into used and unused
parts that always add back up; this is the plan-change calculation built on
the same idea, with two prices and an explicit rounding mode.