Design an e-commerce checkout end to end: cart, payment with a provider like Stripe, inventory and order confirmation. What can go wrong and how do you make it reliable?
What the interviewer wants to hear
- Server calculates prices and totals, never trusting the client
- Reserve or atomically decrement inventory to avoid overselling
- Use idempotency keys for payment requests
- Treat verified webhooks as the source of truth for payment status
- Model the order as a state machine and make handlers idempotent
- Send emails and other side effects through a queue or outbox
Model answer
The client only sends cart item IDs and quantities; the server looks up prices, discounts and tax, so totals cannot be tampered with. When the user starts checkout, I create an order in PENDING state and reserve stock with an atomic conditional update, so two buyers cannot take the last item; reservations expire if payment never completes. I create a Stripe PaymentIntent with an idempotency key tied to the order, so retries never double charge. The browser confirms the payment, but I mark the order PAID only when a signature-verified webhook arrives, because the user might close the tab. Webhook handlers are idempotent, since providers retry, and the order moves through a clear state machine. Confirmation emails and fulfilment go through an outbox or job queue. A daily reconciliation job compares orders with the provider’s records to catch anything missed.
Can you answer it under time pressure?
Take a timed hard round and get scored on every answer.
More hard Full Stack Developer questions
- You are building a multi-tenant B2B SaaS app. How would you design data isolation between tenants, and what are the trade-offs?
- Your app works well for 1,000 users. Traffic is expected to grow to 1 million users. How would you prepare the system, and in what order?
- An order flow touches your database, a payment provider and an email service. How do you keep the system consistent when any step can fail?
- You need to split a large users table column "name" into "first_name" and "last_name" on a table with 50 million rows, with no downtime. Walk through your plan.
- For a large e-commerce site in Next.js, how would you choose the rendering and caching strategy for the home page, product pages, cart and account pages?
- Your startup’s Next.js monolith is growing and some engineers want to split it into microservices. How do you decide, and what would you do?
- Ten minutes after a deploy, 500 errors jump from 0.1% to 8% on the main API. Walk through how you handle the incident.
- Customers need to import CSV files with up to two million rows into your app. Design the feature end to end.
- You are opening your product’s API to outside partners. How do you design authentication, authorization, rate limiting and change management for it?