← Resources

Guide · 9 min read · Published 26 September 2026

Cancellations and refunds on subsidised staff travel: who owes what

By Neil Middleton · Co-founder, UnityTrip

The moment staff pay by card for a spare seat on a company aircraft, the organisation becomes an airline, and every cancellation becomes a liability question. This guide sets out the data model that makes refunds decidable, the two ledgers a cancellation can touch, the three ways a refund ledger drifts, and why a decision queue belongs before automation.

Most travel policy writing assumes a fare. Cancel a commercial ticket and the airline's rules decide what comes back; the employer's only job is to reclaim it. A company that operates or leases its own aircraft has no such rules to lean on, and the moment it sells spare seats to staff and their families at a subsidised price, it has to write them. It is now the carrier: it holds the passenger's money, it owes the passenger a seat, and when the passenger cancels it has to decide, defensibly and repeatably, how much goes back.

That decision looks simple on a policy page: a full refund a few days out, half inside two days, nothing inside one. It is not simple in the data, and the gap between the policy page and the data is where operations teams lose weeks. This guide is about closing it. It follows the two-channel model throughout: business travel is approved and paid by the company to itself; private and subsidised travel is unapproved, governed by quota, and paid by the traveller. Cancellation behaves completely differently on each side, which is the first thing to get straight.

The two ledgers a cancellation can touch

On the business side, a seat on a company aircraft has no fare. The company paid for the aircraft whether or not anyone boards, so a business cancellation moves no cash: it is a cost reversal posted to the accounting system against the claim number, cost centre, and period that the booking was charged to. Few rows, large amounts, approval-gated, reconciled to the accounting system every period. The risk is a wrong posting.

On the private side, the traveller paid real money by card and the organisation holds it as a liability until the segment is flown. A cancellation returns the fare less the penalty the rules set for that timing, and the penalty is kept as earned. Many small rows, no approval step, decided by the same people who answer the phone. The risk is that support staff are overwhelmed.

Private and subsidised → card gatewayBusiness → accounting system
MoneyTraveller paid; the organisation is the airlineCompany paid itself; no cash moves
KeyGateway payment referenceClaim number, cost centre, period
CancelFare less penalty returned; penalty keptCost reversal posting, not a refund
ShapeMany small rows, no approval stepFew large rows, approval-gated
ToolDecision queue, recommended amount, one operator, audit logExact posting, maker-checker, reconciled each period
RiskSupport staff overwhelmA wrong posting

The two sides need different tools, and the boundary between them matters: the recommendation logic that helps an operator decide a private refund must never leak into the business side, where the posting is exact or it is wrong. Immutability is ours; the ledger of record is theirs. UnityTrip carries its own travel ledger, authoritative for travel and synchronised through daily balances; the accounting system remains the final ledger of record that consolidates travel with everything else.

State lives per passenger per segment. Money lives per booking.

Here is the trap. A card gateway takes one charge per booking, so there is one receipt, one transaction, and one place to send a refund. It is natural to conclude that "the money lives per booking" and to build the refund as a booking-level calculation. But that is a payment fact, not a pricing fact. Prices are set per seat per direction. Cancellations happen per passenger per segment: one traveller cancels the return leg while the other still flies; three of four passengers cancel while the fourth boards. Eligibility is a rule evaluated per row, at the moment of cancellation, against that row's departure time; only then is the result reconciled to the single payment.

Reschedules make it worse. Moving one passenger's return leg restarts that row's penalty clock and, in most systems, splits the passenger into a new booking, which now carries a seat and a liability but no payment of its own. When that passenger later cancels, the refund belongs to the new booking but must be sent against the original transaction. Airlines solved this decades ago with tickets, flight coupons, and fare components; an organisation selling seats on its own aircraft has to solve it without issuing a ticket.

Freeze a value line at booking

The solution is the coupon model without the ticketing overhead. At booking, freeze a value line for every passenger on every segment, and for every extra: fare, meal, seat selection, baggage, insurance, change fee, card surcharge, booking fee, tax. Each line has an amount that is never recomputed, a status that moves from open to flown, refunded, or void, and a refund rule keyed on its type and timing. Then everything else is arithmetic on rows:

  • The booking total is the sum of its value lines.
  • The residual liability is the total less the refunded lines.
  • A refund is a set of status changes on lines, plus the stored rule outcome and the operator's recorded decision.
  • The recommended refund is the sum of the lines the rules say are refundable, shown line by line so the operator can see fare, taxes, and extras separately.
  • Reconciliation between the gateway, operations, and accounts runs off rows, not recomputed totals.

The price on the line is evidence of what happened, not a claim about the fare table. This is the airline's two-event accounting structure, accrue at booking and recognise at departure, applied one level down. The institutional-memory point applies too: the rule that decided a refund is stored with the decision, so it can be reproduced a year later by someone who was not on shift.

Why deriving the amount at cancellation fails

The alternative, computing the refund from the fare table when the passenger cancels, works only if the pricing function is pure and time is not an input. Fare tables change: a price rises, a route is added, a seasonal rate comes in, a typo is fixed. From that moment every unrefunded booking priced under the old table is unrecomputable, and the refund screen offers the wrong amount without anyone knowing until a complaint. Versioning the table is a possible patch, but it turns the fare table into an immutable ledger where no row may ever be edited in place, and in practice someone edits a row in place within months.

There is a second reason, specific to how private refunds are actually decided. They are decided by a single operator, usually without a second approver, with every decision recorded. That record is only auditable if the recommended amount it was made against can be reproduced later. A stored value line gives that; a figure derived from the fare table "as it stood that afternoon" does not.

Where extras and fees sit

Not every line belongs at the passenger-segment level, and getting the level wrong produces refund arguments over trivial sums.

  • Per passenger per segment: meals, seat selection, excess baggage, assistance. These follow the segment and usually carry a refund rule that differs from the fare's.
  • Per passenger, not per segment: insurance, lounge access, a change fee already paid. Insurance is generally non-refundable once cover starts; a change fee is non-refundable full stop.
  • Per booking: card surcharge, booking fee, service fee. Two questions to settle with the organisation, not assume: is the card surcharge a pass-through of the gateway's cost or a fee the organisation keeps, and on a partial cancellation does a booking-level fee refund in full, proportionally, or not at all? Airlines typically choose "not at all" or "in full only when the whole booking is cancelled". Proportional works but invites rounding disputes.
  • Taxes and passenger charges: per departing passenger, so passenger-segment level, and usually refundable even when the fare is not, because the charge was never incurred if the passenger did not fly. If the organisation collects any government passenger charge on its seats, that line refunds regardless of penalty and must show separately on the queue screen.

One more question to close before building: are seats ever priced as a return bundle rather than two one-way directions? If never, every coupon maps to a component and refunding one segment is arithmetic. If sometimes, fix the split at booking, for instance 50/50, and never recalculate at refund time. Recalculating the unused half of an indivisible return fare under the fare rule is the branch where complexity explodes, and the advice from airline revenue accounting has long been to simplify the cancellation rules so that branch does not exist.

A worked example

Two passengers, A and B, book a return between a site and a hub at 300 a segment, paid as one card transaction of 1,200. Then five events happen. Amounts are in units; the shape is what matters.

  1. Booked and paid: two passengers, return, 1,200 in one transaction.
  2. B's return leg is rescheduled. The system splits B's rows into a second booking, which carries a non-refundable change fee of 20 paid as a second transaction, and no other payment of its own.
  3. The outbound flies. A and B depart.
  4. A cancels the return 40 hours out. The rule for that timing keeps 50%.
  5. B cancels the return 80 hours out. The rule for that timing returns the full fare; the change fee is kept.
Row1 Booked2 Rescheduled3 Outbound flies4 A cancels5 B cancels
A · outPaidPaidFlownFlownFlown
A · returnPaidPaidPaidCancel, 50%Refund 150
B · outPaidPaid (b2)Flown (b2)Flown (b2)Flown (b2)
B · returnPaidMoved (b2)Moved (b2)Moved (b2)Refund 300
B · change fee—Paid 20 (b2)KeptKeptKept
Liability held1,2001,2006003000
Earned (flown and fees)020620620620
Refunded000150450
Penalty kept000150150
Organisation banks020620770770

(b2) marks rows that moved to the second booking at event 2. Every column adds to 1,220: what came in is always liability held, plus earned, plus refunded. B's refund of 300 in the last column belongs to booking 2 but must be sent against the first transaction; booking 2's own transaction is the 20 fee, which is kept. A system that only knows booking totals cannot produce this table. A system with value lines produces it as a by-product.

Left out of the simplified view, and each one adds a row, a rule, or a reason the totals stop adding up: taxes; landing and card surcharges; expense claims; fare-class or terms changes on reschedule; chargebacks; the currency the gateway settles in versus the currency the ledger reports in, which needs a line of its own; company-initiated schedule changes; and no-shows, which are a subject in themselves.

The three ways a refund ledger drifts

Before designing anything, reconcile what the platform believes about refunds to what the card gateway has actually done. The gateway is the control point: money either left or it did not. In practice three patterns account for most of the drift a review finds.

  1. A full refund recorded as zero. A "full refund" control records a zero-amount event and omits the amount in the call to the gateway, which treats a missing amount as a full refund. The money goes back; the platform thinks it is still held. Record the real amount, always send an explicit amount, and backfill historical zero-amount events from the gateway's refund records.
  2. A request never closed by the event that fulfilled it. The traveller's refund request and the refund that actually happened are two objects that were never linked, so requests sit at "acknowledged" or "started" for months after the money moved. On every refund recorded, find the open request on the booking and close it with the amount, date, and gateway reference. Backfill the open ones.
  3. A refund made outside the platform. Someone processes a second refund directly in the gateway dashboard and no confirmation reaches the platform, so the ledger is wrong by exactly that amount. Across hundreds of cancellations this is usually an outlier rather than a pattern, so correct the record, surface any gateway refunds the platform did not originate, and do not rebuild the transport for one case.

Gateway refunds that need attention on the gateway side, for instance where bank details were not captured at payment and a retry needs manual entry, are typically invisible in the operations tool. Surface them; do not try to fix them from the platform.

A decision queue before automation

The request that usually arrives is for automatic refunds: calculate on cancellation, apply the penalty bands, initiate the refund, notify the traveller. It is the obvious thing to want and the wrong thing to build first. Automation applied to a booking-level total on top of a ledger that has drifted produces wrong refunds at machine speed, and the first time it does, every refund it ever made comes under question.

Build the queue first. A screen in the operations tool that lists every cancellation needing a refund, new ones appearing automatically, with everything needed to decide on one screen; a recommended amount shown line by line and explicitly non-binding; a single operator who decides; a full audit log of who, how much, when, and the comment that explains why; an "ignore" flag for the historical backlog; and a status view for finance showing treated, outstanding, and refund state. Then reconcile the queue to the gateway for a period. Automation, when it comes, is a rule applied to a queue that is already correct. This is the discipline that runs through the platform: the engine proposes, the person with the operation in their head decides, and the record shows both.

It is also the honest answer to a question every organisation should ask of any system that offers to fix its processes with AI. The recommendation is only as good as the record it is derived from, and the record is only trustworthy once someone who ran the operation has reconciled it. Diagnosis from a reconstructed process, judged by a probabilistic model, needs a person who can say no. Build that person into the method.

Questions to settle before building

  • Are fares ever priced as a return bundle rather than two one-way directions? If never, the split problem is closed.
  • What extras are actually sold? Get the real list; do not invent rules for hypothetical extras.
  • Is the card surcharge a pass-through or retained, and does the gateway return its fee on a partial refund?
  • On a partial cancellation, does a booking-level fee refund in full, proportionally, or not at all?
  • Are any government taxes or passenger charges collected on the seats? If so, they refund regardless of penalty.
  • Does the traveller get an email on cancellation, or an in-screen confirmation? Decide it; do not let it default.

Common questions

How should refunds work when staff pay for seats on company aircraft?

Treat the organisation as the airline. Each paid seat is a liability to the passenger from the moment of payment until the segment is flown; a cancellation returns the fare less the penalty the rules set for that timing, and the penalty is kept as earned. Refunds are decided per passenger per segment against a value frozen at booking, then reconciled to the single card payment that covered the booking. A decision queue with a recommended amount and a full audit trail should come before any automation.

Why does the money live per booking but the refund live per passenger per segment?

Because payment and pricing are different facts. A card gateway takes one charge per booking, so there is one receipt and one transaction to refund against. But prices are set per seat per direction, and cancellations happen per passenger per segment: one traveller cancels a return leg while the other still flies. Eligibility is a rule evaluated per row at cancellation time against that row's departure; the refund is then sent against the one payment. A system that only holds the booking total cannot do this.

What is a value line in a booking?

The amount attached to one passenger on one segment, or to one extra such as a meal, a seat, or a change fee, frozen at the time of booking and never recomputed. It is the equivalent of an airline flight coupon and fare component without a ticket being issued. Each line carries a status (open, flown, refunded, void) and the refund rule that applies to its type. The booking total is the sum of its lines; the residual liability is the total less refunded lines; a refund is a set of status changes on lines plus the operator's recorded decision.

Why not calculate the refund from the fare table when the passenger cancels?

Because fare tables change. Once a price rises, a route is added, or a typo is fixed, every unrefunded booking priced under the old table becomes unrecomputable, and the refund screen offers the wrong amount without anyone knowing until a complaint. Versioning the fare table is fragile in practice; someone edits a row in place within months. Freezing a value per passenger per segment at booking makes the price evidence of what happened rather than a claim about the fare table, and makes every later refund decision reproducible for audit.

Should a cancellation refund be automatic?

Not until the per-passenger-segment state model exists and has been reconciled against the payment gateway for a period. The practical first step is a queue in the operations tool listing every cancellation that needs a refund, with all the information to decide on one screen, a non-binding recommended amount shown line by line, a single operator who decides, and a full audit log of who, how much, when, and why. Automation then becomes a rule applied to a queue that is already correct, rather than a calculation applied to data that is not.

How are business travel cancellations different from private travel cancellations?

Business travel on a company fleet is paid by the company to itself, so no cash moves and a cancellation is a cost reversal posted to the accounting system against the claim number, not a refund. Private and subsidised travel is paid by the traveller by card, so the organisation holds a real liability and a cancellation returns real money through the gateway. The two sides need different tools: exact postings with maker-checker on the business side; a human decision queue with a recommended amount on the private side. The recommendation logic must never leak into the business side.

What are the most common ways a refund ledger goes wrong?

Three patterns account for most drift. A full refund recorded as a zero-amount event, so the platform thinks the money is still held while the gateway has already returned it. A refund request that is never linked to the refund event that fulfilled it, so requests stay open forever. And a refund made directly in the gateway dashboard that never reaches the platform, so the ledger is wrong by exactly that amount. Reconciling the platform's refund state to the gateway's is the control point, and it is the first thing a review checks.

How does UnityTrip handle cancellations and refunds?

Penalty bands, seasons, and surcharges are configuration on the fare class. The per-passenger-segment state model is built once: value lines frozen at booking, statuses that move from open to flown or refunded, rule outcomes stored with each decision. Private-channel refunds run through a decision queue with a recommended amount and an audit trail; business-channel cancellations post as cost reversals to the accounting system of record. See the traveller-touch test for where the travel ledger ends and the ledger of record begins.

Go deeper

From the record to the fix

A cancellation and refund review starts by reconciling what your platform believes to what your gateway has done, then ranks what it finds by the money involved. Findings are yours whether or not you go further. See how a review works →

Talk to us