In this volume · VOLUME 05
Accounting
Chart of Accounts Journals & Ledger Billing & Invoicing Payments & Receipts Payment Reconciliation Multi-Currency Deferred Revenue Commission Accounting Tax (VAT/GST) Period Close

Chapter 5.7 — Deferred Revenue & Revenue Recognition

1. Purpose

This chapter defines how travoBooks recognises revenue in line with IFRS 15 — Revenue from Contracts with Customers (and the materially equivalent ASC 606 under US GAAP). It covers the deferred-revenue mechanism for advance-billed services that have not yet been delivered, the service-date-driven recognition trigger, partial recognition for multi-segment itineraries, and the period-end recognition run that reclassifies deferred → earned revenue.

2. Why it matters in modern travel accounting

A travel agent typically bills before delivery: a customer pays for a flight in May that is taken in August. Under accrual accounting, the cash received in May is not yet revenue — it is a liability (deferred revenue) until the service is delivered. Without this discipline: - Monthly P&L is materially misstated - Quarterly results overstate revenue in growth periods and understate in decline - Refund liability is invisible (recognised revenue cannot be refunded cleanly) - Audit fails — IFRS 15 is the single most-tested area in travel-agency audits

3. Industry relevance

Travel-specific complications IFRS 15 must handle: - Multi-leg itineraries (outbound May, return August → split recognition) - Hotel stays (recognise pro-rata over stay nights, or on checkout date per policy) - Tour packages (revenue at tour-start date or pro-rata across the tour) - Insurance (recognise over the policy period, not at sale) - No-show / unused services (the unused performance obligation is extinguished at the service date) - Free-cancel windows (initial recognition deferred until cancellation right lapses, in some interpretations)

4. Compliance considerations

  • IFRS 15 five-step model must be demonstrably applied: (1) identify contract, (2) identify performance obligations, (3) determine transaction price, (4) allocate price to obligations, (5) recognise as obligations are satisfied.
  • ASC 606 mirrors IFRS 15 in substance; immaterial differences for disclosure.
  • Audit evidence — every recognised revenue line must trace to a service-date-driven event with documentary support (boarding pass scan via airline data, hotel checkout, tour completion).
  • Variable consideration — when contracts include refundable elements, variable consideration is constrained per IFRS 15 §56–58.

5. Business logic

5.1 The fundamental model

When a booking is issued and the partner is the agent (Chapter 3.2), the gross ticket amount is not revenue — it is a pass-through. Only commission, service fee, and markup can be revenue.

When the partner is the principal, gross is revenue and supplier cost is COGS, but timing of recognition still depends on service-date.

The two recognition models are:

Agent model (typical for air via GDS): - Commission is revenue — recognised at service-date (flight flown). - Service fee is revenue — recognised at issuance (the service of arranging is delivered at issuance). - Ticket gross is not revenue — never enters the P&L.

Principal model (typical for own tours, marked-up hotel inventory): - Gross is revenue — recognised at service-date. - Supplier net is COGS — recognised at service-date matching.

5.2 The deferred-revenue account

For each revenue category that requires deferral, there is a matching liability account:

Earned (P&L) Deferred (Balance Sheet liability)
4011 Air Base Commission 2031 Deferred Air Revenue
4012 Override Commission 2032 Deferred Override Commission
4021 Hotel Commission / Markup 2033 Deferred Hotel Revenue
4022 Tour Revenue 2034 Deferred Tour Revenue
4023 Insurance Commission 2035 Deferred Insurance Revenue
4031 Service Fee (Not deferred — earned at issuance)
4041 Cancellation Fee (Not deferred — earned at cancellation event)

At issuance, revenue posts to deferred, not earned:

Original issuance JE (agent model, simplified):
  Debit  1101 AR — Customer                X (gross)
  Credit 2011 BSP Payable                  Y (net to BSP)
  Credit 2031 Deferred Air Revenue         Z (commission, not yet earned)
  Credit 4031 Service Fee Revenue          W (earned now — partner's service of arranging is complete)

At service-date, recognition JE reclassifies:

Recognition JE:
  Debit  2031 Deferred Air Revenue         Z
  Credit 4011 Air Base Commission          Z

5.3 Service-date model

Each booking carries service_date_start and service_date_end. Recognition rules per product type:

Product Recognition trigger Allocation
Air — one-way / one-segment Flight depart date 100% on that date
Air — round-trip Each direction independently Pro-rata by fare per direction (or 50/50 if undifferentiated)
Air — multi-segment Per segment Pro-rata by fare per segment, or all on last segment per partner policy
Hotel — short stay Check-in date 100%
Hotel — long stay (policy-driven) Pro-rata across stay nights Per-night recognition
Tour package Tour start date 100%
Tour package (long, milestone) Per-milestone Per partner policy
Insurance Pro-rata over policy period Daily / monthly
Service fee (any) At issuance 100% immediately
Cancellation fee At cancellation event 100%

5.4 The monthly recognition run

A scheduled job (revenue.recognition.run) executes nightly and at period-close:

  1. Identify all bookings with unrecognised deferred balance and any service_date <= today (or <= period_end at close).
  2. For each booking, compute the recognition-eligible amount per the rules.
  3. Group by account / dimensions and post a single recognition JE per partner per night.
  4. Update booking_revenue_recognition_log with what was recognised, when, and by which JE.
  5. Generate a recognition report.

This is idempotent — running it twice does not double-recognise; the log table prevents re-entry.

5.5 Pro-rata segment recognition (worked example)

Beta Corp issues EK round-trip DAC-DXB outbound May 28, return Jun 10. Commission BDT 7,200 total.

Allocation policy: 50/50 by direction. - BDT 3,600 deferred until May 28 → recognised on May 28 against May P&L. - BDT 3,600 deferred until June 10 → recognised on June 10 against June P&L.

Recognition JEs:

May 28:

Debit  2031 Deferred Air Revenue          3,600  booking_id=..., supplier=EK, direction=outbound
Credit 4011 Air Base Commission           3,600  booking_id=..., supplier=EK

Jun 10:

Debit  2031 Deferred Air Revenue          3,600  booking_id=..., supplier=EK, direction=inbound
Credit 4011 Air Base Commission           3,600  booking_id=..., supplier=EK

If the customer no-shows the return flight, the deferred BDT 3,600 still recognises on Jun 10 (the airline has performed by readying the seat — the no-show is the customer's election; per IFRS 15 the obligation was satisfied or extinguished).

5.6 Refund effect on recognised vs deferred

Refunds (Chapter 4.3) interact with deferred revenue differently depending on whether recognition has occurred:

Scenario Treatment
Refund before service date Reverse the deferred-revenue posting; no P&L impact
Refund after service date (full) Reverse the recognised revenue in current period (reduction of revenue), not back-dated
Partial refund Proportional reversal of recognised + deferred buckets

This is why commission recall on refund matters: it must touch the right side (deferred 2031 or earned 4011) depending on when the refund occurs vs. service date.

5.7 No-show treatment

A booking flagged NO_SHOW after the service date still recognises revenue: - The airline has performed (seat was ready). - The supplier obligation is satisfied (BSP-payable still owed; commission still earned). - Customer side: if the ticket was non-refundable, no AR adjustment.

The platform treats no-show as "performed by the supplier" and recognises accordingly.

5.8 Period-end run vs. nightly run

Run Purpose
Nightly Catch up day-by-day; keeps month-to-date P&L accurate for managers
Period-close Final sweep; locks the month; full disclosure report

The period-close run is part of the soft-close → close → lock flow (Chapter 5.10).

6. Inputs → processing → outputs

Recognition run

Input: as_of_date (defaults to current).

Processing: 1. Lock recognition log table (Redis distributed lock per partner). 2. Query bookings with (deferred_balance > 0) AND (next_recognition_date <= as_of_date). 3. For each booking, compute per-segment / per-line allocation. 4. Skip booking-segment combinations already in booking_revenue_recognition_log. 5. Group and post recognition JE(s). 6. Append log rows. 7. Generate per-account recognition summary. 8. Release lock.

Output: {recognised_total_by_account, je_ids[], booking_count, segment_count}.

7. Module dependencies

Direction Module
Depends on Booking, JE Engine, FX, Period Management
Depended on by Reporting (P&L), Audit, Period Close

8. Security & permissions

Permission Allows
revenue_recognition.run.platform Trigger run manually
revenue_recognition.view.partner View recognition reports
revenue_recognition.policy.update.partner Change partner allocation policy
revenue_recognition.override.platform Manual override of a recognition (rare; full audit)

9. Validation rules

Code Condition
RECOGNITION_BOOKING_NO_SERVICE_DATE Booking missing service_date_start
RECOGNITION_DOUBLE_ATTEMPT Idempotency check stopped re-entry
RECOGNITION_PERIOD_CLOSED as_of_date in closed period; only platform admin can override
RECOGNITION_POLICY_INCONSISTENT Per-segment policy chosen but no per-segment fare attached
RECOGNITION_FX_RATE_MISSING Service-date FX rate not available for translation
RECOGNITION_NEGATIVE_DEFERRED Deferred balance negative (likely refund overshoot)

10. Error handling

  • Missing service dates surface as a pre-recognition validation report; bookings are listed for operations to remediate; the run proceeds for valid bookings.
  • A failed recognition leaves the run rollback-safe; idempotency guarantees re-run cleanliness.

11. Real-world examples

A — Simple round-trip recognition cycle

May 15: issuance. Commission 7,200 deferred. Outbound May 28, return Jun 10.

Date Action JE
May 15 Issuance Cr 2031 7,200
May 28 Recognition (outbound) Dr 2031 / Cr 4011 — 3,600
Jun 10 Recognition (return) Dr 2031 / Cr 4011 — 3,600
May 31 P&L Air Commission 3,600
Jun 30 P&L Air Commission 3,600

B — Refund mid-cycle

Same booking; customer cancels Jun 2 (outbound flown, return not). - Outbound recognised already (3,600 in May). - Return deferred not yet recognised (3,600 still in 2031). - Refund: - Reverse deferred portion: Dr 2031 3,600 / Cr 1101 AR 3,600 (no P&L impact). - Outbound revenue stays in May (no back-dating). - Penalty / fees per Chapter 4.3.

C — Insurance policy pro-rata

Customer buys annual travel insurance BDT 12,000 partner-side commission BDT 1,200 on Jan 1. - Issuance: Cr 2035 Deferred Insurance Revenue 1,200. - Nightly run recognises BDT 100/month on the last day of each month. - By Dec 31, BDT 1,200 fully recognised; deferred balance zero.

12. Step-by-step workflow

sequenceDiagram autonumber participant SCH as Scheduler (cron 02:00) participant RR as Recognition Engine participant DB as MySQL participant JE as JE Engine SCH->>RR: run(as_of_date=today) RR->>DB: SELECT bookings WHERE deferred > 0 AND next_rec_date <= today loop For each booking RR->>DB: Read recognition_log RR->>RR: Compute allocation alt Already recognised (idempotent) RR->>RR: Skip else New recognition RR->>JE: Build JE lines (Dr deferred / Cr earned) end end RR->>JE: Post batched JE per partner JE->>DB: INSERT journal_entries + lines + recognition_log JE-->>RR: je_ids[] RR-->>SCH: summary

13. Database tables touched

Table Role
bookings service_date_start, service_date_end
booking_segments / _rooms / _services Per-segment recognition triggers
booking_revenue_recognition_log Idempotency + audit trail
partner_recognition_policies Allocation rules per partner
journal_entries / _lines
fx_rates Translation at recognition date

14. Future scalability

  • Continuous recognition — switch from nightly batch to event-driven (segment-flown webhook from supplier) for real-time P&L.
  • ML-anomaly detection — flag bookings where service-date is materially different from expected (data-quality signal).
  • Multi-element bundling under IFRS 15 §22 — for tours combining flight + hotel + transfer, stand-alone-selling-price allocation logic for unbundling.

15. Common pitfalls

  • ⚠️ Recognising at issuance, not at service date. This is the single most common mis-application of IFRS 15 in travel.
  • ⚠️ Forgetting to recognise no-shows. They are performed obligations; recognise.
  • ⚠️ Back-dating refunds to original period. Don't. The reversal is a current-period event for the recognised portion.
  • ⚠️ Allocating multi-segment 100% to first segment. Acceptable only if explicit partner policy. Default is per-direction or per-segment.
  • 🔒 Recognition log must be append-only. Editing it conceals revenue manipulation; treat as financial record.