The Refund That Could Not Be Refunded

Read what each party saw, commit to a cause, and only then find out which of them was right. The root cause, why the obvious reading was wrong, and the fixes are all held back until you have answered.

The symptom

What was reported, before anyone knew what was happening.

A travel booking saga failed at the final step. The compensating transactions ran. Two hours later the customer had no hotel, no flight, a charge on their card, and a loyalty account with 40,000 points that were spent and then returned twice. The saga log says COMPENSATED_OK.

What each party saw, and what each concluded

The evidence, in the form it actually arrived in — several parties, several partial views, several confident conclusions.

WhoWhat they could actually seeWhat they concludedVerdict
Saga orchestratorStep 4 (seat assignment) failed. Emitted compensations for steps 3, 2 and 1. All three returned 200.The saga is fully reversed; the system is back to its pre-saga state.✕ wrong
Payments serviceA refund call for a charge that had settled 90 minutes earlier.Settled charges cannot be voided; issue a refund transaction instead. Returned 200 with status: pending.✓ right
Loyalty serviceTwo credit 40000 calls with the same saga id, four minutes apart, because the orchestrator retried a compensation whose response was lost.Two legitimate credits.✕ wrong
Hotel partner APIA cancellation 90 minutes after booking, inside their free-cancellation window.Cancelled cleanly.✓ right

2 of 4 parties reasoned correctly from what they could see and still reached the wrong conclusion. Nobody in this table is careless. Each one acted on complete-looking local information, and the information was local. That gap — between what a node can observe and what is true — is the whole domain, and one of these readings will usually be yours.

Commit before you read on

Every compensation returned 200 and the orchestrator’s logic was correct. Commit before reading on: name the assumption the orchestrator makes about compensations that the payments service quietly violated — and say whether the loyalty double-credit is the same bug or a different one.

Write it down even if you are unsure. An unwritten guess quietly becomes “that is what I thought” the moment you read the answer.

Everything below stays hidden until you commit. Being wrong here is the exercise — the answer looks obvious the moment you read it, which is exactly why reading it first teaches nothing.