Dynamic Shipping Prices

If you need to manage dynamic shipping costs based on certain conditions, rest assured, you're not alone. In this guide, we'll see how to set this up on Medusa.
Understanding the challenge
In the case of Discord community member, they wanted to increase the price based on a fixed amount, depending on the total number of items in the cart.
Here's the scenario:
- Fixed amount of $5 for the base shipping option
- $2 per item added to the cart
In the case where we only have one item in the cart, the price would be equal to $5 (since we only have one item). If we have 2 items, then the price would be $7.
Here is the formula in a nutshell :
Shipping Total = Fixed Amount + (Total items in cart - 1) * Additional price per itemImplementing the custom shipping solution
What we need to keep in mind here is that we'll need a new fulfillment provider, one that we can customize as we wish and inject our own logic. The official documentation covers the creation of a FulfillmentProvider "here".
Once your FulfillmentProvider is created, the function we're going to be interested in modifying is calculatePrice, it's inside that function that the magic will happen :
1class CustomFulfillmentService extends AbstractFulfillmentProviderService {
2 static identifier = "custom-fulfillment";
3
4 async calculatePrice(
5 optionData: CalculateShippingOptionPriceDTO["optionData"],
6 data: CalculateShippingOptionPriceDTO["data"],
7 context: CalculateShippingOptionPriceDTO["context"]
8 ): Promise<CalculatedShippingOptionPrice> {
9 // Get the total number of items in the cart
10 const totalItems = context.items.reduce(
11 (sum, item) => sum + Number(item.quantity),
12 0
13 );
14
15 // If there are no items, return 0
16 if (!totalItems) {
17 return {
18 calculated_amount: 0,
19 is_calculated_price_tax_inclusive: true,
20 };
21 }
22
23 // Define the base shipping cost and the additional item shipping cost
24 const BASE_SHIPPING_COST = 5; // $5 in cents
25 const ADDITIONAL_ITEM_SHIPPING_COST = 2; // $2 in cents
26
27 // Calculate the total price
28 const totalPrice =
29 BASE_SHIPPING_COST +
30 (totalItems - 1) * ADDITIONAL_ITEM_SHIPPING_COST;
31
32 return {
33 calculated_amount: totalPrice,
34 is_calculated_price_tax_inclusive: true,
35 };
36 }
37
38 // ...
39}The returned calculated_amount is the price that will be displayed to the customer and used for any further calculations inside Medusa.
Note
Don't forget to enable your FulfillmentProvider in the Admin UI and setup everything related to it inside your regions.