Overview
The Pricing Module manages product pricing with support for multiple currencies, customer groups, regions, and dynamic pricing rules. It provides flexible price calculation based on context.
Key Features:
Multi-currency pricing
Price lists with rules
Context-based price calculation
Customer group pricing
Region-specific prices
Time-based pricing (sales, schedules)
Bulk pricing rules
Price preferences
When to Use
Use the Pricing Module when you need to:
Set prices in multiple currencies
Create customer group discounts
Implement region-specific pricing
Run time-limited sales
Calculate context-aware prices
Support B2B and wholesale pricing
Configure minimum/maximum quantities
Handle complex pricing rules
Data Models
PriceSet
Groups prices for a product variant or other entity.
Unique price set identifier
Individual prices in this set
Price
Represents a specific price with optional rules.
ID of the parent price set
Three-letter ISO currency code
Minimum quantity for this price to apply
Maximum quantity for this price to apply
Pricing rules (region, customer group, etc.)
PriceRule
Defines conditions for price applicability.
Rule attribute (e.g., “region_id”, “customer_group_id”)
Rule priority for conflict resolution
PriceList
Groups prices for sales, promotions, or special pricing.
Unique price list identifier
List type: sale, override
When price list becomes active
Rules defining when list applies
PriceListRule
Defines conditions for price list applicability.
Allowed values for the attribute
PricePreference
Defines default pricing behavior.
Unique preference identifier
Whether prices include tax
Service Interface
The Pricing Module service is available at @medusajs/medusa/pricing.
Create Price Set
Create a price set for a product variant.
import { MedusaRequest , MedusaResponse } from "@medusajs/framework/http"
import { IPricingModuleService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
export async function POST (
req : MedusaRequest ,
res : MedusaResponse
) {
const pricingModuleService : IPricingModuleService = req . scope . resolve (
Modules . PRICING
)
const priceSet = await pricingModuleService . createPriceSets ({
prices: [
{
amount: 2000 ,
currency_code: "usd" ,
rules: {},
},
{
amount: 1800 ,
currency_code: "eur" ,
rules: {},
},
],
})
res . json ({ price_set: priceSet })
}
data
CreatePriceSetDTO | CreatePriceSetDTO[]
required
Price set data Prices to create in this set
priceSet
PriceSetDTO | PriceSetDTO[]
The created price set(s)
Add Prices
Add prices to an existing price set.
Simple Price
With Rules
Quantity-Based
await pricingModuleService . addPrices ({
priceSetId: "pset_123" ,
prices: [
{
amount: 1500 ,
currency_code: "gbp" ,
rules: {},
},
],
})
Price data prices
CreatePricesDTO[]
required
Prices to add
Calculate Prices
Calculate prices based on context.
const calculatedPrices = await pricingModuleService . calculatePrices (
{ id: [ "pset_123" , "pset_456" ] },
{
context: {
currency_code: "usd" ,
region_id: "reg_us" ,
customer_group_id: "cgroup_vip" ,
},
}
)
for ( const result of calculatedPrices ) {
console . log ( result . id , result . calculated_amount )
}
Filters to select price sets Price set IDs to calculate
Pricing context Currency code for calculation
Region ID for region-specific pricing
Customer group ID for group pricing
Quantity for quantity-based pricing
Array of calculated prices with calculated_amount field
Create Price List
Create a price list for sales or special pricing.
const priceList = await pricingModuleService . createPriceLists ({
title: "Summer Sale 2024" ,
description: "20% off summer items" ,
type: "sale" ,
status: "active" ,
starts_at: new Date ( "2024-06-01" ),
ends_at: new Date ( "2024-08-31" ),
rules: [
{
attribute: "region_id" ,
value: [ "reg_us" , "reg_eu" ],
},
],
})
data
CreatePriceListDTO | CreatePriceListDTO[]
required
Price list data List type: sale, override
Set Price List Prices
Add prices to a price list.
await pricingModuleService . setPriceListPrices ([
{
price_list_id: "plist_123" ,
price_set_id: "pset_456" ,
amount: 1600 , // Discounted price
currency_code: "usd" ,
},
])
Remove Price List Prices
Remove prices from a price list.
await pricingModuleService . removePriceListPrices ([
"plist_123_pset_456" ,
])
Integration Examples
With Product Module
Create prices for product variants.
import { Modules } from "@medusajs/framework/utils"
const productModule = container . resolve ( Modules . PRODUCT )
const pricingModule = container . resolve ( Modules . PRICING )
// Create product
const product = await productModule . createProducts ({
title: "T-Shirt" ,
variants: [
{ title: "Small" , sku: "TSHIRT-S" },
],
})
const variant = product . variants [ 0 ]
// Create price set
const priceSet = await pricingModule . createPriceSets ({
prices: [
{ amount: 2000 , currency_code: "usd" , rules: {} },
{ amount: 1800 , currency_code: "eur" , rules: {} },
],
})
// Link price set to variant (via workflows)
With Cart Module
Calculate prices for cart items.
import { Modules } from "@medusajs/framework/utils"
const cartModule = container . resolve ( Modules . CART )
const pricingModule = container . resolve ( Modules . PRICING )
// Get cart
const cart = await cartModule . retrieveCart ( "cart_123" , {
relations: [ "items" ],
})
// Calculate prices for all items
const priceSetIds = cart . items . map ( item => item . variant . price_set_id )
const prices = await pricingModule . calculatePrices (
{ id: priceSetIds },
{
context: {
currency_code: cart . currency_code ,
region_id: cart . region_id ,
customer_group_id: cart . customer ?. group_id ,
},
}
)
// Update cart items with calculated prices
for ( let i = 0 ; i < cart . items . length ; i ++ ) {
await cartModule . updateLineItems ( cart . items [ i ]. id , {
unit_price: prices [ i ]. calculated_amount ,
})
}
With Customer Module
Customer group pricing.
import { Modules } from "@medusajs/framework/utils"
const customerModule = container . resolve ( Modules . CUSTOMER )
const pricingModule = container . resolve ( Modules . PRICING )
// Get customer with groups
const customer = await customerModule . retrieveCustomer ( "cus_123" , {
relations: [ "groups" ],
})
const customerGroupId = customer . groups [ 0 ]?. id
// Calculate prices for customer group
const prices = await pricingModule . calculatePrices (
{ id: [ "pset_123" ] },
{
context: {
currency_code: "usd" ,
customer_group_id: customerGroupId ,
},
}
)
With Region Module
Region-based pricing.
import { Modules } from "@medusajs/framework/utils"
const regionModule = container . resolve ( Modules . REGION )
const pricingModule = container . resolve ( Modules . PRICING )
// Get region
const region = await regionModule . retrieveRegion ( "reg_us" )
// Add region-specific price
await pricingModule . addPrices ({
priceSetId: "pset_123" ,
prices: [
{
amount: 2000 ,
currency_code: region . currency_code ,
rules: {
region_id: region . id ,
},
},
],
})
Pricing Strategies
Multi-Currency
// Add prices in multiple currencies
await pricingModule . addPrices ({
priceSetId: "pset_123" ,
prices: [
{ amount: 2000 , currency_code: "usd" , rules: {} },
{ amount: 1800 , currency_code: "eur" , rules: {} },
{ amount: 1500 , currency_code: "gbp" , rules: {} },
{ amount: 170000 , currency_code: "jpy" , rules: {} },
],
})
Tiered Pricing (Quantity Discounts)
// Volume discounts
await pricingModule . addPrices ({
priceSetId: "pset_123" ,
prices: [
{
amount: 2000 ,
currency_code: "usd" ,
min_quantity: 1 ,
max_quantity: 9 ,
rules: {},
},
{
amount: 1800 ,
currency_code: "usd" ,
min_quantity: 10 ,
max_quantity: 49 ,
rules: {},
},
{
amount: 1600 ,
currency_code: "usd" ,
min_quantity: 50 ,
rules: {},
},
],
})
Customer Group Pricing (B2B)
// Wholesale pricing
await pricingModule . addPrices ({
priceSetId: "pset_123" ,
prices: [
{
amount: 2000 ,
currency_code: "usd" ,
rules: {}, // Retail price
},
{
amount: 1400 ,
currency_code: "usd" ,
rules: {
customer_group_id: "cgroup_wholesale" ,
},
},
{
amount: 1200 ,
currency_code: "usd" ,
rules: {
customer_group_id: "cgroup_distributor" ,
},
},
],
})
Flash Sales
// Time-limited sale
const flashSale = await pricingModule . createPriceLists ({
title: "24-Hour Flash Sale" ,
type: "sale" ,
status: "active" ,
starts_at: new Date (),
ends_at: new Date ( Date . now () + 24 * 60 * 60 * 1000 ), // 24 hours
rules: [],
})
// Add discounted prices
await pricingModule . setPriceListPrices ([
{
price_list_id: flashSale . id ,
price_set_id: "pset_123" ,
amount: 1500 , // 25% off from $20
currency_code: "usd" ,
},
])
Best Practices
Rule Priority : When multiple prices match the context, the module selects based on rule specificity. More specific rules (with more conditions) take precedence.
Currency Codes : Always use lowercase three-letter ISO currency codes (“usd”, not “USD”).
Quantity Ranges : Use min_quantity and max_quantity for tiered pricing. Ensure ranges don’t overlap.
Price List Types :
sale: Reduces prices (used for promotions)
override: Replaces prices entirely
Context Calculation : Include all relevant context when calculating prices (currency, region, customer group, quantity) for accurate results.
Tax Inclusion : Use PricePreference.is_tax_inclusive to indicate if prices include tax. This affects tax calculations in other modules.