PNR হলো GDS-এ সংরক্ষিত বুকিংয়ের রেকর্ড। travoBooks স্থানীয়ভাবে বুকিং সংরক্ষণ করে এবং supplier_record_locator ফিল্ডে PNR ট্র্যাক করে। ইস্যুয়েন্স ক্রিটিক্যাল: GDS কল ডিবি ট্রানজ্যাকশনের বাইরে (অরফান টিকেট প্রতিরোধে reconciler সিস্টেম)।
Chapter 4.2 — Ticketing & PNR Management
1. Purpose
This chapter defines how travoBooks interfaces with airline reservation systems to create, hold, modify, and ticket PNRs (Passenger Name Records), and how the issued e-ticket and its TST (Transitional Stored Ticket) records map into platform state. It covers GDS-issued (BSP) and NDC-issued workflows, fare-rule capture, the ticketing time-limit enforcement, and the distinction between PNR creation (a hold) and ticketing (a financial event).
2. Why it matters in modern travel accounting
Ticketing is the financial trigger in air travel — it is the moment at which the supplier (airline, via BSP) and the partner (agent) crystallise an obligation. Mis-handling ticketing produces: - ADMs — unticketed PNR fees, churn fees, ticket-after-departure fees - Revenue loss — lost commission from late ticketing - Customer disputes — wrong name on ticket, wrong fare booked, no e-ticket issued - Settlement errors — BSP file mismatches
Modern travel accounting depends on a precise model of PNR vs ticket vs settlement.
3. Industry relevance
The PNR / ticket model in travoBooks mirrors IATA's Resolution 722g and the underlying EDIFACT / NDC schemas. Industry vocabulary (PNR, TST, fare basis, ATPCO, EMD, ticket image) is preserved verbatim so that staff trained on Amadeus / Sabre / Travelport recognise the system immediately.
4. Compliance considerations
- IATA Resolution 850m — agent code on every ticket, accurate fare construction.
- BSP rules — ticketing deadlines, void windows, name-change restrictions vary by country.
- IFRS 15 — ticket issuance is the customer-side performance-obligation trigger; service is not delivered until the flight is flown but the supplier obligation crystallises now.
- Tax invoices — many jurisdictions require ticket-level tax breakdown (YQ/YR carrier-imposed surcharge, government taxes) for VAT recoverability.
5. Business logic
5.1 PNR vs Ticket
| Concept | Definition | travoBooks table |
|---|---|---|
| PNR | Passenger Name Record — supplier-side reservation; identifies traveller(s), segments, contact info; tracked by record locator (ABC123). May exist without a ticket. |
booking_pnrs |
| TST | Transitional Stored Ticket — fare calculation attached to PNR; defines what would be issued; expires at fare timelimit. | booking_tsts |
| Ticket | Actual financial document — 13-digit e-ticket number; the obligation that BSP settles. | booking_tickets |
| EMD | Electronic Miscellaneous Document — for ancillaries (bag, seat, lounge) tied to the same passenger; settled like a ticket. | booking_emds |
A booking may contain: 1 PNR, 1+ TSTs (one per fare component), 1+ tickets (one per passenger), 0+ EMDs.
5.2 PNR creation flow
- Agent (or API consumer) builds a booking from offer selection.
- travoBooks sends
Air_SellFromRecommendation(Amadeus) /OTA_AirBookRQ(Sabre) /OrderCreate(NDC). - Supplier returns record locator + segment statuses.
- travoBooks stores
booking_pnrs.record_locator,pnr_status,created_at,timelimit_at. - Booking moves to
HELD.
5.3 TST & fare timelimit
When a fare is quoted and attached:
1. travoBooks calls Fare_PricePNRWithBookingClass / OrderPriceRQ.
2. Supplier returns one or more TSTs with timelimit and currency.
3. travoBooks stores TST snapshot in booking_tsts (with raw XML / JSON for audit).
4. The earliest TST timelimit becomes the booking's ticketing_deadline.
The scheduler enforces the deadline:
- T-24h → email reminder to selling agent + mid-office.
- T-2h → SMS escalation.
- T-0 → auto-action per partner config (auto_void_at_timelimit, auto_extend_via_supplier, or keep_open).
5.4 Ticketing (issuance)
- Pre-flight validation: payment status (cash) OR credit available (corporate); TST still valid; PNR fares unchanged on re-price.
- travoBooks calls
Ticket_CreateTSTFromPricing→DocIssuance_IssueTicket(Amadeus) /OrderChangewithIssuanceRQ(NDC). - Supplier returns ticket number(s).
- travoBooks persists
booking_ticketsrows:ticket_number,pax_id,tst_id,issued_at,commission_pct,commission_amount,tax_breakdownJSON. - Posts JE in the same DB transaction as ticket persistence (Chapter 4.1 invariant).
- Generates e-ticket PDF, attaches to booking documents.
- Emits
ticket.issuedevent.
5.5 Fare components & tax breakdown
A ticket's tax_breakdown captures each XT (tax code) line as returned by the GDS:
[
{ "code": "BD", "name": "Bangladesh Departure Tax", "amount": 500, "currency": "BDT" },
{ "code": "YQ", "name": "Carrier Imposed Surcharge", "amount": 12000, "currency": "BDT" },
{ "code": "YR", "name": "Carrier Imposed Misc", "amount": 800, "currency": "BDT" }
]
This drives: - VAT-recovery reporting (carrier-imposed vs government taxes differ in deductibility) - Tax-invoice line items per jurisdiction - BSP file matching (BSP lists per-tax amounts)
5.6 Reissue (exchange)
Reissue replaces an existing ticket with a new one for the same passenger.
- Original ticket marked
status = REISSUED,replaced_by_ticket_idset. - New ticket inserted with
replaces_ticket_idlink. - Fare difference JE: debit AR (customer pays more) or credit AR (residual to customer credit balance).
- Reissue fee applied per fare rules / partner config.
- Commission recall: original commission may be partially clawed back; new commission accrued on new fare.
5.7 Void
Same-day void (per supplier rules; typically same calendar day in PNR/BSP country timezone):
1. Validate void window not closed.
2. Call supplier void endpoint.
3. Mark ticket status = VOIDED, voided_at.
4. Reversing JE posts (full reversal of issuance JE).
5. Customer refund (cash) or AR reduction (credit) posted.
5.8 EMD (ancillaries)
EMDs are handled identically in lifecycle but with their own document numbers and a link to the parent ticket. Bag fees, seat fees, lounge access, premium meal — each generates a separate EMD with its own settlement.
5.9 ATPCO / fare basis preservation
The platform stores the fare basis code (e.g., KLOWBD, YOWFLEX) and the full fare rules text. This is non-negotiable: when a customer asks "can I refund?" or "can I change?", the answer comes from the captured fare rules, not from generic policy.
6. Inputs → processing → outputs
Issue ticket from priced PNR
Input: booking_id (state = HELD with priced TSTs), payment_status = OK or credit available.
Processing: 1. Validate state, payment, credit, TST validity. 2. Begin DB transaction. 3. Call supplier issuance API (idempotent — replays return existing ticket numbers). 4. Persist tickets, EMDs. 5. Compute and post JE. 6. Update booking state → ISSUED. 7. Commit. 8. Async: generate e-ticket PDF, dispatch emails, fire webhooks.
Output: Array of ticket numbers, e-ticket PDF URL, JE reference.
7. Module dependencies
| Direction | Module |
|---|---|
| Depends on | Booking, Customer, Supplier, Tax Config, Payment, JE Engine, Supplier Integration |
| Depended on by | Refund, Reissue, Void, BSP Import (matches our tickets to BSP records), ADM/ACM (memos reference ticket numbers) |
8. Security & permissions
| Permission | Allows |
|---|---|
tickets.read.partner |
View tickets |
tickets.issue.partner |
Trigger issuance |
tickets.void.partner |
Same-day void |
tickets.reissue.partner |
Reissue |
tickets.refund.partner |
Refund (delegates to refund module) |
Ticket numbers themselves are not secret but treated as PII for log-redaction in customer-facing surfaces.
9. Validation rules
| Code | Condition |
|---|---|
TICKET_TST_EXPIRED |
TST timelimit passed |
TICKET_PRICE_CHANGED |
Re-price returned different total |
TICKET_NAME_MISMATCH |
PNR name differs from booking traveller |
TICKET_DUPLICATE_ISSUE |
Idempotency check found existing ticket |
TICKET_VOID_WINDOW_CLOSED |
Void attempted past window |
TICKET_VOID_DIFFERENT_BSP_DAY |
Void attempted in different BSP day from issue |
TICKET_REISSUE_SAME_FARE |
Reissue would not change fare (suggest void+rebook) |
TICKET_FARE_RULE_VIOLATION |
Operation violates captured fare rules |
TICKET_EMD_PARENT_VOIDED |
EMD operation on ticket already voided |
TICKET_SUPPLIER_REJECTED |
Supplier rejected — error preserved |
10. Error handling
Supplier rejections at issuance are particularly sensitive: the PNR may have been auto-cancelled supplier-side. travoBooks captures the raw error, marks booking state safely (back to HELD or to ERROR), notifies the agent, and does not post any JE for a failed issuance.
If issuance succeeded supplier-side but the response failed mid-transmission, the idempotency-key replay recovers the ticket numbers on the next attempt.
11. Real-world examples
Example A — Standard BSP ticket issuance
Beta Corp booking: 1 passenger, EK DAC-DXB, USD 600 base + USD 80 YQ + USD 50 government taxes = USD 730.
Booking HELD with PNR ABC123, TST timelimit 2026-05-28 23:59
→ Agent triggers issue
→ Supplier returns ticket 176-2400000123
→ JE posted (per Chapter 5.1 example)
→ Booking ISSUED
→ E-ticket PDF emailed to Beta's travel coordinator
Example B — Reissue with fare difference
Customer changes return date; new fare USD 800.
Original ticket 176-2400000123 marked REISSUED
New ticket 176-2400000456 issued
Fare difference USD 70 (800 − 730) + USD 25 reissue fee
JE: Debit Customer AR USD 95
Credit Supplier/BSP Payable USD 70
Credit Reissue Fee Revenue (4032) USD 25
Original commission USD 36 partially recalled — JE adjusts commission receivable
Example C — Late void prevented
Agent attempts to void at 23:55 local but supplier BSP day rolled over at 23:59 UTC.
Validation rule TICKET_VOID_DIFFERENT_BSP_DAY fires
Operation rejected with explanation
Refund workflow suggested instead
12. Step-by-step workflow
13. Database tables touched
| Table | Role |
|---|---|
booking_pnrs |
Supplier PNR records |
booking_tsts |
Fare-price snapshots |
booking_tickets |
Issued tickets |
booking_emds |
Ancillary documents |
booking_tax_breakdown |
Per-XT tax lines |
booking_fare_rules |
Captured fare-rule text |
journal_entries / _lines |
Financial impact |
audit_logs |
Operational events |
booking_history |
State transitions |
14. Future scalability
- NDC OrderManagement — for NDC-native suppliers, the order-and-offer model replaces TST/ticket semantics; abstraction layer planned.
- ATPCO fare-rule parser — structured parsing of fare rules so customer-facing change/refund quotes are computed automatically rather than requiring an agent to read the text.
- BSP file watermarking — each issued ticket pre-marked with BSP-period; the import job matches with zero ambiguity.
- Multi-leg single-record-locator support for round-the-world itineraries.
15. Common pitfalls
- ⚠️ Issuing without re-pricing. Always re-price immediately before issue; supplier fares change.
- ⚠️ Treating PNR creation as a financial event. It is not — only ticketing is.
- ⚠️ Letting a TST expire silently. Without the timelimit job you accumulate ADM exposure.
- ⚠️ Voiding in customer-local time instead of BSP-country time. Use the BSP country's timezone for the void window.
- ⚠️ Losing the fare-basis code. Without it, refund quotes become guesswork.