Revenue recognition
Selling something and earning the revenue from it are two different events, and the gap between them is what this module exists to record. Under Revenue, CPQ carries the ASC 606 / IFRS 15 objects that sit behind a signed contract: the rules that say how each product’s revenue is earned, the split of the transaction price across the performance obligations in the deal, the schedule that spreads each obligation’s revenue over time, the deferred revenue balance that has not been earned yet, and the journal entries that record what was.
CPQ is not the ledger of record. Everything below is a revenue sub-ledger — a working set your finance team maintains alongside the accounting system that actually holds the balances. See Relationship to Accounts before you plan around it.
Core objects
Section titled “Core objects”- Recognition rules — reusable policy: which recognition method applies, what triggers recognition, the default term, proration and reversal behaviour, and the revenue, deferred revenue and unbilled receivable account codes.
- Revenue allocations — one per deal: the total transaction price and the list of performance obligations it is split across, each with a standalone selling price, an allocated amount and a percentage.
- Revenue schedules — one per obligation: an amount, a start and end date, a frequency and a period count, forming the plan for when that revenue is earned.
- Deferred revenue — a period-by-period roll-forward of the unearned liability: opening balance, additions, reductions, adjustments and closing balance, with the two account codes it sits between.
- Revenue journal entries — balanced debit/credit entries with their own approve, post and reverse lifecycle.
Rules, Allocations, Schedules, Deferred Revenue and Journal Entries each have a list, a detail view and a form, and each appears in the navigation under Revenue.
The workflow
Section titled “The workflow”The intended path starts on the contract, not in the Revenue module.
- Set up your rules once. Under Revenue → Rules, create a recognition rule for each way you earn revenue — a perpetual licence recognised at a point in time, a support contract recognised over twelve months, a milestone-based professional services engagement.
- Open an active contract and choose Generate Revenue. CPQ lists the contract’s products and asks you to pick a recognition rule for each one. Every product needs a rule; the dialog names the ones you have missed and will not continue until they all have one. The button sits on every contract but only opens the dialog once the contract is active — on a draft it does nothing, so activate the contract first.
- Allocate the transaction price. You land on a new allocation form already loaded with the contract, its products as performance obligations, and the rules you just chose. Set the standalone selling prices, pick an allocation method, and CPQ works out each obligation’s share.
- Approve the allocation. Approving locks it — an approved allocation cannot be edited or deleted.
- Generate the schedules. An approved allocation offers Generate Revenue Schedule, which creates one revenue schedule per obligation from the allocated amounts.
- Activate each schedule. Activation is what opens the deferred revenue balance for schedules recognised over time.
- Record the accounting as journal entries as each period’s revenue is earned, and post them.
Steps 1 to 6 work as described. Step 7 is manual, and the reason is the honest limitation of this module: see Recognising revenue period by period.
Recognition rules
Section titled “Recognition rules”A rule is named policy, held in one place so that a hundred contracts do not each invent their own treatment. Each carries a code and name, what it applies to, the revenue type, and then the substance:
- Recognition method — point in time, over time, milestone, usage, or percentage of completion.
- Recognition trigger — what event starts the clock, such as the invoice or a milestone. A milestone-based rule must use the milestone trigger; the form enforces that.
- Schedule type and default term — required for over-time recognition, so the rule knows how long the revenue spreads across.
- Upfront recognition percentage, for the part of a deal earned immediately.
- Proration and reversal — whether each is allowed, and by which method.
- Account codes — revenue, deferred revenue and unbilled receivable.
Each rule also carries an Active toggle, so policy you no longer want offered can be retired without deleting the history of contracts that used it.
One thing to know about Applies To: a rule records the scope you set it to, but nothing matches on it automatically. Rules are applied by explicit choice — you pick one per product in the contract’s Generate Revenue dialog, which offers every rule you have defined. Treat the scoping fields as documentation for the person choosing, not as a matching engine. Scoping a rule to a specific product is saved; the category and family variants are not stored, so use the rule name and description to say what a rule is for.
Allocating the transaction price
Section titled “Allocating the transaction price”This is ASC 606 step 4, and it is the part of the module with the most care in it.
An allocation is built against a contract, a quote or a sales order. Only the contract source auto-populates the obligations: choose a contract and CPQ pulls in its products as performance obligations, one row each, carrying the quantity, unit price, list price and — as the opening standalone selling price — the product’s own SSP if it has one, otherwise the net line value after discount. For a quote or a sales order you build the obligation rows yourself.
Each obligation row carries its standalone selling price and the SSP method used to arrive at it — observable price, adjusted market assessment, expected cost plus margin, or residual — which is the evidence trail an auditor asks for.
The allocation method then decides how the transaction price is split:
| Method | How the split is made |
|---|---|
| Standalone selling price / relative standalone | Proportionally to each obligation’s SSP |
| Residual | SSP to every obligation except the last, which takes the remainder |
| Adjusted market assessment / expected cost plus margin | Your entered percentages; if none are entered, an equal split |
A bundle discount can be spread on top, either proportionally across obligations, applied to the first obligation only, or applied to the last. Variable consideration can be recorded on the allocation with its estimate and method.
The sum has to be right. The API refuses an allocation whose allocated amounts do not add up to the transaction price, to the cent, on create and on edit, and tells you both figures. The API also exposes a validate call that recomputes the sum of a saved allocation and tells you whether it still matches; there is no button for it on the allocation screens.
Whether an allocation needs approval is set on the allocation itself. If it does, it is created as a draft and waits for Approve or Reject on the detail screen — rejection asks for a reason. If it does not, it is created approved.
A contract takes one allocation. If the contract already has an active allocation, a second is refused unless that first allocation was itself flagged as a re-allocation, in which case it is superseded and the new one records it as its original. Plan on getting the allocation right rather than iterating on it, and use the re-allocation flag deliberately when a contract modification means you will need to reallocate later.
Revenue schedules
Section titled “Revenue schedules”A schedule is the plan for one obligation’s revenue: the total amount, the recognition start and end dates, the frequency, the number of periods, and the recognition method.
Generating schedules from an approved allocation opens a dialog with one row per obligation, pre-filled with a schedule number derived from the allocation number, the obligation’s allocated amount and recognition method, and twelve monthly periods starting today with auto-recognise on. Adjust the dates, term and frequency per product before you confirm. Schedules are created one at a time, so if one fails you are told how many were created before the error.
You can also create a schedule by hand under Revenue → Schedules. Useful details:
- If you leave the number of periods blank, CPQ derives it from your dates and frequency — daily, weekly, monthly, quarterly or annually.
- If you name a revenue rule, the schedule takes its recognition method from the rule rather than from the form.
- Schedule numbers auto-increment rather than collide: give a number that is already taken and CPQ increments the numeric suffix until it finds a free one, and tells you what it used.
- Creating a schedule against a contract supersedes earlier schedules for the same contract and product — they are marked Adjusted and drop out of the list — so regenerating after a contract change replaces rather than duplicates.
- Schedules also carry proration, variable consideration with its constraint, and a performance metric and total for percentage-of-completion work.
Leave the Sales Order field on the schedule form unset. It is wired to a column the schedule table does not carry, so selecting a sales order makes the save fail; link the schedule to its contract or invoice instead.
A schedule opens as Pending and Activate moves it to In Progress. The detail screen shows the derived period table — period number, dates, amount, recognition status and GL status — computed from the amount, the period count and the frequency, so you can see the plan before anything is booked.
Activation and the opening deferred balance
Section titled “Activation and the opening deferred balance”Activating a schedule whose method is over time and which has auto-recognise set also opens its deferred revenue entry: an addition for the schedule’s full revenue amount into the current accounting period, classified as a current liability, over the schedule’s own start and end dates. Note that this opening entry uses fixed default account codes — 2400 for deferred revenue and 4000 for revenue — rather than the codes on your recognition rule, so check and correct them on the entry if your chart of accounts differs.
Schedules on other methods, or with auto-recognise off, do not open a deferred balance; create the deferred revenue entry by hand if you want one.
Recognising revenue period by period
Section titled “Recognising revenue period by period”This is the gap to plan around. CPQ does not draw down a schedule period by period. There is no recognition run, no scheduled job, and no Recognise action on the schedule screen; the API’s recognise and suspend endpoints require a schedule state that the current database no longer permits, so they reject every schedule. Activation is the last state change a schedule receives, which is why the period table always reads Pending against every period and the recognised amount stays at zero.
What this means in practice: use schedules as the recognition plan — the authoritative, auditable statement of how much of each obligation is earned in each period, generated from an approved allocation — and record the actual recognition as revenue journal entries, keeping the unearned balance current with a deferred revenue entry per period. The plan tells you what to book; you book it.
Deferred revenue
Section titled “Deferred revenue”A deferred revenue entry is a roll-forward for one schedule in one accounting period: opening balance, plus additions, less reductions, plus or minus adjustments, giving the closing balance. CPQ checks the arithmetic on every save and refuses an entry whose closing balance does not match the movement, quoting both figures, so the balance cannot drift.
Each entry carries its accounting period and fiscal year and quarter, the period start and end dates, the liability classification, the deferred revenue and revenue account codes, and reconciliation notes. The list is filterable and there are API lookups by schedule, period, fiscal year, contract and customer, plus the total deferred balance and unposted and unreconciled views.
The form offers more fields than are stored. The addition, reduction and adjustment reason boxes, the revenue-recognised amount, fiscal month, invoice and performance-obligation references, and the product, revenue-type and customer-segment classification fields are all dropped on save. What persists is the schedule and contract link, the customer, the period, the four balance figures, the classification, the two account codes and the notes — which is enough for the balance itself to be right, but means the reasons for a movement have to go in the notes.
Treat a deferred revenue entry as a record of the balance rather than as a way to post it. Neither of the two buttons on the detail screen completes: Reconcile fails on save, and Post to GL builds a debit line from the entry’s reduction and a credit line from its revenue-recognised amount — and the recognised amount is one of the fields the API does not store, so the entry can never balance and the posting is refused. Book the movement as a revenue journal entry instead, and keep reconciliation state in the notes field.
Revenue journal entries
Section titled “Revenue journal entries”Journal entries are the most complete part of the module, and the place the real accounting is captured.
An entry has a number, a type and source, its accounting period, posting date and fiscal year and quarter, a currency, a description, and its lines. Each line carries an account code, a debit and a credit. Entries must balance. The form totals debits and credits live, shows the difference, marks the entry Balanced or not, and disables submission until it is; the API repeats the check on create and on edit and refuses an unbalanced entry with both totals. Entry numbers are unique per company.
The lifecycle runs Draft or Pending Approval → Approve → Post to GL → optionally Reverse, with the buttons appearing on the detail screen as each becomes available. An entry can only be edited while it is draft or pending approval, and cannot be posted until it is approved. The Delete button is offered only while it is draft; a posted entry cannot be deleted at all — reverse it instead. The API also exposes unposted, pending-approval and integration-error views, and lookups by schedule, period, fiscal period, status, contract and customer.
Reversal creates a mirrored entry — every line’s debit and credit swapped,
numbered REV- plus the original number, already approved and ready to post,
carrying your reason in its description. It requires a reversal date and a reason,
and the Reverse button on the entry screen does not currently send either, so it
fails from the web app; a reversal has to be requested through the API with both
supplied, or entered as a fresh opposing entry by hand.
Posting is the one step that does not go where its name suggests — see Relationship to Accounts.
Period close, reconciliation and adjustments
Section titled “Period close, reconciliation and adjustments”Screens exist for period close, revenue reconciliation and revenue adjustments —
at /revenue/periods, /revenue/reconciliation and /revenue/adjustments — but
they are not in the navigation and they do not work against the current database:
the periods, reconciliation and adjustment services are written against columns
and a table that are not there, so creating a period, running validations,
closing, reopening or locking a period, running or exporting a reconciliation, and
creating or approving an adjustment all fail. Do not plan a close process around
them yet.
The one piece of this area that does run is the period lock. If a revenue period record exists and is closed or locked, CPQ refuses writes dated into that period — creating a schedule whose recognition starts in it, creating, editing, posting or deleting a deferred revenue entry in it, and creating, editing, approving, posting, reversing or deleting a journal entry in it. The guard is live and correct wherever it is reached. It just has nothing to read until period records exist, and they cannot currently be created through the application, so treat period control as something to enforce by process for now.
Relationship to Accounts
Section titled “Relationship to Accounts”Post to GL does not reach a general ledger. It marks the entry posted and stamps it with a simulated reference and batch number; nothing leaves CPQ. There is no connector from CPQ to WorkSquares Accounts, and no external ERP adapter is configured — the integration layer ships an adapter interface and a generic REST adapter, but the posting path is wired to the simulator, for every company.
So read the status honestly: Posted on a CPQ revenue journal entry means “approved and released by revenue accounting”, not “in the ledger”. The entries themselves are complete and correct — balanced lines with account codes, periods and dates — so they are exactly what you need to enter or import into Accounts, which is the double-entry ledger of record for the suite and holds the balances your statements are built from. Until a seam exists, that hand-off is yours to make, and Accounts is the system that must agree with your financial statements.
Not on mobile
Section titled “Not on mobile”Revenue recognition is web only. None of the four CPQ mobile apps carry rules, allocations, schedules, deferred revenue or journal entries.
Connects to
Section titled “Connects to”- Orders & contracts — the contract is where revenue generation starts, and its obligations carry the transaction price, standalone selling price, allocated amount and recognition method that this module works from.
- Billing & payments — invoicing bills the customer; recognition says when you earned it. They are deliberately separate.
- Subscriptions — recurring agreements are the usual source of over-time recognition.
- Accounts — the ledger of record the revenue journals belong in.