If you’re building a multi-vendor e-commerce platform using the MERN stack (MongoDB, Express.js, React, Node.js), integrating a secure and flexible payment system like Razorpay is a crucial step. In this guide, we’ll walk you through setting up a multi-vendor architecture and integrating Razorpay to route payments to respective vendors.
🧩 Overview
- Set Up Vendor Model and Authentication
- Create Product Listings Linked to Vendors
- Build Order Management System
- Razorpay Integration Basics
- Create Orders with Razorpay API
- Webhook Handling
- Route Payment to Specific Vendor (Razorpay Route)
- Test Payment and Completion Flow
1. 📦 Vendor Schema & Authentication (MongoDB + Express.js)
First, create a separate Vendor model in MongoDB.
// models/Vendor.js
const mongoose = require('mongoose');
const vendorSchema = new mongoose.Schema({
name: String,
email: { type: String, unique: true },
password: String,
razorpayAccountId: String, // Connected account
});
module.exports = mongoose.model('Vendor', vendorSchema);
🔐 Use
bcrypt
for password hashing and JWT for authentication.
2. 🛍️ Product Model Linked to Vendor
Update the Product schema to include a vendor reference.
// models/Product.js
const mongoose = require('mongoose');
const productSchema = new mongoose.Schema({
title: String,
price: Number,
vendor: { type: mongoose.Schema.Types.ObjectId, ref: 'Vendor' },
});
module.exports = mongoose.model('Product', productSchema);
3. 📋 Orders Model & Checkout Flow
Add an Order model that includes buyer, product, and vendor info.
// models/Order.js
const mongoose = require('mongoose');
const orderSchema = new mongoose.Schema({
product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product' },
buyer: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
vendor: { type: mongoose.Schema.Types.ObjectId, ref: 'Vendor' },
amount: Number,
status: { type: String, default: 'pending' },
});
module.exports = mongoose.model('Order', orderSchema);
4. 💳 Razorpay Setup (Backend – Node.js)
Install Razorpay SDK:
npm install razorpay
Initialize Razorpay instance:
// config/razorpay.js
const Razorpay = require('razorpay');
const razorpay = new Razorpay({
key_id: process.env.RAZORPAY_KEY_ID,
key_secret: process.env.RAZORPAY_SECRET,
});
module.exports = razorpay;
5. 📤 Create Razorpay Orders
Create an API to generate an order when a customer checks out.
// routes/payment.js
const express = require('express');
const router = express.Router();
const razorpay = require('../config/razorpay');
router.post('/create-order', async (req, res) => {
const { amount, currency, receipt, notes } = req.body;
const options = {
amount: amount * 100, // in paise
currency: currency || 'INR',
receipt,
notes,
};
try {
const order = await razorpay.orders.create(options);
res.json(order);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
6. 📡 Razorpay Webhook for Payment Verification
Set up webhook to confirm payment status:
// routes/webhook.js
router.post('/razorpay-webhook', express.raw({ type: 'application/json' }), (req, res) => {
const secret = process.env.RAZORPAY_WEBHOOK_SECRET;
const crypto = require('crypto');
const shasum = crypto.createHmac('sha256', secret);
shasum.update(req.body);
const digest = shasum.digest('hex');
if (digest === req.headers['x-razorpay-signature']) {
// Update order status in DB
console.log('Payment verified:', req.body);
res.status(200).json({ status: 'ok' });
} else {
res.status(400).json({ status: 'invalid signature' });
}
});
7. 🔄 Razorpay Route Integration for Multi-Vendor
Razorpay’s Route feature allows you to split payments between vendors.
7.1 Create Vendor Razorpay Accounts
Each vendor must be onboarded and approved via Razorpay Partner program or API.
Once approved, you’ll get a razorpay_account_id
for each.
7.2 Transfer Payment to Vendor
After payment is completed, use the Transfers API:
// routes/payment.js
router.post('/transfer-to-vendor', async (req, res) => {
const { payment_id, vendor_account_id, amount } = req.body;
try {
const transfer = await razorpay.transfers.create({
account: vendor_account_id,
amount: amount * 100,
currency: "INR",
transfer_type: "vendor",
reference_id: `transfer_${payment_id}`,
notes: {
note1: "Multi-vendor marketplace transfer",
},
});
res.json(transfer);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
8. 💻 Frontend – React Payment Component
On the frontend, use Razorpay Checkout SDK:
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
Example React Integration
const makePayment = async () => {
const res = await fetch('/create-order', {
method: 'POST',
body: JSON.stringify({ amount: product.price }),
headers: { 'Content-Type': 'application/json' },
});
const data = await res.json();
const options = {
key: process.env.REACT_APP_RAZORPAY_KEY_ID,
amount: data.amount,
currency: data.currency,
order_id: data.id,
handler: function (response) {
alert('Payment successful');
// Call backend to trigger transfer to vendor
},
};
const rzp = new window.Razorpay(options);
rzp.open();
};
🧪 Final Testing
✅ Test scenarios:
- [x] Customer buys a product
- [x] Razorpay order is created
- [x] Payment is successful
- [x] Webhook confirms payment
- [x] Admin/backend transfers payment to vendor Razorpay account
🔐 Important Notes
- Always verify payments server-side using signature.
- Razorpay Route requires approval.
- Onboard vendors using Razorpay APIs or manually through dashboard.
- Store
razorpay_account_id
securely for each vendor.
🧾 Conclusion
Implementing Razorpay in a MERN-based multi-vendor marketplace is very achievable with the right structure. This guide covered everything from vendor setup, product linking, payment collection, to final payout via Razorpay Route.
If you’re building a project like this and want to scale, ensure compliance, security, and use real Razorpay API documentation:
👉 https://razorpay.com/docs/
🔗 Originally published on Makemychance.com
Arsalan Malik is a passionate Software Engineer and the Founder of Makemychance.com. A proud CDAC-qualified developer, Arsalan specializes in full-stack web development, with expertise in technologies like Node.js, PHP, WordPress, React, and modern CSS frameworks.
He actively shares his knowledge and insights with the developer community on platforms like Dev.to and engages with professionals worldwide through LinkedIn.
Arsalan believes in building real-world projects that not only solve problems but also educate and empower users. His mission is to make technology simple, accessible, and impactful for everyone.