Design a digital game shop backend
Company: Databricks
Role: Software Engineer
Category: System Design
Difficulty: hard
Interview Round: Onsite
Design the backend for a simple digital game shop where users can buy virtual items (e.g., games, in‑game currency, skins) using credits in their account.
### Functional requirements
1. **User credit (wallet)**
- Each user has an account with a wallet balance in a single currency (e.g., EUR).
- Users can **add credit** to their wallet (e.g., after successful payment with a card or external PSP).
2. **Purchase item**
- A user can purchase one or more items from the shop.
- The system must:
- Check that the user has sufficient credit.
- Deduct the correct amount from the user's wallet.
- Grant the user ownership/entitlement of the purchased items.
- The purchase should go through a **`PENDING` → `COMPLETED`** flow rather than directly `COMPLETED`.
- In the purchase API, discuss whether the client should send:
- `item_id` + `quantity` (and the server looks up prices), or
- `total_amount` to charge (sent by the client),
and justify your choice.
3. **Refund**
- Support refunding a purchase (full or partial refund of items / amount).
- Refunding should:
- Return credits to the user's wallet.
- Potentially revoke entitlements for refunded items (depending on business rules you can define).
4. **Failure scenarios**
- Handle **duplicate client requests** (e.g., due to retries when the client times out) so that operations are **idempotent**.
- Handle **server failure** in the middle of an operation (e.g., crash after debiting the wallet but before granting the item, or vice versa) using appropriate data modeling and database transactions.
### Non‑functional requirements (you may assume reasonable numbers)
- Millions of users, with typical read/write traffic of an online store.
- Strong consistency for money and entitlements: no user should be charged without getting the item, or get an item without being charged.
- High availability is nice but correctness of balances and orders is more important.
### Tasks
Design the system focusing on:
1. **High‑level architecture**
- Roughly outline the services/components (e.g., User Service, Wallet Service, Order Service, Catalog Service) or a monolith if you prefer, and how they interact.
2. **APIs**
Define REST‑style APIs (you can give example HTTP endpoints and JSON bodies) for at least:
- `Add credit to user` (top up wallet)
- `Create a purchase` (place an order for one or more items)
- `Complete a purchase` (if you separate creation and payment) or a single `Purchase` endpoint that handles the full flow
- `Refund` a purchase (full or partial)
Be explicit about:
- Request / response schemas.
- What fields are client‑supplied vs server‑computed (e.g., whether the client sends `total_amount`).
- How you represent `PENDING`, `COMPLETED`, `CANCELLED`, `REFUNDED` states.
3. **Data model**
Propose a relational data model (tables/collections and key fields) for at least:
- `User`
- `Item` (or `Product`)
- `Wallet` and/or `WalletTransaction` (ledger of credits/debits)
- `Order`
- `OrderItem`
- Optionally `PaymentTransaction` and `Refund`
Show how you keep a consistent wallet balance and item ownership.
4. **Transaction and consistency model**
Explain:
- How you will use **database transactions** to ensure that wallet balance updates and entitlements changes happen atomically for a purchase (or are rolled back together on error).
- How the `PENDING` order status fits in (e.g., why it is better than going directly to `COMPLETED`).
- What happens if the server crashes at each step of the purchase or refund flow, and how your design ensures that you can recover to a correct state (possibly using background jobs or retries).
5. **Idempotency and duplicate requests**
- Show how you make operations like "add credit" and "purchase item" **idempotent** (e.g., via idempotency keys, request IDs, or unique constraints).
- Describe what happens if the same request is replayed multiple times by the client or by the payment provider callback.
6. **Additional considerations (brief)**
- Handling concurrent purchases from the same user.
- Simple scaling strategy (read replicas, partitioning by user ID, etc.).
- How you would log and audit financial and entitlement changes.
Your answer should walk through the main flows:
- Add credit to a user's account
- Purchase an item
- Refund an item
and explain how your design meets the consistency, failure‑handling, and idempotency requirements.
Quick Answer: This question evaluates system design skills including transactional data modeling, API design, service decomposition, and reliability concerns for money-related operations such as wallets, purchases, refunds, idempotency, and failure recovery.