Company context and the revenue surface area
The company is a vertical SaaS platform serving mid-market customers, with $50M ARR split roughly 70% subscription / 30% usage-based consumption. The customer book runs ~480 active contracts, with average contract value of $95K and term lengths between 12 and 36 months. About 22% of the book is multi-year, 14% includes professional services tied to the subscription, and 6% includes premium support add-ons sold as separate performance obligations.
Revenue recognition complexity does not come from any one factor but from how factors combine. A typical large customer at this company has a multi-year subscription with annual price escalators, a usage-based component priced per-API-call with monthly minimums, an implementation services SOW recognized over the implementation period, and one or two premium support tiers added mid-term. Each of these elements has its own ASC 606 treatment, and modifications happen on roughly 18% of contracts every quarter.
- Subscription revenue — fixed monthly fees, recognized ratably over the term, with annual escalators that re-trigger transaction-price re-allocation
- Usage-based revenue — variable consideration, recognized as customers consume, constrained where minimum commitments apply
- Implementation services — distinct performance obligation when standalone, otherwise combined with subscription and recognized over the term
- Premium support — distinct performance obligation; standalone selling price estimated using cost-plus + observable evidence
- Material rights — multi-year discounts and renewal options assessed for materiality each cycle
Before automation — where revenue actually lived
Revenue recognition lived in two spreadsheets that the senior accountant maintained personally: one for committed ARR with one row per active contract and a column per future month, and one for usage that pulled from a Stripe export and applied minimum commitments by hand. Contract modifications required manual recalculation of cumulative catch-up against the prior allocation, and modifications that crossed quarter-end frequently broke the spreadsheet's array formulas.
The auditor flagged 7 modifications the prior year that had been computed inconsistently — five used prospective treatment when the goods/services were not distinct from the original contract (cumulative catch-up should have applied), and two used cumulative catch-up when they should have been treated as separate contracts. The findings did not cause a restatement but consumed roughly nine days of senior-accountant time during fieldwork to re-perform.
- Manual ASC 606 revenue schedule per contract, maintained in two spreadsheets
- Usage revenue posted from billing system separately, no reconciliation
- Contract modifications recalculated by hand with no documented logic
- Deferred revenue waterfall built from spreadsheets at quarter-end
- Standalone selling price re-estimated only when the auditor asked
- Auditor findings on modification cumulative-catch-up calculations (7 contracts)
- Revenue close cycle: 11 business days, ending on the day of the board pack
What Ledger Summit implemented
We built a contract-aware revenue engine that pulls from the CRM and billing system, applies ASC 606 logic, generates revenue-recognition journal entries, and produces a per-contract evidence pack. Contract modifications run through documented logic with reviewer sign-off. The engine sits on top of the existing NetSuite + Salesforce + Stripe stack — no rip-and-replace, no migration to a dedicated rev-rec product.
- Contract-level rev-rec engine integrated with Salesforce (orders) and Stripe (usage)
- ASC 606 five-step logic: identify contract, identify performance obligations, determine transaction price, allocate transaction price to POs, recognize revenue as POs are satisfied
- Contract modification handling: prospective vs. cumulative catch-up vs. separate contract, with worked-example documentation and reviewer sign-off on judgment-heavy cases
- Usage-based revenue tied to source Stripe events with daily reconciliation and monthly true-up
- Deferred revenue waterfall auto-generated each close, with full GL roll-forward tie-out
- Per-contract evidence pack: contract data, allocation worksheet, JE trace, reviewer log, modification history
- Standalone selling price re-estimation cadence: annual review, with documented methodology
Technical architecture and data flow
Salesforce remains the source of truth for contract data — order lines, term dates, escalator clauses, modification flags, and SOW metadata. Stripe remains the source of truth for billing events and usage. The rev-rec engine reads from both nightly, applies ASC 606 logic, and writes journal entries back to NetSuite via the suiteTalk API on the close calendar.
Three principles drove the design. First, every revenue number on the financial statements has to be traceable back to a contract and a performance obligation in under five clicks. Second, modifications never silently change prior-period revenue — modifications that would adjust historical revenue produce a flagged journal entry that requires reviewer sign-off before posting. Third, the engine never blocks the close — if a contract has missing data or ambiguous treatment, the engine flags it for manual review rather than failing the run.
- Salesforce → engine — order, modification, and contract metadata pulled nightly; contract version history retained
- Stripe → engine — invoice and usage events pulled daily; minimum commitment and overage logic applied centrally
- Engine → NetSuite — JEs posted via suiteTalk in summary form, with contract-level detail in a custom record for drill-down
- Engine → controls system — every reviewer decision, override, and modification ruling logged with timestamp and user
- Reconciliation — daily check that sum of contract-level revenue equals sum of GL revenue; failures alert immediately
Scenario coverage — every revenue situation we modeled
Comprehensive automation only works if the engine can handle every contract scenario the sales team will close. Each of these was modeled, documented, and tested before cutover.
| Scenario | Treatment | Reviewer required? |
| New contract, single PO, fixed price | Ratable over term | No |
| New contract, multiple POs, allocated price | Allocate by relative SSP, recognize each PO independently | No |
| New contract with usage component | Subscription ratable; usage as-consumed with constraints | No |
| Mid-term upgrade (add seats / tier increase) | Cumulative catch-up if not distinct; prospective if distinct | Yes |
| Mid-term downgrade | Prospective; reassess transaction price for remaining term | Yes |
| Contract extension at price discount | Material rights assessment; modification or separate contract | Yes |
| Termination + new contract within 30 days | Combined as a single arrangement | Yes |
| Implementation services with the subscription | Combined unless capability is independently usable | One-time at SOW |
| Premium support added mid-term | Separate PO; allocation over remaining term | No |
| Pilot phase at zero dollars | Constrained variable consideration; recognize zero until paid phase begins | No |
| Foreign-currency contract | Re-measured at functional currency on each recognition date; CTA into OCI | No |
| Customer credit memo (service issue) | Variable consideration update; reduce remaining transaction price | Yes |
| Renewal at higher price (escalator triggered) | New contract for renewal period; no carry-over | No |
| Reseller / channel sale | Principal-vs-agent assessment; recognize gross or net per ruling | One-time at deal type |
| Multi-year prepaid with annual escalators | Allocate prepaid amount over total term; escalator changes future-period recognition only | No |
Alternatives considered — build vs. buy at $50M ARR
The client evaluated three approaches before selecting build-and-integrate. The decision is sensitive to ARR scale, deal-mix complexity, and team headcount; our recommendation flips above ~$200M ARR or with materially more complex commerce.
| Option | Time to live | 3-year cost | Strengths | Weaknesses at this scale |
| RightRev (dedicated rev-rec product) | 4–6 months | $280K–$420K | Purpose-built; strong audit posture | Heavy implementation; license overhead vs. value at $50M ARR |
| Zenskar (subscription-billing-plus-rev-rec) | 3–5 months | $220K–$340K | Tight billing-to-rev-rec coupling | Disrupts existing Stripe billing; team retraining cost |
| NetSuite Advanced Revenue Management | 6–9 months | $140K–$260K | Already in NetSuite; one-vendor | Module is rigid for usage-based; modification logic is awkward |
| Build on existing stack (selected) | 10 weeks | $95K–$140K | Fits existing architecture; full ASC 606 control; auditor-friendly | Maintenance load on internal team; we transition ownership |
At ~$200M ARR, modification volume and contract-shape diversity typically push organizations toward a dedicated product. Below that, the build-and-integrate path delivers faster, costs less, and produces a stronger audit posture because the logic is explicit rather than abstracted behind a vendor's black-box engine.
When this approach fits
The build-and-integrate pattern is the right answer when the company has:
- $10M–$200M ARR with growth above 30% YoY
- An existing accounting platform that supports clean JE posting (NetSuite, Sage Intacct, even Xero/QBO at the lower end)
- A CRM that holds canonical contract terms (typically Salesforce or HubSpot)
- A billing system with clean usage event data (Stripe, Chargebee, Maxio, Recurly)
- Modification volume below ~5% of contracts per month
- A finance team of 4–10 with at least one revenue-focused accountant