Back

Dynamic Shipping Prices

Adil Basri
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 :

bash
Shipping Total = Fixed Amount + (Total items in cart - 1) * Additional price per item

Implementing 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 :

bash
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.

See the solution in action

Tagged:
Guides