Extend Shipping Services
Build your own marketplace from scratch using Medusa
Now that we’ve extended the ShippingOption
and ShippingProfile
entities, we can start integrating new features into our services.
What’s the goal here ?
The aim of this part is to override various functions of the ShippingOption
and ShippingProfile
services, so that vendors can only access their own shipping options/profiles, and create a shipping option/profile for their store only.
We’ll also look at the concept of loaders, to create a default ShippingProfile
file for each store.
ShippingOptionService
Extend the service
Let’s start by extending the ShippingOptionService
file :
Override the ShippingOptionService.list
function
We will now override the ShippingOptionService.list
function and the ShippingOptionService.listAndCount
function:
Override the ShippingOptionService.create
function
We also override the ShippingOptionService.create
function and the CreateShippingOptionInput
type to allow for a store_id
property :
Override the ShippingOptionService.validateCartOption
A final function to be overrided is the validateCartOption
function, which validates a ShippingOption for a Cart before saving it in the Cart. Here, we’re going to make sure that a chosen shipping option, has one or more products that belongs to the same store :
ShippingProfileService
Extend the service
Before launching our server and starting to create ShippingOption, we need to extend ShippingProfileService :
Override the ShippingProfileService.list
By overriding this function, we can ensure that only the ShippingProfiles of the connected user’s store are listed:
Override the ShippingProfileService.create
When creating a ShippingProfile, if a user is logged in, we can assign its store_id
:
Override the ShippingProfile.retrieveDefault
function
Overriding this function allows for new created products being linked to the store’s shipping profile, this is useful for the storefront, since it will fetch Cart options depending on the shipping profile of the current products in the Cart :
Create the ShippingProfile.createDefaultForStore
function
This function will later allow us to create default ShippingProfile for our stores:
Here we have wrapped our process into a transaction (this.atomicPhase_
) , so that in the case of an error throwed when creating a user (for example, an email already in use), no event is sent and it will rollback changes.
Create your first loader
Before launching our server and creating ShippingOption, we’re going to make sure that each store has its own default ShippingProfile.
To do this, we’re going to make sure that, when the server starts, shipping profiles are created automatically for each new store.
In our case, we’re going to create a file in the src/loaders/create-defaults-shipping-profiles.ts
folder :
Perfect, but this will only work when we start our server, so we’ll also make sure that when a store is created, a default shipping profile is created, so that nothing needs to be restarted.
Update the StoreService
We’re going to update our StoreService so that it exposes a kind of enum that will represent events. These events will be emitted and listened to afterwards:
Update the UserService
Now we can use this event name in our UserService when creating a new store:
Create your first subscriber
Once our event is ready to emit, all we need to do is create a Subscriber that will listen and execute code when it receives the event. In this case, we’ll create a ShippingProfile each time a new store is created:
The ShippingProfile is now inserted each time a new store is created, without having to restart our server and wait for our loader to process :
We can now take the time to test the Admin UI with two separate accounts, for example.
In the screenshot below, we can see that each one sees only its own Shipping options, linked to their own Shipping Profile under the hood :
GitHub Branch
You can access the complete part’s code here.
Next Steps
In the next part, we’ll look into Orders, specifically how to ensure that each vendor can handle their own order. This will be an opportunity to use all we’ve learned in the previous parts, as well as to reuse the Subscriber notion from that current part!
Was this page helpful?