Back to all posts

Implements Dynamic Shipping Prices

Adil Basri

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.

Implements Dynamic Shipping Prices

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:

typescript
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"

Tagged:
Guide