Revenue Recognition (IFRS 15 / ASC 606)
When you record revenue is a bigger deal than whether you invoice. Invoicing is a cash-collection event; revenue recognition is an accounting judgement, and since 2018 it’s governed by a single global five-step model.
The core principle
Recognise revenue when control of the goods or services transfers to the customer, in the amount you expect to be entitled to.
Not when you invoice. Not when you’re paid. When control transfers.
The five steps
1. Identify the contract
A contract exists when: it’s approved, rights and payment terms are identifiable, it has commercial substance, and collection is probable. Multiple contracts with the same customer may need combining if they’re negotiated as a package.
2. Identify the performance obligations
Each distinct good or service is a separate obligation. Distinct means: the customer can benefit from it on its own, AND it’s separately identifiable in the contract.
Software deal, 120,000:
├── Perpetual licence → obligation 1 (point in time)
├── Implementation services → obligation 2 (over time)
├── 3 years support & updates → obligation 3 (over time)
└── Training (5 days) → obligation 4 (as delivered)
Unbundling is where most of the work is. Common bundles: hardware + installation + warranty; product + free shipping; equipment + extended service plan; SaaS + onboarding.
3. Determine the transaction price
Not just the list price. Adjust for:
| Adjustment | Effect |
|---|---|
| Variable consideration | Volume rebates, penalties, bonuses — estimate using expected value or most likely amount, constrained so a significant reversal isn’t probable |
| Significant financing component | If payment is >12 months from delivery, split out interest |
| Non-cash consideration | Measured at fair value |
| Consideration payable to the customer | Slotting fees, co-op advertising — usually a reduction of revenue, not an expense |
| Rights of return | Recognise only what you expect to keep; book a refund liability and a return asset |
4. Allocate the price to the obligations
Allocate in proportion to standalone selling price (SSP) — what you’d charge for each item separately.
SSP SSP % Allocated (of 120,000)
Licence 60,000 40.0% 48,000
Implementation 45,000 30.0% 36,000
Support (3 yr) 37,500 25.0% 30,000
Training 7,500 5.0% 6,000
─────────────────────────────────────────────────────────
150,000 100.0% 120,000
Note the 30,000 discount is spread proportionally, not dumped on one line — even if the sales contract shows the discount against the licence. Determining SSP where you never sell something separately is the hardest judgement in the standard.
5. Recognise revenue as obligations are satisfied
Point in time — when control transfers. Indicators: you have a present right to payment, the customer has legal title, physical possession, the risks and rewards, and has accepted the asset.
Over time — if any of:
- The customer simultaneously receives and consumes the benefit (a subscription, a cleaning service)
- Your work creates/enhances an asset the customer controls as it’s built (construction on the customer’s land)
- The asset has no alternative use to you AND you have an enforceable right to payment for work done to date (custom manufacturing)
Over-time measurement:
- Input method — cost incurred / total expected cost (“percentage of completion”, “cost-to-cost”)
- Output method — units delivered, milestones, surveys of work performed
What this creates in the ERP
Because revenue and invoicing decouple, you get two new balance-sheet items:
| Item | Meaning | When |
|---|---|---|
| Contract asset / unbilled receivable / accrued revenue | Revenue recognised, not yet invoiced | Percentage-of-completion projects, usage billed in arrears |
| Contract liability / deferred revenue / unearned revenue | Invoiced, not yet earned | Annual subscriptions billed upfront, deposits |
1 Jan: Invoice a 12-month support contract, 36,000 upfront
Accounts receivable Dr 36,000
Contract liability Cr 36,000 ← not revenue yet
Each month:
Contract liability Dr 3,000
Revenue Cr 3,000
The deferred revenue roll-forward (opening + billings − recognised = closing) is a standard audit schedule. Build it.
Common patterns
Subscription / SaaS
Straight-line over the term. Watch for: mid-term upgrades (prospective remeasurement), setup fees (usually not distinct → spread over the expected customer life, not the contract term), usage overages (recognised as incurred), and multi-year deals with escalators.
Percentage of completion
Contract value 5,000,000
Total estimated cost 3,800,000
Cost incurred to date 1,520,000
Percentage complete 40%
Revenue to recognise 2,000,000
Cost recognised 1,520,000
Gross profit 480,000
Invoiced to date 1,600,000
Contract asset (unbilled) 400,000
Critical: when the estimate of total cost changes, you catch up cumulatively in the current period, not retrospectively. And if the contract becomes loss-making, you recognise the entire expected loss immediately — an onerous contract provision.
Bill-and-hold
Customer is invoiced but goods stay in your warehouse. Revenue only if: the reason is substantive (customer requested it), the goods are separately identified as theirs, ready for delivery, and you can’t use them for anyone else. Historically abused for period-end revenue inflation, so auditors look hard.
Consignment
Goods at the customer’s site remain yours. No revenue until they sell or consume them. Inventory stays on your balance sheet in a “consignment stock at customer” location.
Principal vs agent (gross vs net)
Do you record the full sale (gross) or just your commission (net)?
You’re the principal if you control the good/service before transfer — indicators: you’re primarily responsible for fulfilment, you bear inventory risk, you set the price.
Marketplaces get this wrong constantly, and it can change reported revenue by 10×. Same profit, wildly different top line.
Warranties
- Assurance warranty (“it will work as specified”) → not a separate obligation; accrue a provision for expected costs
- Service warranty (“we’ll service it for 3 years”) → a separate performance obligation, allocate price to it, recognise over time
If the customer could buy it separately, it’s a service warranty.
Contract costs
- Costs to obtain a contract (sales commissions) → capitalise if incremental and recoverable, then amortise over the customer relationship period (which may be longer than the contract term if renewals are expected). A practical expedient lets you expense them if the amortisation period is ≤1 year.
- Costs to fulfil → capitalise if they relate directly to a contract, generate resources, and are recoverable.
The commission capitalisation requirement blindsided a lot of SaaS companies; it’s a real ERP feature (a “contract cost asset” with its own amortisation schedule).
Data model
contract(id, customer_id, contract_number, start_date, end_date,
total_transaction_price, currency, status)
performance_obligation(
id, contract_id, description,
standalone_selling_price, allocated_price,
recognition_method, -- POINT_IN_TIME | OVER_TIME_INPUT | OVER_TIME_OUTPUT | RATABLE
start_date, end_date,
satisfied_amount, recognised_amount
)
revenue_schedule( -- generated, then executed by a period job
obligation_id, period, planned_amount,
recognised_amount, recognised_at, journal_document_id
)
contract_modification(id, contract_id, effective_date, type, -- PROSPECTIVE | CUMULATIVE_CATCHUP
old_price, new_price, reallocation_basis)
Key behaviours:
- The schedule is regenerated on every contract modification, and the treatment (prospective vs cumulative catch-up) depends on whether the added goods are distinct and priced at SSP.
- The recognition run is a monthly batch job — idempotent, restartable, with a test mode. Same requirements as the depreciation run.
- Every recognition posting links back to the obligation and the schedule line, or you cannot support the audit.
Audit and disclosure
IFRS 15 requires disclosing:
- Revenue disaggregated by category (product line, geography, timing of transfer, channel)
- Contract asset and liability balances with a roll-forward
- Remaining performance obligations (the backlog) and when it will be recognised
- Significant judgements: how SSP was determined, how variable consideration was constrained
That backlog disclosure is a real reporting requirement your data model must support — you need to be able to say “we have 14.2M of unrecognised contract value, of which 8.1M recognises next year.”
Developer rules
- Invoicing and revenue recognition are separate processes with separate schedules. Do not couple them.
- Deferred revenue is a liability with its own roll-forward. Build the report early.
- The recognition run is a batch job with the same requirements as depreciation: idempotent, restartable, test mode, per-period, catch-up capable.
- Contract modifications regenerate schedules, and the ledger effect depends on modification type. Model modifications explicitly.
- Never let a revenue posting bypass the schedule. If it isn’t on a schedule line, it isn’t auditable.
- Keep the allocation calculation reproducible — store the SSPs used and the allocation percentages, not just the results.