A marketplace is a multi-tenant system that happens to sell things. That sentence is the whole implementation problem in one line. The seller dashboard looks like the hard part during planning, but the real work shows up around week three, when every query in the system suddenly has to answer a new question. Whose data is this? Which vendor owns this product, this order line, this stock level, this price? The storefront was never the issue. The issue is that a marketplace is multi-tenant from the first table, and most shops are not.
So the first decision you make is also the one that costs the most if you get it wrong: do you build the tenancy yourself, or start from a backend that already has it. Retrofitting isolation onto a single-tenant shop is not a feature you add — it's a rewrite you discover. You thread a vendor_id through models, then through queries, then through the cart, then through the admin, and every place you forget becomes a data leak where one seller sees another seller's orders. This guide takes the other path: build on Aimeos, a Laravel ecommerce package that's multi-tenant from the data model up, and spend your time on the marketplace instead of the plumbing.
Decide where tenancy lives
Before any code, pick the foundation honestly, because it determines how much of the next month you spend on isolation you'll never show a user.
| Approach | Vendor isolation | Self-service onboarding | Scales to thousands of vendors |
|---|---|---|---|
| Build it yourself | you thread it through every query | you build it | you re-architect for it later |
| Single-tenant shop + add-on | bolted onto a single-tenant base | extension-dependent | medium |
| Aimeos | built into the data model, scoped per site | one env flag | designed for it, 1 to more than 1 billion items |
Build it yourself looks cheapest on a whiteboard and turns out to be the most expensive. Tenancy is a cross-cutting concern: it touches every model, every join, every report and every API endpoint, and the cost isn't the scoping code you write — it's the one clause you forget. A single missing filter in a join is one vendor reading another's orders, and you find it in production, not review. It also never stays finished. Every feature you add afterwards has to re-earn its isolation, so you end up maintaining a multi-tenancy framework as an unpaid side project to the marketplace you actually wanted to build.
Single-tenant shop + add-on moves the problem rather than solving it. The base assumes one merchant, so the extension grafts vendor columns and filters onto a schema that was never designed for them. Isolation then lives in the add-on's discipline instead of the data layer — it holds where the extension remembered to apply it and leaks at the edges the base shop reaches directly: admin tools, exports, and third-party plugins that have never heard of vendors. On top of that you inherit the add-on's release cycle and price, and you're betting it keeps pace with the platform it's bolted to.
The rest of this guide assumes the third row, where isolation is a property of the data model rather than something layered on top. Each step is a flag or a small amount of config, not a sprint.
Stand up the backend
You need PHP 8.2+ and a database (MySQL, MariaDB, PostgreSQL or SQL Server). The distribution wires the storefront, the admin, the APIs and a seeded catalog in one command.
composer create-project aimeos/aimeos myshop
Answer the prompts for database, mail and the admin account, then look around:
cd myshop
php artisan serve
The storefront is at http://127.0.0.1:8000, the admin at http://127.0.0.1:8000/admin. At this point you have a working single shop. The next two steps turn it into a marketplace.
Enable multi-vendor mode
The multi-vendor machinery ships in the box. You switch it on with one line in .env:
SHOP_MULTISHOP=true
That gives every vendor a scoped storefront and a scoped backend at their own site — Aimeos's word for a tenant. You can see what the flag did in the routing: every route gains a {site} segment, so the storefront, the JSON:API, the admin panels and the seller's own backend all scope to the vendor in the URL.
'admin' => ['prefix' => 'admin/{site}/jqadm', 'middleware' => ['web', 'auth', 'verified']],
'graphql' => ['prefix' => 'admin/{site}/graphql', 'middleware' => ['web', 'auth', 'verified']],
'jsonapi' => ['prefix' => '{site}/jsonapi', 'middleware' => ['web', 'api']],
'default' => ['prefix' => '{site}/shop', 'middleware' => ['web']],
'supplier' => ['prefix' => '{site}/s', 'middleware' => ['web']],
The {site} placeholder isn't there for pretty URLs. It's the seam that keeps one vendor's administration from reaching into another's, all the way down to the API.
Let vendors onboard themselves
Creating each seller account by hand doesn't scale past a demo. Turn on self-registration:
SHOP_REGISTRATION=true
A newly registered seller gets administrator rights over their own site and nothing else — their catalog, their orders, their customers, their settings, none of anyone else's. If that's more power than you want to hand a fresh signup, drop the default permission level:
SHOP_PERMISSION=editor
And if neither "admin" nor "editor" maps to the access you have in mind, the permission sets are themselves configuration. Publish your own version of the admin resource config and decide exactly which panels and actions each role can touch. The platform operator keeps the root; vendors get precisely the slice you grant them.
Understand the isolation you just got
It's worth knowing why the two flags above are enough, so you trust the result instead of double-checking it forever. Aimeos organizes everything around the site. Every record the system stores — products, prices, orders, stock — carries a site id, and the data layer filters on it automatically. You never write the where siteid = ? clause; the manager that loads the data already added it. That single design decision is what turns "build a marketplace" from a tenancy project back into a normal shop project.
Sites form a tree rather than a flat list, so a parent can hold shared catalog, categories or configuration that child vendors inherit, while each vendor still owns and overrides their own. A platform operator runs the root; vendors live underneath it with their data sealed off from each other by default.
Give each vendor a catalog and a storefront
Each seller logs into a backend that looks like a complete shop because, scoped to their site, it is one. They manage their own products with the full Aimeos catalog model behind them — variants, bundles, vouchers, virtual and downloadable goods, configurable and custom products, and subscriptions with recurring payments. A marketplace rarely sells one shape of thing; the moment one vendor wants tiered B2B pricing while another sells monthly boxes and a third sells license keys, a thin product table becomes the bottleneck. Aimeos models all of it without schema surgery, so you don't have to say no to a seller's business model.
On the storefront side, each vendor has a public supplier page (the /s route from Step 2) — a branded presence inside the marketplace with their catalog, profile and listings. Buyers shop across vendors; the basket and checkout are shared; the data behind each line stays attributed to the vendor that owns it.
Handle the money
This is the step teams put off and regret. The marketplace-specific concerns — routing the lines of a mixed-vendor order to the right sellers, commissions, and seller payouts — live in a dedicated marketplace extension that builds on the multi-vendor core. The core gives you isolation and per-vendor administration for free; the extension adds the commercial layer of running a platform that takes a cut.
Settle the money at the gateway rather than reconciling it by hand afterward. Aimeos ships payment extensions built for marketplaces — Stripe among them — that split each transaction the moment it's captured, sending the platform its commission and forwarding the remainder to the seller who fulfilled the line. Payouts stop being a monthly spreadsheet exercise and become a property of checkout: the buyer pays once, and the money lands where it's owed, already divided. The same model covers the awkward cases a marketplace inherits — refunds that have to claw back the right share, and orders spanning several vendors that need several payees from a single basket.
Plan for scale before you need it
Marketplaces don't fail at launch. They fail when they succeed — when a few dozen vendors become a few thousand, each with thousands of SKUs, and the catalog that felt instant at 5,000 products crawls at five million. Scale is the requirement that's invisible on day one and existential by month eighteen.
You don't implement anything extra here; you inherit it. Aimeos runs the same architecture from a single seller up past a billion items, with render times down to around 20ms and response times near 100ms on a properly built catalog. The performance work a hand-rolled marketplace postpones until it's an emergency is the work this backend already did, so growth stays a business problem instead of becoming a database firefight.
Go headless where it pays
Vendors increasingly want their own tooling — a mobile app to manage listings, a custom analytics view, an ERP that pushes inventory. Aimeos is API-first underneath the bundled storefront: a JSON:API following jsonapi.org for the buyer side and a GraphQL API for administration, both already scoped per site. Drive the whole marketplace headless, give vendors programmatic access to their own data, or keep the included storefront and only go headless where it pays. None of those are a rebuild — they're the same backend addressed differently.
Verify it
The claim worth testing is the boring one: that the isolation is real and you didn't have to write it. With SHOP_MULTISHOP=true and SHOP_REGISTRATION=true set, create a couple of vendor accounts, sign in as each, and confirm the obvious thing from the inside — neither one can see the other's catalog or orders, and nobody wrote a scoping clause to make that true.
The live frontend demo and admin demo are up if you want a look first, the docs cover the multi-vendor setup end to end, and the marketplace extension is where the commission and payout layer lives.
Implementing a marketplace is mostly about not implementing the parts that should already exist. Start from a backend that's multi-tenant by design, and the thing you ship is the marketplace — not the plumbing underneath it.