Tutorial

How to Design Proration and Upgrades in a Custom SaaS Billing System

How to calculate proration, apply upgrades mid-cycle and keep ledger entries auditable when you build billing into a custom SaaS platform.

Proration is the practice of charging or crediting a customer for the part of a billing period they used when a plan changes mid-cycle. To design it in a custom SaaS billing system, you fix an effective date, calculate a credit for unused time on the old plan and a charge for the remaining time on the new plan, then record both as separate entries that trace back to one change event. Tax, entitlements and payment retries all hang off those decisions.

What is proration in a custom SaaS billing system?

Proration is the pro-rated adjustment of a charge when a subscription changes partway through a billing period. The system credits unused time on the old plan and charges for the remaining time on the new one.

A billing period is the window a subscription is invoiced for, usually one month or one year. Say a customer moves from a $20 plan to a $50 plan on day 10 of a 30 day cycle. Twenty days remain.

The credit is roughly two thirds of $20, about $13.33, and the new charge is roughly two thirds of $50, about $33.33, so the customer pays about $20 today. That arithmetic is easy. The hard part is deciding when to apply it, how precisely to measure elapsed time and how to record the result so finance can audit it six months later.

Which proration method should you choose?

Choose the simplest method that fits your price points and support tolerance. Daily proration stays accurate within a fraction of a percent for monthly plans and takes a few days to build; per-second proration only pays off on high-value contracts.

The options differ less in accuracy than in effort and in how the customer reads the resulting invoice.

MethodCredit calculationAccuracyBuild effort
No prorationOld plan runs to period end, new plan starts next periodExact, but the customer waitsMinimal
DailyUnused days / days in the periodWithin roughly 1 to 3 percent on short cyclesLow
Per-secondUnused seconds / seconds in the periodSub-cent on most plansModerate
Immediate resetCustomer pays the full new price, no creditDepends on your pricingLow, higher support load

Daily proration is the default for most products. It is defensible, easy to explain and cheap to compute. Per-second proration makes sense when a single day of the plan is worth more than the engineering time it costs to get right, which in practice means contracts in the thousands per month. The immediate reset option, where you charge the full new price and grant a fresh period starting today, is common in self-serve tools.

It also annoys anyone who upgrades on day 28. Whatever you pick, apply it consistently across seats, add-ons and plan tiers. Mixed rules produce the kind of invoice that generates a support thread rather than a payment.

Should an upgrade take effect immediately or at the next renewal?

Most SaaS products apply upgrades immediately and downgrades at the next renewal. Immediate upgrades give customers the access they just paid for; deferred downgrades avoid refunds and stop people from cycling plans to collect credits.

The effective date is a timestamp you store on the change event, not something you infer from when a webhook arrives. A webhook is an HTTP callback your payment processor sends when something happens on its side. If you infer timing from delivery, a delayed webhook during an outage can backdate a change by hours and shift the proration amount.

Decide the policy per direction of change:

  • Upgrade: apply once payment succeeds, and grant entitlements at that moment.
  • Downgrade: schedule for the end of the current period and keep current entitlements until then.
  • Seat increase: usually immediate, prorated the same way as a plan change.
  • Seat decrease: schedule for the next period, and never let a negative balance turn into a cash refund on its own.
  • Same-price crossgrade: treat it as a swap, move no money, change entitlements at the effective date.

An entitlement is the set of features, limits and quotas a plan unlocks. Entitlements should be derived from subscription state rather than written directly by the upgrade flow, so a failed payment or a reversal puts the account back where it belongs.

How do you record a mid-cycle change in the ledger?

Post the credit and the new charge as separate ledger entries tied to a single change event, not as an edit to an existing invoice. The customer sees a credit note, the new charge, and a net amount.

A ledger is an append-only record of money movements. Append-only means you add rows and never rewrite them; corrections arrive as new rows. That constraint is what makes the system auditable and what makes reconciliation with your payment processor possible.

Three rules keep it honest:

  1. One change event produces one credit line, one charge line and one net payment request. Never mutate the original invoice for that period.
  2. Every write is idempotent. Idempotent means running the same operation twice leaves the same single result, which matters because webhooks retry and background jobs restart.
  3. Tax is recalculated on the net amount, not on the old invoice total. Treatment varies by jurisdiction and by whether you issue a credit note or a revised invoice.

If a credit exceeds the amount due, decide early whether it becomes account credit or a refund. Account credit is simpler and keeps the money with you, but some enterprise contracts require a refund on request. Store the balance as a ledger account rather than a column you overwrite on the customer record.

This is the part of the system that finance, support and product all touch, which is why teams often bring in outside help. ObjiDev builds custom SaaS platforms with billing, entitlements and reporting modelled together rather than bolted on after launch.

Which edge cases break a first version?

Trials without a card, coupons, annual plans upgraded in month two, rapid seat changes and currencies with different minor units break naive day-count math. Handle each case explicitly, or the first support ticket becomes a refund.

  • Trial upgrades: decide whether unused trial days convert to credit or are discarded. Converting is friendlier, but it forces you to value a trial day.
  • Coupons: store the discount on the subscription, not the invoice. A 30 percent coupon on the old plan should not follow the customer to a new plan unless the coupon says so.
  • Annual to monthly: someone two months into an annual plan carries a large unused credit, potentially hundreds of dollars. Cap how much credit an account can hold.
  • Same-day seat churn: net the change per day instead of emitting a line per event, or finance receives a page of one-cent rows.
  • Currencies without decimal places: Japanese yen has no minor unit, so rounding per line gives totals that do not equal the sum of the lines. Round at the invoice level and store the difference.
  • Failed payment after an upgrade: dunning, the automated retry and reminder sequence for failed charges, has to be able to revoke entitlements when the net amount is never collected.

What does a realistic build sequence look like?

Ship the calculator and the ledger before you design the interface, because the pricing screen is the easy part and the money math is where the expensive bugs hide. Expect the first version to take a few weeks.

  1. Write the policy in plain language first: what happens on an upgrade, a downgrade, a seat change and a reversal. One page, agreed by finance.
  2. Model each change as an immutable event with an effective date, an old plan snapshot and a new plan snapshot.
  3. Build the proration calculator as a pure function: the two snapshots and the effective date go in, a list of credit and charge lines comes out.
  4. Post those lines to the ledger inside one transaction, using an idempotency key that includes the change event ID.
  5. Derive entitlements from subscription state and let a background job reconcile them against what the customer can actually access.
  6. Test from a written case table: upgrade on day 1, day 15 and day 29, downgrade mid-period, upgrade with a coupon, upgrade while a payment is failing.

A focused build of proration, ledger entries and entitlement sync typically runs two to four weeks for one experienced engineer. Tax handling, invoice rendering and reconciliation reports add another one to two weeks. Plan to reconcile at least one full billing cycle, roughly 30 days, against processor payouts before you quote the numbers anywhere that matters.

Frequently asked questions

How do you calculate proration on a mid-cycle upgrade?

Divide the time remaining in the current billing period by the total length of that period to get a fraction, then apply the fraction to the old plan price as a credit and to the new plan price as a charge. The difference between the two is what you collect, before tax, and it should be posted as separate lines rather than as an edit to the existing invoice.

Should you prorate downgrades?

Downgrades are normally scheduled for the next renewal rather than prorated right away, because an immediate downgrade creates a credit balance instead of a payment. If a contract requires immediate downgrades, prorate the change and hold the credit on the account rather than issuing a refund by default.

Do you need per-second proration in a SaaS billing system?

Only when a single day of the subscription is worth more than the effort of building and testing a more precise calculation, which usually means contracts worth thousands per month. For monthly plans priced in the tens or low hundreds, daily proration is accurate enough that customers will not notice the difference.

How long does it take to build proration into a custom billing system?

A focused build covering the proration calculator, ledger entries and entitlement sync typically takes two to four weeks for one experienced engineer. Tax handling, invoice rendering and reconciliation reports add roughly one to two weeks, plus at least one full billing cycle of running in parallel before you rely on the figures.

Back to blog