A Hyderabad FMCG super-distributor moves ₹140 crore of goods a year across 37 brands — soaps, biscuits, packaged foods, beverages, personal care — to ~3,400 retailer customers from kirana stores to mid-tier supermarkets across Telangana, Andhra Pradesh, and northern Karnataka. Until April 2025 they ran the entire orderbook on 37 brand-by-brand WhatsApp groups, an Excel master, and a 9-person tele-calling team typing orders into a desktop ERP. We shipped a multi-vendor B2B marketplace that consolidated all 37 brands into one app, one checkout, one settlement engine. Order capture time went from 11 minutes per order (call + retype) to 90 seconds (retailer self-serve). This is the architecture and the trade-offs.
The Answer in 60 Words
We built a Next.js + React Native marketplace, a Node.js + Fastify API backed by PostgreSQL 16, a settlement engine that routes payments across 37 brand virtual accounts via Razorpay Route, BullMQ-backed reconciliation workers, and a Metabase analytics layer. ~3,400 active retailers, ~94,000 orders/month, ₹140 cr annual GMV.
Why This Matters Now
Indian FMCG distribution has been pulled in three directions since 2023. ONDC (Open Network for Digital Commerce) hit ~12 million transactions/month by mid-2025 and forced even traditional distributors to think about API-first ordering. Brand-direct platforms (Udaan, Jumbotail, ElasticRun) have squeezed super-distributor margins. And kirana retailers — the demand side — got smartphone-first during COVID and never went back to paper. A 37-brand super-distributor running on WhatsApp groups in 2025 is leaving 8-12% of GMV on the table to faster competitors. The build was defensive as much as offensive.
The other shift is on the payment side. Razorpay Route and Razorpay X (and the equivalent products from Cashfree, Easebuzz) made multi-vendor settlement programmable in a way it was not three years ago. Pre-Route, splitting a ₹14,000 retailer order across 5 brands meant manual T+2 reconciliation. Post-Route, it is automatic per-transaction.
The Client (Specific Details)
The Architecture (One Diagram Worth Drawing)
The Settlement Engine (The Hardest Part)
A typical retailer order has 12 SKUs across 4 brands. Some brands have a 7-day credit term, some 14, some immediate. Some brands settle to the distributor, some direct to the brand. The distributor takes a per-brand commission, plus a cash-discount adjustment, plus GST handling. Pre-marketplace, this was a 4-person back-office task running on Excel for 8 hours a day. Post-marketplace, it runs as a pipeline that takes 14 minutes a day for the back-office to review and approve.
The pipeline:
Webhook Idempotency (Where We Earned Our Money)
Razorpay's webhook spec is honest about it: events may be delivered more than once. Their best-practices doc is explicit: build idempotent handlers, dedupe on event id, expect out-of-order delivery, respond 2xx on success.
Our handler enforces three invariants:
razorpay_event_id. Re-delivery is a no-op.We have processed ~1.4 million webhook events without a single double-spend or missed-payment incident. The discipline matters at this scale.
Multi-Brand Catalogue: The Other Hard Part
37 brands x ~140 SKUs per brand = ~5,200 SKUs in the catalogue, each with its own pricing, packaging unit, schemes, MOQ, and brand-side promotional rules. The catalogue is the second-most-complicated part of the system after settlement.
Our approach:
The 18-Week Plan
- Weeks 1-2: Discovery — interview 8 retailers, 12 brand contacts, 4 warehouse managers; map the existing WhatsApp + Excel + ERP flow end-to-end
- Weeks 3-5: Schema design (the catalogue and settlement schemas alone took 10 days of debate), authentication, brand-onboarding tools
- Weeks 6-8: Retailer app v1 — browse, cart, checkout in English first; payment integration with Razorpay Route
- Week 9: Settlement engine v1, reconciliation worker, brand console
- Weeks 10-11: Multi-language (Hindi, Telugu) for the retailer app; voice search; offline-cache for spotty rural networks
- Week 12: Brand catalogue self-serve uploads, scheme rules engine, MOQ guards
- Week 13: Warehouse fulfillment workflow — picking lists, dispatch confirmations, delivery proof
- Week 14: Returns + credit notes — including the messy partial-return-of-bundled-scheme case
- Weeks 15-16: UAT with 2 brand teams + 12 hand-picked retailers; iterate on scheme rule edge cases
- Week 17: Soft launch with 4 brands, 200 retailers, ~₹4 cr GMV in 5 days
- Week 18: Full launch — all 37 brands, all 3,400 active retailers
Common Mistakes (Each One Hurts)
Symptom: "Brand settlement is off by Rs 14,000." Cause: Razorpay fee deducted from the settlement but expected-split computation did not subtract it. Fix: read the Razorpay settlement API carefully — fees can be deducted from the platform side or from the linked-account side depending on configuration. Match your config exactly.
Symptom: "Retailer placed an order then complained 'I did not pay'." Cause: webhook arrived late and the app showed a stale "pending" state. Fix: poll the order status from the app on a 30-second interval until terminal state. Do not rely on push alone for payment confirmation.
Symptom: "Two brands are arguing over a returned crate." Cause: returns hit a single inventory bucket and were attributed to the wrong brand. Fix: every return record carries the brand_id from the original order. Audit log shows attribution. Run a reconciliation report weekly with brand-side counterparts.
Symptom: "Some retailers cannot complete UPI payment." Cause: Razorpay's UPI flow occasionally fails on older Android handsets. Fix: enable both Razorpay Standard Checkout (in-app SDK) and a hosted Web Checkout fallback. Detect failure modes and switch automatically.
Symptom: "Daily MIS report takes 14 minutes to load." Cause: aggregation across 5,200 SKUs x 3,400 retailers x 30 days is slow on the live transactional DB. Fix: use a Postgres logical replica for analytics, materialise the daily-rollup on a cron, serve from the materialised table for sub-second loads.
When NOT to Build a Multi-Vendor Marketplace
Skip the build if (a) you carry under 8 brands and your order volume is under 200/day — a vanilla B2B WhatsApp commerce setup will deliver 80% of the value at 5% of the build cost, (b) your brand principals refuse to accept programmable settlements — a Razorpay-Route style stack requires brand-side bank-account onboarding which can take 2-4 weeks per brand, or (c) your sales team is your competitive advantage and digital self-serve will erode that. Some categories (premium spirits, regulated goods) need the conversation.
For our earlier work on a Diwali-cracker multi-vendor marketplace, see Diwali Crackers Multi-Vendor Marketplace. Same architectural pattern at smaller scale (9 sellers vs 37 brands). The Razorpay Route integration carries over almost identically.
Real Outcome (10 Months Post-Launch)
The +18% GMV is the number the brand principals cared about — proof the digital orderbook captured incremental orders, not just shifted existing ones. The 90-second median capture time meant the tele-calling team of 9 dropped to 3 (the others moved to brand-acquisition and credit-collection roles, no layoffs).
A Detail That Saved Us On Day 41
On day 41 of UAT, a brand-side promo rule was misread by the scheme engine: "10+1 free on Surf Excel 1kg" was applied as "+1 unit at MRP" instead of "+1 unit free." 14 retailers were each billed for the free unit. We caught it in our daily back-office review (the 14-minute one). We refunded all 14 within 2 hours, posted credit notes by EOD, and added a property-based test that synthesises 1,000 random scheme combinations and asserts the cart total never exceeds the sum of (unit_price x quantity). Eight months later we have not had a similar incident.
The lesson: marketplace promo rules will eventually betray you. Test the cart total invariant, not just the rule logic.
The Stack Cost Per Month
| Component | Notes |
|---|---|
| Hetzner CCX43 (app + Postgres primary) | 16 vCPU / 64 GB RAM, oversized for headroom |
| Hetzner CCX23 (read replica + Metabase) | Analytics workload isolated |
| Hetzner CX22 ×3 (BullMQ workers) | Settlement, reconciliation, MIS workers |
| Backup S3 (Cloudflare R2) | 240 GB hot + 7 years archive |
| Razorpay Route fees | Transactional, scales with GMV |
| Twilio + Gupshup (SMS + WhatsApp) | Order updates, payment reminders |
| Sentry + Logtail | Error + log infrastructure |
| Engineering retainer (0.6 FTE) | Higher than a CRM because of payment-side complexity |
The transaction fees scale with GMV. The fixed infrastructure cost is small — the rest is variable on volume.
FAQ
Why Razorpay Route and not Cashfree Easy Split?
We evaluated both. Both work for this use case. Razorpay Route had stronger settlement-API documentation at the time we built (Q2 2025) and the founder already had a Razorpay account. Cashfree's Easy Split has a slightly cleaner sub-account onboarding flow which we would consider for a new build today.
How did you handle GST for cross-state retailers?
State-wise GSTIN validation at retailer onboarding. CGST/SGST split for intra-state orders, IGST for inter-state. The brand's GSTIN is the seller of record on the invoice; the distributor's GSTIN appears as the consignor. Two-tier invoice generation with a dedicated GST library. We use ClearTax's e-invoicing API for IRN generation when above the threshold.
What about credit-terms management?
Credit-term orders generate an unsettled invoice with a due date. A separate credit-collection workflow runs at T+5, T+12, T+20 days for 7-day terms (escalating). Credit limits are enforced at order placement — a retailer at credit limit cannot place a new credit-term order until they pay down.
How did you onboard 37 brands?
A 4-step onboarding: (1) brand legal contract + commission rate schedule, (2) Razorpay Route sub-account creation with brand bank details, (3) brand catalogue upload via CSV template + brand UAT in sandbox, (4) brand-team training on the brand console. Median brand onboarding time: 18 days from contract to live.
Did you replace the existing ERP?
No. The ERP stays for accounting, GST, and finance functions. The marketplace pushes daily summary entries into the ERP via a webhook. The two systems live alongside; the marketplace is the truth of orders, the ERP is the truth of books.
What about offline orders from tele-calling?
The 3-person tele-calling team uses the distributor console to enter orders on behalf of retailers. Same checkout, same payment flow. ~22% of orders still come via the tele channel — typically larger orders or new retailers being onboarded.
Do retailers actually use the voice search?
Yes — about 31% of search queries are voice. Especially for brand names where the spelling is non-obvious in Telugu transliteration. We use the device's native speech-to-text, not a server-side STT, to keep latency low and avoid cloud cost.
What was the team composition?
Three full-stack engineers, one engineer dedicated to payment + settlement (the hardest piece), one mobile engineer (React Native), Manvi at 0.6 FTE for QA on the financial flows, our designer at 0.4 FTE, and our founder Vivek at 0.2 FTE for client direction. Total 5.4 FTE for 18 weeks.
Related Reading
If you found this useful
- Diwali Crackers Multi-Vendor Marketplace — same Razorpay Route pattern at 9-seller scale
- Radiant Finance Lead Pipeline — payments-domain case study
- Our Web Application Development Service
- Founder commentary on Indian B2B marketplace economics from Vivek Kumar
Need a Multi-Vendor Marketplace for Your Distribution Business?
We ship multi-vendor B2B marketplaces with Razorpay Route settlement, brand-self-serve catalogues, and reconciliation workers for Indian distributors and aggregators in 14-20 weeks, fixed price. First call is technical, with the engineer who would lead your build. Suitable for 5+ brand operators with ₹20+ cr annual GMV.
Book a Marketplace Scoping Call
