Headless marketplace for the vintage market on Medusa.js
E-commerce2025

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

Backend / APIFrontendDevOpsMaintenance

Technologie

Medusa.jsNext.jsPostgreSQLDocker
Headless marketplace for the vintage market on Medusa.js — zrzut ekranu 1
Headless marketplace for the vintage market on Medusa.js — zrzut ekranu 2
Context

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.

Challenge

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 Seller entity 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.
Solution

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.

Results
  • 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.
Maintenance

The project remains under my active technical care. The retainer covers monitoring, dependency updates, minor improvements, and fast incident response.