Buy Now Pay Later (BNPL) System
Design a Flipkart-style Buy Now Pay Later system — credit limits, dues tracking, delayed payments, and blacklisting, built entirely in memory.
Design and implement a Buy Now Pay Later (BNPL) system for Flipkart from scratch. Users can purchase products either prepaid or on credit, and the system must track credit limits, pending dues, and repayment behavior over time.
This one tests whether you can model a credit system correctly — tracking limits, dues, and time-based status changes — while keeping order placement, repayment, and eligibility checks cleanly separated so blacklisting and inventory rules can be layered on without touching the core purchase flow.
Objective
The primary objective of this project is to design and implement an in-memory BNPL system that supports inventory management, per-user credit limits, prepaid and BNPL purchases, partial or full due clearance, and accurate due-status reporting — including a bonus blacklisting mechanism for repeat defaulters.
Functional Requirements
Requirements are split into two tiers so you know what to prioritize under time pressure: build first, and build if time allows.
Part 1 — Core Requirements
Core functionality you must build and get working first.
Part 2 — Bonus Requirements
Extensibility checks — can your design layer risk management and inventory flexibility on top of the core flow without a rewrite.
Example Usage: Full Walkthrough
Here's how a sample session might run end-to-end, one step at a time.
1. Seed and view inventory
> seed_inventory([
{ name: "Headphones", count: 50, price: 2000 },
{ name: "Keyboard", count: 30, price: 1500 },
])
✅ Inventory seeded with 2 products.
> view_inventory
📦 Inventory:
- Headphones qty: 50 price: ₹2000
- Keyboard qty: 30 price: ₹1500
2. Register a user
> register_user("alice", creditLimit: 5000)
✅ User 'alice' registered with BNPL credit limit ₹5000.
3. Place a BNPL order
> buy("alice", ["Headphones"], "BNPL", "2026-01-01")
✅ Order #1001 placed via BNPL. Amount due: ₹2000.
Remaining credit limit: ₹3000.
4. Attempt an order that exceeds the remaining limit
> buy("alice", ["Keyboard", "Headphones"], "BNPL", "2026-01-05")
❌ Purchase blocked. Order amount ₹3500 exceeds remaining credit limit ₹3000.
5. View dues, including a delayed one
> view_dues("alice", "2026-02-05")
📋 Pending dues for alice (as of 2026-02-05):
- Order #1001 ₹2000 purchased 2026-01-01 status: DELAYED
6. Clear a due, partially
> clear_dues("alice", ["1001"], "2026-02-06", amount: 1000)
✅ ₹1000 applied to Order #1001. Remaining due: ₹1000.
Remaining credit limit: ₹4000.
7. Check full order status
> order_status("alice")
🧾 Order history for alice:
- Order #1001 Headphones ₹2000 BNPL status: DELAYED paid: ₹1000 due: ₹1000
Available BNPL credit limit: ₹4000
Alice's first BNPL order correctly reduces her credit limit, a second order that would exceed the remaining limit is blocked outright, and once 30 days pass unpaid the due flips from PENDING to DELAYED. A partial payment restores credit proportionally and updates the order's remaining due — all without touching the underlying inventory or user records directly.
What They Looked For
This round weighed design quality as heavily as correctness — the goal was demoable, extensible code, not just passing test cases.