ADR-0002: Never queue the decision; fast retryable decline; stand-in built but off
Status: Accepted · Date: 2026-10-19
Context
The caller is a person at a till with a ~3 s timeout. A queue in front of the decision silently turns a synchronous approve/decline into an asynchronous one. The till cannot poll or receive webhooks, and the customer walks away. Card networks have handled "authoriser unreachable" for decades: either decline, or approve below a floor limit (stand-in) and accept bounded risk. A queue is not a third option. It is a decline with worse ergonomics.
Decision
- When the wallet is unavailable (breaker open, bulkhead full, 503, refused), respond
201 DECLINED WALLET_UNAVAILABLE,retryable=true,Retry-Afterwithin milliseconds. - Implement the degradation policy as a separate table-driven component. Tier 0 (stand-in under a
floor limit with exposure caps) is built and tested but disabled (
stand-in.enabled=false, floor 0). - Queue only follow-ups that nobody waits for: capture, release, compensating credit, resolution of unknown outcomes.
- Report technical declines as
201plus a decision body, not as5xx. The till gets one uniform shape, and503is reserved for "Transaction Service itself cannot accept work".
Consequences
- + Honest, fast, measurable. An outage shows up as a spike in
WALLET_UNAVAILABLEdeclines, not as hung tills. - − Lost sales during wallet outages, until the business opts into stand-in.
- Enabling stand-in later requires: floor limit > 0, per-account and global exposure caps, a kill switch, reconciliation of every stand-in decision, and a business owner (OQ-3). Because of legacy debiters (C2) we cannot estimate balances conservatively, so every stand-in approval is real credit risk.