Recipe: Proration logic explainer (mid-cycle changes)
How Meridian computes partial-period charges when a subscription upgrades, downgrades, or changes seat count between billing dates.
The core formula
unused_credit = (remaining_days / total_days) × old_plan_price
new_charge = (remaining_days / total_days) × new_plan_price
prorated_total = new_charge − unused_credit
Worked example
- Billing cycle: 30 days, $90/mo Pro plan
- Day 10: upgrade to $150/mo Enterprise
- Remaining: 20 days
- Unused credit: (20/30) × $90 = $60.00
- New charge: (20/30) × $150 = $100.00
- Prorated total: $100.00 − $60.00 = $40.00 due now
Edge cases
Downgrade
Credit exceeds new charge → negative total → account balance applied to next invoice.
Same-day flip
remaining_days = total_days → full credit, full new charge. Net difference only.
Seat changes
Multiply old_plan_price and new_plan_price by respective seat counts before proration.
Trial expiry
No unused credit. Charge full new plan price from conversion date to cycle end.
Implementation notes
- Use UTC midnight for day boundaries to avoid DST skew.
- Round all amounts to 2 decimal places with banker's rounding.
- Store proration events in an immutable ledger for audit.
- Cache total_days per subscription to avoid mid-cycle drift.