Skip to content
Preptima
hardDesignScenarioMidSeniorStaff

Checkout calls pricing, tax, fraud, inventory and a session store. Which of those are you willing to carry on without, and what does the shopper see?

Sort each dependency by what the loss looks like. Price and payment authorisation must fail closed because the loss is unrecoverable; personalisation degrades silently. Tax and fraud sit between, and the answer is a written policy with a bounded exposure, not a timeout value.

6 min readUpdated 2026-07-29Target archetype: Big Tech, Enterprise Captive, Product Startup
Practice answering out loud

What the interviewer is scoring

  • Does the candidate classify each dependency by the recoverability of the loss rather than by how fast it usually responds
  • Whether a fail-open decision is followed through to who absorbs the money when the assumption turns out wrong
  • That order capture is described as durable and idempotent independently of whether the downstream calls succeeded
  • Whether the degraded path is treated as code that must be exercised, not a branch that exists on paper
  • Does the answer say what the shopper is told and how the order is put right afterwards

Answer

Sort the dependencies by what the loss looks like

The instinct is to rank checkout dependencies by latency and set timeouts accordingly. That produces a design where everything is soft and everything is slightly wrong under load. The useful axis is different: for each dependency, ask what you lose by proceeding without it, and whether that loss is recoverable after the fact.

Some losses are recoverable at almost no cost. If recommendations, recently-viewed, a loyalty-points preview or the delivery-slot map are unavailable, the shopper sees a poorer page and the order is still correct. Nobody has to be telephoned afterwards. Some losses are recoverable but expensive per unit: you accept an order you cannot source, and somebody cancels it, refunds it and apologises. And some are not recoverable at all, because you have charged the wrong amount or handed over goods to someone who was never going to pay. Those three tiers, not the response-time distribution, decide fail-closed or fail-open.

That framing is also what the interviewer is really probing, which is whether you understand your own commercial exposure. "We degrade gracefully" is not an answer. "We accept orders without a fraud decision up to a stated basket value, we queue them for screening before release, and the trading team has agreed to carry the residual loss for at most two hours" is an answer, because somebody has priced the risk and bounded it.

The parts that must fail closed

The price is the first. If pricing and promotions cannot be reached you do not have a number you are entitled to charge, and a defaulted or guessed price is how you sell at the wrong amount at scale. The right behaviour is to hold the last authoritatively quoted total for the basket, with an expiry, and to refuse the order once that quote is stale rather than substitute something. This is why the quote should be persisted with the basket at the moment it is computed: it converts an outage in the pricing service into a bounded window during which checkout still works, rather than an immediate hard failure. It also gives you the evidence for what you charged, which the same estate will need when a customer disputes their total.

Payment authorisation is the second, and it is the least negotiable. There is no degraded mode in which you record an order as paid without an authorisation and settle it later, because the population you would be extending credit to during an incident is exactly the population most motivated to exploit it. If the gateway or acquirer is unavailable, the honest behaviours are to fail the attempt with a message that invites a retry, or to route to a secondary provider if you have genuinely built that path. A second provider is only a real control when tokens, reconciliation, refunds and dispute handling all work through it, which is a far larger commitment than adding a second client library.

Order capture is the third, and it is the one candidates skip. Once the shopper has been charged, the order must exist durably whatever else is broken. That means the order record is written before the payment call and carries a client-supplied idempotency key, so a retry after a timeout re-attaches to the same order instead of creating a second one. Everything after capture — allocation, tax finalisation, the confirmation email, the warehouse hand-off — can be asynchronous work driven off that durable record, and that is precisely what allows the rest of the estate to be soft.

Tax and fraud sit in the awkward middle

Tax is interesting because the cost of being wrong is asymmetric and lands on you. Under-collecting is your loss to make good later; over-collecting is a refund and a complaint. For a single-market estate with stable rates, falling back to a cached rate table for the destination is a defensible short-term degradation, and the compensating control is to flag those orders so the amount is recomputed before invoicing rather than trusted. For cross-border baskets, landed cost with duties and import thresholds is not something a cached table reproduces, so blocking is often cheaper than guessing. The answer is a per-market decision, and saying so is stronger than offering one global rule.

Fraud is a policy question dressed as an availability question. You can accept unscreened orders and screen them before release, which works when there is a physical dispatch step to hold them at and works badly for digital goods delivered on payment. The substance is a value threshold, a review queue with real human capacity behind it, and a cap on how long you are willing to run in that mode. Without the cap, an incident on a Friday evening becomes a weekend of unscreened acceptance that nobody decided on.

Inventory belongs here too. Accepting orders without an availability check trades cancellations for conversion, which is sometimes right for a deep-stock line and never right for a scarce one. If you allow it, the compensating behaviour is to allocate against the real ledger when it returns, and to cancel with an apology promptly rather than leave the order in limbo while someone waits for a dispatch note.

The degraded path nobody has ever run

What separates a strong answer here is not choosing the wrong fallback. It is that the fallback has never executed under load and does not work. Cached price tables expire and are not refreshed, because the refresher lives in the same failure domain as the thing it is insuring against. The breaker opens and the fallback calls a second service that is also down, so the timeout budget is spent twice and the page times out anyway. The queue you divert unscreened orders into has no consumer with capacity, so the backlog outlives the incident by days. The retry storm from every checkout in the estate becomes the reason the dependency cannot recover.

So the design has to include the boring parts. An explicit end-to-end budget for the submit request, with per-call budgets inside it that sum to less than the whole. Breakers with real half-open probes rather than fixed sleeps. Fallbacks that live in a different failure domain from what they replace. Load shedding that protects checkout at the expense of browse rather than the other way round, because a shopper who cannot see a category page is annoyed and a shopper who cannot pay is lost. And it has to be exercised deliberately, by failing each dependency in a game day and then confirming that the order taken during the failure was priced correctly, charged once, and fulfilled. A degraded mode that has only been reasoned about is a hypothesis.

When a dependency you assumed was always there is not

In February 2017, an engineer running a documented playbook against Amazon S3 in us-east-1 mistyped a command and removed far more capacity from an index subsystem than intended, and a large number of consumer services that depended on S3 failed with it. Many of those services had no functioning degraded mode, and some could not even serve their own status pages. The lesson for checkout is that your availability is bounded by whatever you treat as always present, and that includes things nobody drew on the dependency diagram: the image host, the static asset bundle, the configuration store your feature flags live in, the object store holding those cached price tables. The interviewer wants to hear which parts of the basket and checkout flow keep working when one of those is simply unreachable, and how you would know rather than assume.

The question is never whether to degrade, it is who absorbs the loss when you do. If you cannot name the budget that absorbs it and the time limit on it, you have not designed a degraded mode, you have deferred a commercial decision to whoever is on call.

Likely follow-ups

  • The fraud service is unreachable during your busiest hour. Do you accept orders unscreened, and up to what value?
  • Inventory is unreachable at the point of order submission. Do you take the order anyway?
  • Your session store loses every live basket. What is recoverable, and from where?
  • How would you prove in a game day that the degraded checkout still takes money correctly?

Related questions

Further reading

checkoutgraceful-degradationdependency-failureidempotencyorder-capture