Skip to main content

Overview

The Cart Module manages shopping carts and their associated data including line items, shipping methods, addresses, and real-time total calculations. It provides the foundation for the checkout process. Key Features:
  • Cart and line item management
  • Real-time total calculations
  • Tax line and adjustment tracking
  • Shipping method integration
  • Cart completion tracking
  • Credit lines for store credit
  • Multi-currency support

When to Use

Use the Cart Module when you need to:
  • Create and manage shopping carts
  • Add/remove products to carts
  • Calculate cart totals with taxes and discounts
  • Track shipping methods and costs
  • Store customer shipping and billing addresses
  • Handle cart-to-order conversion
  • Support guest and registered customer carts

Data Models

Cart

The core cart entity representing a shopping session.
id
string
required
Unique cart identifier (prefix: cart_)
region_id
string
ID of the associated region
customer_id
string
ID of the customer (null for guest carts)
sales_channel_id
string
ID of the sales channel
email
string
Customer email address
currency_code
string
required
Three-letter ISO currency code
locale
string
BCP 47 language tag (e.g., “en-US”)
completed_at
DateTime
Timestamp when cart was completed (converted to order)
items
LineItem[]
Products added to the cart
shipping_address
Address
Shipping address for the cart
billing_address
Address
Billing address for the cart
shipping_methods
ShippingMethod[]
Selected shipping methods
credit_lines
CreditLine[]
Store credit applied to the cart

LineItem

Represents a product in the cart.
id
string
required
Unique line item identifier
cart_id
string
required
ID of the parent cart
title
string
required
Product title
subtitle
string
Product subtitle or variant title
thumbnail
string
Product thumbnail URL
quantity
number
required
Item quantity
product_id
string
ID of the product
variant_id
string
ID of the product variant
unit_price
BigNumber
required
Price per unit before discounts
is_discountable
boolean
Whether discounts can be applied
is_tax_inclusive
boolean
Whether price includes tax
tax_lines
LineItemTaxLine[]
Tax lines applied to this item
adjustments
LineItemAdjustment[]
Discount adjustments applied to this item
metadata
object
Additional custom data

ShippingMethod

Represents a shipping option for the cart.
id
string
required
Unique shipping method identifier
cart_id
string
required
ID of the parent cart
name
string
required
Shipping method name
amount
BigNumber
required
Shipping cost before discounts
is_tax_inclusive
boolean
Whether amount includes tax
shipping_option_id
string
Reference to the fulfillment shipping option
data
object
Provider-specific data
tax_lines
ShippingMethodTaxLine[]
Tax lines applied to shipping
adjustments
ShippingMethodAdjustment[]
Discount adjustments applied to shipping

Address

Shipping or billing address for the cart.
id
string
required
Unique address identifier
customer_id
string
Associated customer ID
first_name
string
First name
last_name
string
Last name
phone
string
Phone number
company
string
Company name
address_1
string
Address line 1
address_2
string
Address line 2
city
string
City
country_code
string
Two-letter ISO country code
province
string
State or province
postal_code
string
Postal/ZIP code

Calculated Totals

The Cart Module automatically calculates totals when specific fields are requested. These are not stored but computed on-demand:
total
BigNumber
Final cart total after all adjustments and taxes
subtotal
BigNumber
Sum of line item subtotals before shipping
tax_total
BigNumber
Total tax amount
discount_total
BigNumber
Total discount amount
shipping_total
BigNumber
Total shipping cost after discounts and taxes
item_total
BigNumber
Sum of all line item totals
item_tax_total
BigNumber
Total tax on line items
shipping_tax_total
BigNumber
Total tax on shipping

Service Interface

The Cart Module service is available at @medusajs/medusa/cart.

Retrieve Cart

Retrieve a single cart with totals.
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { ICartModuleService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"

export async function GET(
  req: MedusaRequest,
  res: MedusaResponse
) {
  const cartModuleService: ICartModuleService = req.scope.resolve(
    Modules.CART
  )

  const cart = await cartModuleService.retrieveCart("cart_123", {
    select: [
      "id",
      "email",
      "currency_code",
      "total",
      "subtotal",
      "tax_total",
    ],
    relations: [
      "items",
      "items.tax_lines",
      "items.adjustments",
      "shipping_methods",
      "shipping_address",
    ],
  })

  res.json({ cart })
}
cartId
string
required
The ID of the cart to retrieve
config
FindConfig
Configuration for the query
select
string[]
Fields to select (include total fields to calculate them)
relations
string[]
Relations to load. Required relations for totals: items, items.tax_lines, items.adjustments, shipping_methods, shipping_methods.tax_lines, shipping_methods.adjustments
cart
CartDTO
The retrieved cart with calculated totals

List Carts

List carts with filtering.
const carts = await cartModuleService.listCarts(
  {
    customer_id: "cus_123",
    completed_at: null,
  },
  {
    relations: ["items"],
    take: 10,
  }
)
filters
FilterableCartProps
Filters to apply
id
string | string[]
Filter by cart IDs
customer_id
string | string[]
Filter by customer IDs
sales_channel_id
string | string[]
Filter by sales channel IDs
email
string
Filter by email
completed_at
null | object
Filter by completion status (null for active carts)

Create Carts

Create a new shopping cart.
const cart = await cartModuleService.createCarts({
  region_id: "reg_us",
  customer_id: "cus_123",
  email: "[email protected]",
  currency_code: "usd",
  sales_channel_id: "sc_web",
  items: [
    {
      title: "Medusa T-Shirt",
      subtitle: "Size: Large",
      product_id: "prod_123",
      variant_id: "variant_456",
      quantity: 2,
      unit_price: 2000,
    },
  ],
})
data
CreateCartDTO | CreateCartDTO[]
required
Cart data to create
region_id
string
ID of the region
customer_id
string
ID of the customer (omit for guest cart)
email
string
Customer email
currency_code
string
required
Three-letter ISO currency code
sales_channel_id
string
ID of the sales channel
items
CreateLineItemDTO[]
Initial line items
cart
CartDTO | CartDTO[]
The created cart(s)

Update Carts

Update cart information.
const cart = await cartModuleService.updateCarts("cart_123", {
  email: "[email protected]",
  region_id: "reg_eu",
  currency_code: "eur",
})
cartId
string
required
The ID of the cart to update
data
UpdateCartDTO
required
Cart data to update

Create Line Items

Add products to a cart.
const lineItem = await cartModuleService.createLineItems({
  cart_id: "cart_123",
  title: "Medusa Hoodie",
  subtitle: "Size: Medium, Color: Black",
  product_id: "prod_789",
  variant_id: "variant_101",
  quantity: 1,
  unit_price: 5000,
})
data
CreateLineItemDTO | CreateLineItemDTO[]
required
Line item data
cart_id
string
required
ID of the cart
title
string
required
Product title
product_id
string
ID of the product
variant_id
string
ID of the product variant
quantity
number
required
Item quantity
unit_price
number
required
Price per unit

Update Line Items

Update cart line items (e.g., change quantity).
const lineItem = await cartModuleService.updateLineItems("item_123", {
  quantity: 3,
})

Delete Line Items

Remove items from the cart.
await cartModuleService.deleteLineItems(["item_123", "item_456"])

Create Shipping Methods

Add shipping method to cart.
const shippingMethod = await cartModuleService.createShippingMethods({
  cart_id: "cart_123",
  name: "Standard Shipping",
  amount: 500,
  shipping_option_id: "so_standard",
})
data
CreateShippingMethodDTO | CreateShippingMethodDTO[]
required
Shipping method data
cart_id
string
required
ID of the cart
name
string
required
Shipping method name
amount
number
required
Shipping cost
shipping_option_id
string
Reference to fulfillment shipping option

Add Addresses

Set shipping and billing addresses.
const cart = await cartModuleService.updateCarts("cart_123", {
  shipping_address: {
    first_name: "John",
    last_name: "Doe",
    address_1: "123 Main St",
    city: "New York",
    country_code: "us",
    postal_code: "10001",
  },
  billing_address: {
    first_name: "John",
    last_name: "Doe",
    address_1: "456 Billing Ave",
    city: "New York",
    country_code: "us",
    postal_code: "10002",
  },
})

Integration Examples

With Product Module

Add products to cart by retrieving product data.
import { Modules } from "@medusajs/framework/utils"

const productModule = container.resolve(Modules.PRODUCT)
const cartModule = container.resolve(Modules.CART)

// Retrieve product with variant
const product = await productModule.retrieveProduct("prod_123", {
  relations: ["variants"],
})

const variant = product.variants[0]

// Add to cart
await cartModule.createLineItems({
  cart_id: "cart_123",
  title: product.title,
  subtitle: variant.title,
  product_id: product.id,
  variant_id: variant.id,
  quantity: 1,
  unit_price: 2000, // From pricing module
})

With Pricing Module

Calculate prices before adding to cart.
import { Modules } from "@medusajs/framework/utils"

const pricingModule = container.resolve(Modules.PRICING)

// Calculate price for variant
const priceSet = await pricingModule.calculatePrices(
  { id: ["variant_456"] },
  {
    context: {
      currency_code: "usd",
      region_id: "reg_us",
    },
  }
)

const price = priceSet[0].calculated_amount

// Add to cart with calculated price
await cartModule.createLineItems({
  cart_id: "cart_123",
  variant_id: "variant_456",
  quantity: 1,
  unit_price: price,
  // ...
})

With Promotion Module

Apply promotions as adjustments.
import { Modules } from "@medusajs/framework/utils"

const promotionModule = container.resolve(Modules.PROMOTION)

// Compute promotions
const promotions = await promotionModule.computeActions(
  ["promo_123"],
  {
    items: cart.items,
  }
)

// Apply as line item adjustments
for (const action of promotions.actions) {
  await cartModule.createLineItemAdjustments({
    item_id: action.item_id,
    amount: -action.amount,
    code: action.code,
  })
}

With Tax Module

Calculate and apply tax lines.
import { Modules } from "@medusajs/framework/utils"

const taxModule = container.resolve(Modules.TAX)

// Calculate taxes
const taxLines = await taxModule.getTaxLines(
  cart.items,
  {
    address: cart.shipping_address,
  }
)

// Apply tax lines to items
for (const taxLine of taxLines) {
  await cartModule.createLineItemTaxLines({
    item_id: taxLine.item_id,
    rate: taxLine.rate,
    code: taxLine.code,
    name: taxLine.name,
  })
}

Converting to Order

Mark cart as completed and create order.
import { Modules } from "@medusajs/framework/utils"

const orderModule = container.resolve(Modules.ORDER)

// Create order from cart
const order = await orderModule.createOrders({
  customer_id: cart.customer_id,
  email: cart.email,
  currency_code: cart.currency_code,
  items: cart.items,
  shipping_address: cart.shipping_address,
  billing_address: cart.billing_address,
  shipping_methods: cart.shipping_methods,
})

// Mark cart as completed
await cartModule.updateCarts(cart.id, {
  completed_at: new Date(),
})

Best Practices

  1. Total Calculation: To calculate totals, you must include total fields in select and required relations (items, items.tax_lines, items.adjustments, shipping_methods, etc.). The module automatically includes needed relations when total fields are selected.
  2. Currency Consistency: Ensure all prices (line items, shipping, adjustments) use the same currency as the cart.
  3. Guest Carts: For guest carts, omit customer_id but always include email for order conversion.
  4. Cart Completion: Set completed_at when converting to an order to prevent reuse.
  5. Adjustments: Use negative amounts for discounts in LineItemAdjustment and ShippingMethodAdjustment.
  6. Tax-Inclusive Pricing: Use the is_tax_inclusive flag to indicate if prices already include tax.

Build docs developers (and LLMs) love