Dev.to WebDev πŸ›  Dev πŸ‘ 0 πŸ“– 3 min read

Your Checkout Design Fails the Moment the Payment Button Gets Clicked Twice

Every frontend system design round has a moment where the candidate looks confident and the interviewer stops believing them. For a checkout, that moment is the second click. Not the first click. The first click is easy

Every frontend system design round has a moment where the candidate looks confident and the interviewer stops believing them. For a checkout, that moment is the second click.

Not the first click. The first click is easy. You draw a cart, a form, a button, a success screen, and you smile like the job is done. Then the interviewer leans in and says, "The user clicked twice. The network is slow. What happens now?" If your answer is "we disable the button," you just told them your architecture is a hope and a prayer.

Disabling the button is a UI trick, not a design. Buttons get re-enabled. Pages get refreshed. Requests get retried by the browser, by the network, and by an impatient human with a thumb. A checkout that only works when everything goes right is not a checkout. It is a demo.

Here is the non-obvious angle most candidates miss. A checkout is not a form. It is a state machine with money attached. The screen is the least interesting part. What the interviewer is really scoring is whether you can name the states, the transitions, and the one state you must never leave ambiguous: did we charge them or not?

Think about it in states, not screens. Idle. Submitting. Awaiting confirmation. Confirmed. Failed, with a reason the user can act on. Unknown, which is the state everyone forgets and the only one that matters. Unknown means the request left the browser and no answer came back. You cannot show success, because you might double charge. You cannot show failure, because the charge might have gone through. A junior redraws the success screen. A senior designs the unknown state first.

That changes every decision that follows. You need an idempotency key, a unique token generated once per checkout attempt and sent with every retry, so a duplicate request is recognised as the same order, not a second one. You need a way to re-check the real order status on reload, instead of trusting whatever the last screen said. You need to separate "the payment was accepted" from "the order was created," because those are two different facts and they fail independently. And you need a failure message that tells the user what to do next, not a generic error that sends them back to click the button a third time.

Here is the artifact to carry into the round. Run every checkout design through this six line check before you draw anything else.

  1. One checkout attempt, one idempotency key, reused on every retry.
  2. Every state named, including unknown, with a screen for each.
  3. On reload, re-fetch order status. Never trust the last screen.
  4. Payment accepted and order created treated as separate facts.
  5. Retry is safe by construction, not by a disabled button.
  6. Every failure tells the user what happened and what to do next.

That turns a vague prompt into decisions you can defend. When the interviewer asks why you chose optimistic or server confirmation, you have an answer tied to a real failure, not a memorised preference. When they ask what breaks at scale, you point at the same joint: duplicate submissions under retry storms, not a prettier component tree.

Candidates love to start with the happy path because it feels like progress. Interviewers score the opposite. They want to see you volunteer the breakage before they have to drag it out of you. Say it early, in plain language: "Here is where this breaks, here is the state that saves us, here is the trade-off." That sentence is worth more than ten extra boxes on the whiteboard.

I turned the full 60-question drill set into The Frontend System Design Interview Playbook ($19): https://bittalk.gumroad.com/l/frontend-interview-playbook. The checkout question is one of the sixty, and the drill is the same: name the failure before you draw the fix.

Next time you practise, skip the success screen. Start with the double click, the dead network, and the reload. If your design survives those three, the happy path will take care of itself. If it does not, no amount of polished UI will save you in the room.

πŸ“° Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.