A marketplace is…
A marketplace, conceptually, is a platform where multiple vendors can sell various products to numerous customers. One key aspect I’ve learned is that typically, the marketplace retains funds until certain conditions are met (e.g an order has been delivered to the customer), after which payouts are made to vendors, including fees. In this blog series, we’ll delve into building a specific type of marketplace—a clothing marketplace where anyone can register and start selling their products. While we won’t cover every detail, the aim is to equip you with the knowledge to customize Medusa for creating a simple yet functional marketplace. You’ll likely need to manage many aspects independently, but this guide will prepare you well. It’s important to note that not every marketplace will be identical, and the provided examples might not exactly match the marketplace you envision. Let’s start by following the recipe detailed in the Medusa documentation. The documentation covers various concepts and sometimes includes actual code implementations. This will be a heavy first part, as it will condense certain points from the official documentation, but I promise that the rest of the parts will be lighter in terms of text.Before we proceed, I’ll assume you’ve already set up your Medusa app.
Before we start…
As we progress through this series, we will be enhancing and altering some of Medusa’s fundamental logic and functionality. However, the ability to use the sales channels feature flag may be impossible upon the design approach taken. The current design of the Cart system, particularly its integration with sales channels, poses a challenge. It is structured in a way that precludes the possibility of associating multiple sales channels with a single Cart. If you wish to leverage the sales channels feature, you have the flexibility to modify the Cart system or develop a similar mechanism to fully capitalize on its capabilities. You’ll learn how to disable thesales_channels feature flag by clicking here.
Following the recipe
The first part of our journey involves extending entities. The documentation guides us on how to begin this process, starting with the concept of aUser linked to a Store (where the User acts as a vendor, it’s distinct from a Customer).
Extending the User entity
Here’s how we can start extending theUser entity:
src/models/user.ts
Extending the Store entity
Next, we extend theStore entity to include a new property representing our OneToMany relationship, which is necessary to avoid type errors in the previously extended User model :
src/models/store.ts
Our First Migration
After extending theUser and Store entities, we proceed with a database migration to reflect these changes in the schema. We continue following the recipe by executing the following command in our terminal:
It’s crucial to manually write your migrations when updating an existing core entity to avoid errors. Detailed instructions are available in the callout section of the Medusa documentation on migrations.
up and down functions in our new migration with the ones provided in the docs :
src/migrations/<timestamp>-add-user-store-id.ts
How to apply migrations ?
To apply these migrations, we build our server and run the CLI command:store_id column in the user table!
 
Our First Middleware
We have just set up the foundation for our marketplace by extending the User and Store entities and creating the necessary migrations. Now, we’ll dive deeper into customizing the data management functionalities using middleware and service extensions.Registering a Logged-in User / Middleware
Medusa provides a way to create middleware that can be applied to specific routes. In the context of our marketplace, we want to ensure that the logged-in user’s information is available throughout our application, especially when retrieving data. Let’s create a new middleware that will register the logged-in user in the request scope:src/api/middlewares.ts
userService.
We then register the loggedInUser value in the request scope, which can be accessed by other services and components.
The middleware is applied to all 
/admin routes, except for a few specific routes that don’t require authentication (This is why the long regex)Extending the User Service
Next, let’s extend theUserService to automatically create a new store when a new user is registered. This will ensure that every user has a store associated with their account, which is a key requirement for our marketplace :
src/services/user.ts
UserService, we override the create method to check if the user has a store_id associated with their account. If not, we create a new store and associate it with the user’s account before creating the new user.
Let’s run our server and try to create a new User, we can use Postman or HTTPie to make a POST request to /admin/users when logged-in.
Let’s try with a simple payload like this one :
POST /admin/users
POST /admin/users
User a new Store is associated to it !
Common Issues
I have CORS errors since I’ve added middlewares
If you have any CORS errors when accessing the Admin UI, this might solves your issueDo not forget to add the environment variable 
ADMIN_CORS in your .env fileMy loggedInUser is undefined or null
If you have this issue and are sure that you are logged in before making a request, please update your LIFE_TIME services to TRANSIENT, it should fix the issues :
src/services/user.ts
GitHub Branch
You can access the complete part’s code here.Next Steps
And this is where this first part of the series ends, as the recipe gives us a few more concepts, such as associating astore_id with the creation of a product etc., before moving on to the “events/subscribers” part.
We’re not going to tackle events just yet, but rather continue to focus on service management and how to extend them so as to have everything nicely tied up to a vendor.