← All Articles
Tutorial9 min read10 April 2026

How to Build a Multi-Vendor Marketplace in Next.js

A practical guide to architecting a multi-vendor marketplace with Next.js, including vendor onboarding, product listings, M-Pesa payments, and commission logic.

JM
James Maroko
Full-Stack Engineer & Cybersecurity Specialist

Introduction

Building a marketplace like TumiaTen taught me more about Next.js architecture than any other project. A multi-vendor marketplace involves multiple user roles, payment splitting, and real-time inventory management. This guide walks through the core architecture decisions.

What Makes a Marketplace Different

A standard e-commerce store has one seller. A marketplace has many. This changes your entire data model and payment flow — every product belongs to a vendor, and every sale needs commission deducted before the vendor receives their payout.

1 — Database Schema

model Vendor {
  id        String    @id @default(cuid())
  name      String
  email     String    @unique
  products  Product[]
  createdAt DateTime  @default(now())
}

model Product {
  id       String  @id @default(cuid())
  title    String
  price    Float
  stock    Int
  vendorId String
  vendor   Vendor  @relation(fields: [vendorId], references: [id])
}

model OrderItem {
  id         String @id @default(cuid())
  orderId    String
  productId  String
  vendorId   String
  quantity   Int
  price      Float
  commission Float
}

2 — Commission Logic

const COMMISSION_RATE = 0.10 // 10% platform fee

const orderItems = await Promise.all(
  items.map(async (item: any) => {
    const product    = await db.product.findUnique({ where: { id: item.productId } })
    const subtotal   = product!.price * item.quantity
    const commission = subtotal * COMMISSION_RATE
    return {
      productId:  item.productId,
      vendorId:   product!.vendorId,
      quantity:   item.quantity,
      price:      product!.price,
      commission,
    }
  })
)

3 — M-Pesa Integration

// On successful M-Pesa callback
await db.order.update({
  where: { id: orderId },
  data: { status: "paid", mpesaRef: receiptNumber }
})

const vendorGroups = groupBy(order.items, "vendorId")
for (const [vendorId, items] of Object.entries(vendorGroups)) {
  await sendVendorNotification(vendorId, items)
}

Conclusion

A multi-vendor marketplace is complex but rewarding. Get the data model right from day one — everything else follows. If you are building a marketplace and need help with the architecture or M-Pesa integration, reach out.

Work With James

Need help with your project?

Whether it’s M-Pesa integration, a full web application, or a performance audit — reach out and let’s build something great.

Get In Touch →