Implements Dynamic Shipping Prices
A common question in the Medusa community is how to adjust shipping costs dynamically based on certain conditions. One member asked on Discord how to increase the delivery price by a fixed amount depending on the total number of items in the cart, aiming for straightforward customization tailoring.

For example:
- A fixed base cost of $5
- Then add $2 for each additional item in the cart
So if the cart contains just one item → the delivery price is $5.
If there are 2 items in the cart → $7.
And so on...
In other words, we want to move beyond flat rates and make shipping responsive to order details. Let’s see how that can be solved with Medusa.
The idea: a custom Fulfillment Provider
To achieve dynamic pricing, we’ll rely on a custom FulfillmentProvider. This provider gives us full control over how shipping prices are calculated, so we can inject our own logic depending on business rules.
"The Medusa docs already walk you through setting up a provider step by step", so we won’t repeat that part here. What we care about in this guide is the calculatePrice
function.
Writing your pricing logic
Inside your custom provider, the calculatePrice
method will allow you to compute shipping rates dynamically. Here’s an example implementation that follows the rules we mentioned earlier:
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 // 1️⃣ Get total items in the cart
10 const totalItems = context.items.reduce((sum, item) => sum + Number(item.quantity), 0)
11
12 // 2️⃣ If no items, return 0
13 if (!totalItems) {
14 return { calculated_amount: 0, is_calculated_price_tax_inclusive: true }
15 }
16
17 // 3️⃣ Define base cost and extra per-item fee
18 const BASE_SHIPPING_COST = 5
19 const ADDITIONAL_ITEM_COST = 2
20
21 // 4️⃣ Calculate final amount
22 const totalPrice = BASE_SHIPPING_COST + (totalItems - 1) * ADDITIONAL_ITEM_COST
23
24 return {
25 calculated_amount: totalPrice,
26 is_calculated_price_tax_inclusive: true,
27 }
28 }
29}
30
What’s happening here is pretty straightforward: we start with a base amount and then add a fee depending on the number of items.
Hooking everything up
Once you’ve set up your custom provider, don’t forget to:
- Enable it in the Admin UI
- Configure it inside your regions where this shipping option should apply
At that point, the amount returned by the calculated_amount
property will be used as the final price shown to the customer and taken into account across Medusa’s checkout flow.
Takeaway
From here, you can extend it as much as you want:
- Adjust based on weight, zones, or cart value
- Add discounted rates under certain conditions
- Or even integrate third-party APIs for real-time shipping pricing
Access the complete "Gist here"