Chapter 4.6 — ADM (Agency Debit Memos) & ACM (Agency Credit Memos)
1. Purpose
ADMs and ACMs are post-issuance financial adjustments raised by airlines through the BSP / ARC settlement system against an agent. An ADM charges the agent (debit); an ACM credits the agent. This chapter defines how travoBooks ingests, validates, posts, disputes, and reports on memos — preserving the link from memo to the originating ticket, booking, customer, and JE.
2. Why it matters in modern travel accounting
ADMs are the single largest source of unpredictable financial leakage for travel agents. Industry surveys consistently report ADM impact in the range of 0.3–1.5% of total ticket sales. Causes include: - Fare-rule violations (wrong booking class) - Improper voids / refunds - Late ticketing past timelimit - Duplicate bookings / churning - Incorrect commission claimed - Tax computation errors
Without a disciplined ADM workflow, agents discover the loss only when BSP cash is debited, by which time the dispute window may have closed.
3. Industry relevance
The platform aligns with IATA Resolution 850m (now 818g in 2026 revisions) ADM lifecycle: raised → notified → dispute window (typically 30–60 days depending on BSP) → final → settled in next BSP cycle.
4. Compliance considerations
- IFRS 15 — ADM is a contract modification or a correction of previously recognised revenue; treatment depends on cause.
- Audit — auditors examine ADM trend; sudden spikes flag operational weakness.
- BSP rules — local BSP authorities define dispute timelines and final-decision processes.
5. Business logic
5.1 Memo states
| State | Description |
|---|---|
RECEIVED |
Memo imported from BSPlink / supplier file |
LINKED |
Successfully matched to originating ticket/booking |
UNLINKED |
Could not match (orphan — manual research needed) |
UNDER_REVIEW |
Internal review pending |
DISPUTED |
Formal dispute filed with airline |
DISPUTE_REJECTED |
Airline upheld memo |
DISPUTE_ACCEPTED |
Airline reversed memo (becomes ACM offset) |
ACCEPTED |
Partner accepts memo; no dispute |
SETTLED_IN_BSP |
Cleared in BSP cycle |
WRITTEN_OFF |
Cost absorbed; classified to write-off account |
RECOVERED_FROM_CUSTOMER |
Recovered onward to customer where applicable |
5.2 Memo record structure
| Field | Type | Notes |
|---|---|---|
memo_id |
BIGINT PK | |
partner_id |
BIGINT FK | |
memo_type |
ENUM(ADM, ACM) |
|
memo_number |
VARCHAR(32) | Airline-assigned |
airline_code |
CHAR(3) | IATA code |
bsp_country_code |
CHAR(2) | |
bsp_period |
VARCHAR(16) | e.g., 2026-05-H2 |
currency |
CHAR(3) | |
amount |
DECIMAL(18,2) | Positive (sign by type) |
cause_code |
VARCHAR(32) | Airline reason code |
cause_description |
TEXT | Free-form |
originating_ticket_number |
VARCHAR(16) NULL | Linked ticket |
booking_id |
BIGINT FK NULL | If linked |
state |
ENUM | |
received_at |
DATETIME | |
dispute_deadline |
DATE | Computed per BSP |
disputed_at |
DATETIME NULL | |
dispute_reference |
VARCHAR(64) NULL | Airline / BSPlink ref |
resolved_at |
DATETIME NULL | |
customer_recovery_id |
BIGINT NULL | If passed to customer |
write_off_je_id |
BIGINT NULL | |
imported_from_file_id |
BIGINT FK | Source BSPlink file |
| Audit columns |
5.3 Linking algorithm
When a memo file is imported:
1. Parse memo lines per BSPlink schema.
2. For each memo, attempt link by (ticket_number, airline_code).
3. If matched, set booking_id and state = LINKED.
4. If no match, search by (passenger_name, segments, issue_date_range) for likely candidates.
5. Present unmatched memos to operations for manual link / mark-orphan.
Orphan memos are typically: - Tickets issued before travoBooks onboarding (pre-platform inventory) - Tickets issued by another agency code mistakenly hitting our partner - Data-quality issues in BSPlink file
5.4 Financial posting
On ADM acceptance / settlement:
Debit 5041 — ADM Expense X (per cause classification)
Credit 2011 — BSP Payable X (settled in next BSP)
If the ADM is recoverable from a customer (e.g., customer-caused name change penalty), a parallel JE recovers:
Debit 1101 — AR Customer X
Credit 5041 — ADM Expense (recovery) X
(Effectively net-zero impact to expense if fully recovered.)
On ACM acceptance:
Debit 2011 — BSP Payable X (reduces what we owe)
Credit 7041 — ACM / Other Recovery X
On dispute success (ADM reversed):
Original ADM posting reversed with a reversing JE.
5.5 Cause-code classification
Airline cause codes are mapped to internal cause categories for reporting:
| Category | Examples |
|---|---|
FARE_VIOLATION |
Wrong booking class, expired fare |
TICKETING_TIMELIMIT |
Past TL, churn |
COMMISSION_DISPUTE |
Wrong commission, override claim invalid |
TAX_ERROR |
Tax under/over collected |
DUPLICATE_BOOKING |
Same pax same route same date |
IMPROPER_VOID |
Void after deadline |
NAME_CHANGE_PENALTY |
Customer-caused (usually recoverable) |
OTHER |
Reporting aggregates by category to drive operational improvement.
5.6 Dispute workflow
- Operations team flags memo for dispute (within window).
- Drafts dispute narrative + attaches evidence (PNR history, fare-rule snapshot, supplier emails).
- Files dispute via BSPlink portal OR through travoBooks' BSPlink API integration.
- Sets state to
DISPUTED; tracks reference. - Airline responds within local-BSP timeframe.
- Outcome posted; state updated.
While disputed, the memo is provisioned (booked as a contingent liability) but not realised as final expense.
5.7 Customer recovery
If a memo cause is customer-attributable (e.g., name correction penalty), the recovery workflow:
1. Operations identifies recoverable amount.
2. Generates a debit note invoice line on the customer's account.
3. Customer pays alongside next invoice (or in lump sum).
4. JE: Debit AR Customer / Credit ADM Expense.
6. Inputs → processing → outputs
Import memos
Input: Daily BSPlink memo file (CSV/HOT format).
Processing: 1. Idempotency-check file by checksum. 2. Parse rows into staging table. 3. Apply linking algorithm. 4. Persist memo records. 5. For provisional postings (un-disputed by deadline), schedule auto-acceptance JE. 6. Notify operations of new memos.
Output: Import summary (count, total amount, linked %).
7. Module dependencies
| Direction | Module |
|---|---|
| Depends on | Booking, Ticketing, BSP Import (Ch 11.3), JE Engine, Period-Close |
| Depended on by | Reporting, AR (customer recovery), Operational analytics |
8. Security & permissions
| Permission | Allows |
|---|---|
memos.read.partner |
View |
memos.link.partner |
Manually link orphan memos |
memos.dispute.partner |
File dispute |
memos.accept.partner |
Accept memo |
memos.write_off.partner |
Write off (above threshold → maker-checker) |
memos.recover.partner |
Generate customer recovery line |
9. Validation rules
| Code | Condition |
|---|---|
MEMO_DUPLICATE_NUMBER |
Same airline memo number imported twice |
MEMO_UNLINKABLE |
No matching ticket and operator chose link |
MEMO_DISPUTE_WINDOW_CLOSED |
Past dispute deadline |
MEMO_AMOUNT_MISMATCH |
Imported amount ≠ stated amount |
MEMO_CURRENCY_MISMATCH |
Currency not in BSP-supported set |
MEMO_PERIOD_CLOSED |
Acceptance posting hits closed period |
10. Error handling
Memos with parsing errors are quarantined; operations works through them. A memo cannot be silently dropped — every memo line in an imported file must result in a memo record (linked, unlinked, or rejected) for full traceability.
11. Real-world examples
Example A — Fare violation ADM, accepted
Airline charges BDT 4,500 ADM for booking-class violation on ticket 176-2400000123 (Beta Corp / EK / DAC-DXB). - Linked to booking BR-2026-000123. - Operations reviews: agent did book wrong class; no dispute basis. - Marked accepted. - JE: Debit ADM Expense (5041, sub-category FARE_VIOLATION) BDT 4,500; Credit BSP Payable BDT 4,500. - BSP cycle settles → cash impact.
Example B — Name-change ADM, recovered from customer
EK charges BDT 6,000 for name correction (customer typo). - Operations flags as recoverable. - JE: Debit ADM Expense BDT 6,000; Credit BSP Payable BDT 6,000. - Customer recovery: debit note line on Beta Corp's next invoice for BDT 6,000 cost-recovery. - JE: Debit AR — Beta Corp BDT 6,000; Credit ADM Expense BDT 6,000 (recovery). - Net impact: zero expense; AR up; BSP-payable up.
Example C — Successful dispute → ACM
Airline raises BDT 12,000 ADM for "duplicate booking" but operations evidence shows the duplicate was a hold that auto-expired (not a real ticket). - Dispute filed via BSPlink with PNR history attachment. - Airline accepts dispute, issues offsetting ACM BDT 12,000 next cycle. - Original ADM JE reversed; ACM JE posted. - Net cash impact: zero.
12. Step-by-step workflow
13. Database tables touched
| Table | Role |
|---|---|
memos |
Memo records |
memo_documents |
Evidence attachments (S3) |
memo_disputes |
Dispute history |
memo_recoveries |
Customer recovery links |
journal_entries / _lines |
Postings |
bsp_import_files |
Source |
audit_logs |
14. Future scalability
- ML-assisted dispute drafting — propose dispute narratives based on memo cause + PNR history.
- Auto-recovery rules — automatically generate customer recovery lines for known customer-caused cause codes.
- Memo-prevention analytics — root-cause analysis per agent, per route, per fare.
- Direct BSPlink API integration — file disputes without manual portal entry.
15. Common pitfalls
- ⚠️ Letting dispute window pass. Hard-deadline; missed = financial loss.
- ⚠️ Posting memo expense before acceptance. Disputed memos should be provisioned, not realised.
- ⚠️ Mis-classifying customer-recoverable memos as agency-cost. Erodes margin.
- ⚠️ Ignoring orphans. Unlinked memos still hit BSP cash; track to root cause.
- 🔒 Memo PII — passenger names appear; redact in non-operational surfaces.