Skip to main content

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.
id
string
required
Unique price set identifier
prices
Price[]
Individual prices in this set

Price

Represents a specific price with optional rules.
id
string
required
Unique price identifier
price_set_id
string
required
ID of the parent price set
amount
BigNumber
required
Price amount
currency_code
string
required
Three-letter ISO currency code
min_quantity
number
Minimum quantity for this price to apply
max_quantity
number
Maximum quantity for this price to apply
rules
PriceRule[]
Pricing rules (region, customer group, etc.)

PriceRule

Defines conditions for price applicability.
id
string
required
Unique rule identifier
price_id
string
required
ID of the price
attribute
string
required
Rule attribute (e.g., “region_id”, “customer_group_id”)
value
string
required
Rule value
priority
number
Rule priority for conflict resolution

PriceList

Groups prices for sales, promotions, or special pricing.
id
string
required
Unique price list identifier
title
string
required
Price list title
description
string
Price list description
type
PriceListType
required
List type: sale, override
status
PriceListStatus
required
Status: active, draft
starts_at
DateTime
When price list becomes active
ends_at
DateTime
When price list expires
rules
PriceListRule[]
Rules defining when list applies

PriceListRule

Defines conditions for price list applicability.
id
string
required
Unique rule identifier
price_list_id
string
required
ID of the price list
attribute
string
required
Rule attribute
value
string[]
required
Allowed values for the attribute

PricePreference

Defines default pricing behavior.
id
string
required
Unique preference identifier
attribute
string
Preference attribute
value
string
Preference value
is_tax_inclusive
boolean
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
CreatePricesDTO[]
Prices to create in this set
priceSet
PriceSetDTO | PriceSetDTO[]
The created price set(s)

Add Prices

Add prices to an existing price set.
await pricingModuleService.addPrices({
  priceSetId: "pset_123",
  prices: [
    {
      amount: 1500,
      currency_code: "gbp",
      rules: {},
    },
  ],
})
data
AddPricesDTO
required
Price data
priceSetId
string
required
ID of the price set
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
PricingFilters
required
Filters to select price sets
id
string[]
Price set IDs to calculate
context
PricingContext
required
Pricing context
currency_code
string
Currency code for calculation
region_id
string
Region ID for region-specific pricing
customer_group_id
string
Customer group ID for group pricing
quantity
number
Quantity for quantity-based pricing
calculatedPrices
CalculatedPriceSet[]
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
title
string
required
Price list title
description
string
Price list description
type
PriceListType
required
List type: sale, override
status
PriceListStatus
Status: active, draft
starts_at
Date
When list becomes active
ends_at
Date
When list expires
rules
CreatePriceListRuleDTO[]
Applicability rules

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

  1. Rule Priority: When multiple prices match the context, the module selects based on rule specificity. More specific rules (with more conditions) take precedence.
  2. Currency Codes: Always use lowercase three-letter ISO currency codes (“usd”, not “USD”).
  3. Quantity Ranges: Use min_quantity and max_quantity for tiered pricing. Ensure ranges don’t overlap.
  4. Price List Types:
    • sale: Reduces prices (used for promotions)
    • override: Replaces prices entirely
  5. Context Calculation: Include all relevant context when calculating prices (currency, region, customer group, quantity) for accurate results.
  6. Tax Inclusion: Use PricePreference.is_tax_inclusive to indicate if prices include tax. This affects tax calculations in other modules.

Build docs developers (and LLMs) love