Refund lifecycle & statuses
Every status a refund can take, what coupon statuses mean, how decisions are made, and how to track a refund to its final outcome — so you never have to discover a state by testing.
1. The lifecycle at a glance
- Quote —
createQuotereads the ticket from the airline system (GDS/PSS), applies refundability rules, and produces a refund candidate with amounts and a decision. - Acceptance —
processRefundsubmits the candidate. A successful response means accepted and queued, not done. - Execution — the fulfillment engine performs the refund in the GDS/PSS and writes a terminal status:
REFUNDEDorERROR.
"Queued for processing" is an acknowledgment, not an outcome. The final result arrives later — track it with webhooks or polling (section 5).
2. Refund candidate statuses
| Status | Meaning | Terminal? | Set by |
|---|---|---|---|
NEW | Created from a quote, not yet actionable | No | Engine |
READY | Approved; fulfillment will pick it up | No | Client or rules |
REVIEW | Held for manual review | No | Client or rules |
SKIP | Excluded from processing | Effectively | Client or rules |
REFUNDED | Executed successfully in the airline system | Yes | Engine only |
ERROR | Execution failed after acceptance | Yes | Engine only |
REFUNDEDandERRORare written only by the fulfillment engine. Clients can move a candidate toREADY,REVIEW, orSKIP— never to a terminal state.- Terminal statuses never transition again. Retrying the same ticket doesn't change them.
ERRORcarries the failure detail in its error history; contact support with the ticket number if it isn't actionable on your side.
3. Coupon statuses
Each flight segment has a coupon with a status in the airline system; refundability is evaluated per coupon.
3.1 Status reference
Deal Engine normalizes Amadeus web-service codes to standard one-letter ("cryptic") codes. The API returns the normalized code.
| Raw (GDS/PSS) | API returns | Meaning |
|---|---|---|
I | O | Open for use (unused) |
OK | OK | Confirmed, unused |
AL | A | Airport control |
CK | C | Checked in |
BD | L | Boarded / lifted |
B | F | Flown / used |
E | E | Exchanged / reissued |
RF | R | Refunded |
PR | P | Printed |
PE | X | Print exchange |
IO | O | Irregular operations |
NAV | U | Not available |
CLO / Z | Z | Closed |
Q | Q | Revoked by the airline |
S | S | Suspended |
V | V | Void |
Y | Y | Refund taxes/fees only |
Unrecognized codes pass through unchanged. If you receive a code you can't interpret, treat the coupon as not refundable and contact support.
3.2 Which statuses are refundable?
Refundability checks each coupon against a configured non-refundable status list. Default:
CLO, RF, 1, B, C, E, F, G, L, N, P, Q, R, T, U, V, X, Y, Z
Everything else — open coupons (O, I, OK, A, AL) — is refundable. E (exchanged) routes through reissue-chain handling; U/NAV trigger deeper fare-rule evaluation.
Fully configurable. These lists — like nearly every rule on this page — are configured per customer, market, and rule set. The values above are defaults; your configuration agreed with Deal Engine is the source of truth.
3.3 UAT note
Fulfillment is not available in sandbox, so refunds never reach REFUNDED there and coupon statuses don't change. See Testing & environments.
4. Refund decisions
4.1 Decision values
Not a fixed enum — configured per customer and flow. Standard values:
| Value | Meaning |
|---|---|
VOLUNTARY | Passenger-initiated, under fare rules |
INVOLUNTARY | Airline-caused (cancellation, schedule change) — typically penalty-free |
IRREGULAR OPERATIONS | Operational disruption |
VOLUNTARY MILES | Miles-paid ticket — only monetary taxes quoted (see Refund amounts) |
REJECTED | Refused by a configured rejection rule (4.2) |
Your configuration may add variants (e.g. VOLUNTARY_BEFORE_DEPARTURE) or informational reasons (No open coupons found). Deal Engine provides your active list at onboarding.
4.2 When is a refund REJECTED?
Rejections are fully configurable per customer — rejection rules follow your business logic and are set up on demand with Deal Engine. There are no hidden rejection paths: a refund is rejected only when one of your configured rules matches. Example rule:
Reject when a coupon is fail-to-board (
U) and the penalty exceeds remaining fare + fuel surcharge (YR) — the refund would be zero or negative.
How a rejection surfaces depends on your configuration:
- Default (no explicit rejection configuration): the rejection is written to the refund's
notesand the quote returns 0 amount to be refunded. - Explicit rejection status (on request): a dedicated
REJECTEDstatus is added to your quotation statuses, so integrations can branch on the quote status directly instead of inspecting notes and amounts.
Ask Deal Engine to enable the explicit REJECTED quotation status if your integration needs a machine-checkable rejection signal.
4.3 Decision-to-action matrix
| Decision | Meaning | Action |
|---|---|---|
VOLUNTARY / INVOLUNTARY / IRREGULAR OPERATIONS | Refundable | Proceed with processRefund or your approval flow |
VOLUNTARY MILES | Taxes-only refundable | Proceed if tax refund desired; miles reinstated outside Deal Engine |
REJECTED | Refused by your configured rules — detected via notes + 0 refund amount, or via the explicit REJECTED quote status if enabled. Retrying returns the same result | Don't auto-retry. Route to manual review/support with the note text |
Quote ERROR | Quote failed (system/GDS/PSS) | Retry with backoff; contact support if persistent |
5. Tracking a refund to completion
5.1 Webhooks (recommended)
refund_request.status_updated— quote-stage progressrefund_candidate.status_updated— candidate changes, including both terminal outcomes
Configured per client and environment — see the Webhooks guide for payloads and setup.
5.2 Polling
Poll unifiedRefund.status or the candidate status every 30–60 seconds (execution can take up to ~2 minutes; faster polling adds nothing). Stop at REFUNDED/ERROR. The authoritative final record — including the executed amount — is Document.refund / unifiedRefund; see Refund amounts & reconciliation.
5.3 Failure after acceptance
Failed execution ends in ERROR (+ webhook if configured). Transient GDS/PSS failures are retried internally (2 retries on network errors) before ERROR; business refusals are never retried.
A candidate that was safe to submit can still fail at execution (GDS/PSS outage, document changed since quoting). Treat REFUNDED — not the acceptance response — as confirmation.
Updated 2 days ago