GTM Systems
The Quote Said $240K, the Invoice Said $261K, and Both Systems Were "Right"
Sales quoted fast and finance could not reconcile a single deal to the penny. The gap was rounding and proration living in two places that never agreed. Here is how to design CPQ so quotes stay fast and the numbers actually tie out to finance.
· 8 min read
The deal closed at $240,000 on the quote. The invoice went out at $261,300. Nobody committed fraud and no field got fat-fingered; both systems were doing exactly what they were told. The quote prorated a mid-month start using a 30-day month and rounded each line to the dollar. The billing system prorated on actual days and carried four decimals, then summed. Multiply a small per-line difference across forty line items and a multi-year ramp, and you get a $21,300 gap on one deal that took finance three days to explain and a very uncomfortable call with the customer to resolve. The CPQ was fast. It just did not tie out.
That is the tension every CPQ build lives inside. Sales wants a quote in minutes, so you push logic into config that generates numbers quickly. Finance needs those numbers to reconcile to the invoice and the revenue schedule to the penny, because a quote that does not match the invoice is a quote that generates disputes, restatements, and mistrust. The two goals are not in conflict if you design for both from the start. They only collide when you optimize the quote for speed and leave reconciliation as someone else’s problem downstream.
The gap is almost always rounding, proration, and term math
When a quote and an invoice disagree, the cause is rarely a wrong price. It is that the same calculation ran twice with different rules. Three culprits account for nearly every gap I have chased. Rounding: does each line round to the dollar, or does only the total round, and to how many decimals do you carry the intermediate math? Proration: does a mid-term start prorate on a 30-day month, a 365-day year, or actual days in the actual months? Term math: on a multi-year ramp, does year two’s uplift compound on the discounted year-one price or the list price? Pick a rule for each, implement it once, and the systems agree. Leave any of the three implicit and the two systems will each guess, differently.
View as table
| Item | Value |
|---|---|
| Proration basis (30-day vs actual) | 12.4K |
| Line vs total rounding | 5.1K |
| Ramp uplift base | 3.8K |
Design the calc once, consume it everywhere
The architectural fix is to make the price calculation a single source that both the quote and the billing feed read, rather than two implementations that happen to agree most of the time. In a Salesforce CPQ context, that means the quote line calculations, the order and contract that generate from them, and the payload you send to billing all derive from the same price rules and the same rounding and proration configuration. If billing lives in a separate system, the reconciliation contract is the order: the quote produces an order with per-line net amounts and a schedule, and billing invoices against that order rather than recomputing from list price and its own proration.
Pin the math rules in metadata, not in a formula field
The proration and rounding rules should be explicit configuration a human owns, not implicit behavior buried in a formula field that a well-meaning admin edits without knowing billing depends on it. When I inherited the mismatched org, the quote’s proration was a formula field on the quote line and billing’s was a setting in the billing platform, and neither team knew the other existed. Making the rule a named, owned config value on both sides, with the same definition written down, is what closed the gap and kept it closed.
// Proration is ONE decision, applied everywhere. Actual/actual, carry 4 dp,
// round the line, not the intermediate. Both the quote and the order-to-billing
// payload call this, so they cannot diverge.
public static Decimal proratedAmount(Decimal annualPrice, Date start, Date end) {
Integer daysInTerm = start.daysBetween(end) + 1;
Integer daysInYear = Date.isLeapYear(start.year()) ? 366 : 365;
Decimal raw = annualPrice * (Decimal.valueOf(daysInTerm) / daysInYear);
return raw.setScale(2, System.RoundingMode.HALF_UP); // round the line, once
}
The worked example: the same deal, tied to the penny
Fast-but-unreconciled versus fast-and-tied-out
| CPQ optimized for speed only | CPQ designed to tie out | |
|---|---|---|
| Where proration lives | A formula field, plus a billing setting | One shared calc both sides call |
| Rounding rule | Implicit, differs by system | Explicit config, identical both sides |
| What billing invoices | Recomputes from list price | The order schedule the quote produced |
| Quote-to-invoice variance | $21.3K on one deal | Zero, tied to the penny |
| Finance reconciliation | Three days per disputed deal | One-line tie-out |
| When rules change | Edit two places, hope | Change the shared config once |
Here is how I design CPQ to tie out
- 1
Write down the three math rules first
Rounding (line vs total, decimals carried), proration (30-day, 365-day, or actual/actual), and ramp uplift base (list vs discounted). These are business decisions. Get finance to sign the definitions before you build.
- 2
Implement each rule once, in a shared calc
One proration method, one rounding method, called by the quote and by the order-to-billing payload. No second implementation anywhere, no formula field quietly doing its own math.
- 3
Make the order the reconciliation contract
The quote generates an order with per-line net amounts and a schedule. Billing invoices against that order, it never recomputes from list price. Now there is a single artifact both finance and sales point to.
- 4
Store the rules as owned config, not buried formulas
The rounding and proration settings are named values a human owns on both sides, with the definition documented. An admin cannot change one without seeing that billing depends on it.
- 5
Build a tie-out test on real deal shapes
Mid-month start, multi-year ramp, partial-period co-term, a forty-line bundle. Assert quote total equals order total equals invoice total to the penny. Run it before every release.
- 6
Reconcile a sample every close, not every dispute
Pick a handful of closed deals each period and tie the invoice back to the quote proactively. A gap you catch in the sample is a config fix; a gap the customer catches is a credit memo and a trust hit.
The $21,300 gap was never a pricing mistake. Both systems were right by their own rules; the rules just never matched, because proration and rounding lived in two places nobody had reconciled. A fast quote and a quote that ties out are the same build if you decide the math once, implement it in a single shared calc, and make the order the contract billing invoices against. Speed for sales and reconciliation for finance are not a trade. They are two requirements of one well-designed system, and the deal that ties to the penny is the one nobody has to spend three days explaining. The same single-source discipline is why every integration needs reconciliation built in from day one, so a dropped or mis-mapped record surfaces the same day instead of at quarter close.
Keep reading
One email. Every week.
One email a week: a systems problem I architected or untangled, with the schema, the config, and what I would change. No roundups, no theory, unsubscribe whenever it stops being useful.
The newsletter opens soon.
Connect a provider in src/config.ts