REFUNDS · NEVER MORE THAN COLLECTED
Refunds: never return more cash than was collected
A $100 order paid with a card and a gift card is fully returned; check that each tender gets back no more than it paid, even with a coupon and a retried request.
Your experiment
Two items listed at $60 were bought with a $20 coupon: $70 on a card and $30 from a gift card. The customer returns both, and the first refund request times out and is retried. Start with list-price refunds to the card and no keys, then add keys, refund the share actually paid, split by tender and cap each tender.
Play replays the computed run over sixty inspection seconds; Next event steps, Restart rewinds, Speed changes the pace and Inspection time scrubs. Any input change recomputes the run and rewinds it without autoplay.
Event trace
Computed data
Final metrics
Fictional order and tenders; no payment provider is called. Cash means money returned to the card; gift-card value returned to a card is counted as converting stored value into cash. Real refunds also depend on card-network rules, partial captures, fees and refund windows.
A full return, refunded three times over
Order 9001 had two items listed at $60 and a $20 coupon, so $100 was collected: $70 on a card and $30 from a gift card. The customer returns both items. In the opening run each refund is the item’s list price, everything goes to the card, and the first request times out and is retried without an idempotency key. The card receives $60, $60 again and $60: $180 for a card that paid $70. MORE CASH THAN COLLECTED.
Deduplicate, then refund what was paid
Check Refund requests carry idempotency keys: the retry returns the original result and the card receives $120. Set Refund amount per item to Share actually paid ($50 after the coupon): the total is now exactly $100, but all of it goes to the card, $30 more than the card ever paid. That $30 is gift-card value turned into cash, a classic way to launder stored value or abuse promotions.
Return money the way it came
Set Where a refund goes to Split like the original payment (70/30): each $50 refund sends $35 to the card and $15 to the gift card, totalling $70 and $30: REFUNDS MATCH COLLECTED CASH. Cap each tender at what it paid reaches the same totals while routing to the card first: the second refund puts $20 on the card and $30 on the gift card. With the caps even list-price refunds stop at $100, because no tender can receive more than it paid.
Every control closes a different gap
Without idempotency keys, splitting by tender still refunds $150 in total. With keys but list prices and a proportional split, the card receives $84 of a $120 total. The coupon, the retry and the tender mix each break the invariant on their own; only the combination of keys, the paid basis or per-tender caps, and tender-aware routing keeps every refund within what was collected.
Reading the run and its limits
Play, Next event, Restart, Speed and Inspection time step through the order, each refund request and the reconciliation across sixty seconds; the table shows what each request sent to the card and to the gift card. The order is fictional; real refunds also face card-network rules, partial captures, fees, refund windows and currency conversion.