Headless marketplace for the vintage market on Medusa.js
Building a multi-vendor marketplace on Medusa.js — a platform designed for single-vendor. Custom plugin, seller data model, and admin panel built from scratch.
Usługi
Technologie
An antiques and vintage marketplace operates by different rules than a typical B2C store. Every item is unique — one unit, one price, one story. The platform had to support dozens of independent sellers listing their own offers, while buyers see a coherent shopping experience without awareness of which specific seller a given item comes from.
Medusa.js is designed as a single-vendor engine. One store, one account owner, one checkout. Building a multi-vendor marketplace meant stepping beyond the platform's ready-made abstractions.
Three main technical challenges:
- Data model. Native Medusa has no
Sellerentity or product↔seller relationship. Each product belongs to the store, not to an individual entity. - Order routing. A cart can contain products from multiple sellers. Medusa treats an order as a monolithic unit — the payment split and separate fulfilment flows had to be solved.
- Seller panel. The standard Medusa Admin is a tool for the marketplace operator, not for individual sellers. A separate interface with a restricted data view was needed.
Instead of forking Medusa, I chose an approach via a custom plugin extending the existing data model without touching the platform core. This means Medusa updates don't break business logic.
Seller entity and relationships. The plugin adds a sellers table to the database with profile, commission rates, and verification status. Products and variants are linked to a seller_id via an additional column and middleware that validates ownership on every mutation.
Order splitting. After an order is placed, a webhook splits it into sub-orders per seller. Each seller sees only their own orders, receives a separate notification, and manages their own fulfilment. Payment is collected by the marketplace, commission deducted automatically.
Seller panel. A separate Next.js application with authentication via the Medusa API. Sellers can add products, track orders, and view sales statistics. The role is restricted — a seller cannot see other sellers' data or platform configuration.
Product uniqueness. For vintage categories, each SKU has inventory tracking enabled with a limit of 1 unit. After a sale, the product is automatically archived.
DevOps. The stack runs on a VPS via Docker Compose: Medusa backend, Next.js storefront, seller panel, PostgreSQL, and Nginx as a reverse proxy. Deployments are automatic on merge to the main branch.
- Zero downtime during Medusa updates — the plugin architecture separates marketplace logic from the core platform.
- Complete fulfilment flow end-to-end: listing → cart → payment → split → shipping — without manual operator intervention.
- Seller independence — each seller manages their own catalogue and orders from a dedicated panel.
The project remains under my active technical care. The retainer covers monitoring, dependency updates, minor improvements, and fast incident response.