Back to Medusa

{metadata.title}

www/apps/resources/app/commerce-modules/cart/cart-totals/page.mdx

2.14.211.7 KB
Original Source

import { CodeTabs, CodeTab } from "docs-ui"

export const metadata = { title: Retrieve Cart Totals using Query, }

{metadata.title}

In this guide, you'll learn how to retrieve cart totals in your Medusa application using Query.

You may need to retrieve cart totals in your Medusa customizations, such as workflows or custom API routes, to perform custom actions with them. The ideal way to retrieve totals is with Query.

<Note title="Looking for a storefront guide?">

Refer to the Retrieve Cart Totals in Storefront guide for a storefront-specific approach.

</Note>

How to Retrieve Cart Totals with Query

To retrieve cart totals, you mainly need to pass the total field within the fields option of the Query. This will return the cart's grand total, along with the totals of its line items and shipping methods. You can also pass additional total fields that you need for your use case.

For example, to retrieve all totals of a cart:

<Note title="Tip">

Use useQueryGraphStep in workflows, and query.graph in custom API routes, scheduled jobs, and subscribers.

</Note> <CodeTabs group="query-type"> <CodeTab label="useQueryGraphStep" value="useQueryGraphStep">
ts
import { createWorkflow } from "@medusajs/framework/workflows-sdk"
import { useQueryGraphStep } from "@medusajs/medusa/core-flows"

export const myWorkflow = createWorkflow(
  "my-workflow",
  () => {
    const { data: carts } = useQueryGraphStep({
      entity: "cart",
      fields: [
        "id",
        "currency_code",
        "total",
        "subtotal",
        "tax_total",
        "discount_total",
        "discount_subtotal",
        "discount_tax_total",
        "original_total",
        "original_tax_total",
        "item_total",
        "item_subtotal",
        "item_tax_total",
        "original_item_total",
        "original_item_subtotal",
        "original_item_tax_total",
        "shipping_total",
        "shipping_subtotal",
        "shipping_tax_total",
        "original_shipping_tax_total",
        "original_shipping_subtotal",
        "original_shipping_total",
        "gift_card_total",
        "gift_card_tax_total",
        "credit_line_subtotal",
        "credit_line_tax_total",
        "credit_line_total",
        "items.*",
        "shipping_methods.*",
      ],
      filters: {
        id: "cart_123", // Specify the cart ID
      },
    })
  }
)
</CodeTab> <CodeTab label="query.graph" value="query.graph">
ts
const query = container.resolve("query") // or req.scope.resolve in API routes

const { data: [cart] } = await query.graph({
  entity: "cart",
  fields: [
    "id",
    "currency_code",
    "total",
    "subtotal",
    "tax_total",
    "discount_total",
    "discount_subtotal",
    "discount_tax_total",
    "original_total",
    "original_tax_total",
    "item_total",
    "item_subtotal",
    "item_tax_total",
    "original_item_total",
    "original_item_subtotal",
    "original_item_tax_total",
    "shipping_total",
    "shipping_subtotal",
    "shipping_tax_total",
    "original_shipping_tax_total",
    "original_shipping_subtotal",
    "original_shipping_total",
    "gift_card_total",
    "gift_card_tax_total",
    "credit_line_subtotal",
    "credit_line_tax_total",
    "credit_line_total",
    "items.*",
    "shipping_methods.*",
  ],
  filters: {
    id: "cart_123", // Specify the cart ID
  },
})
</CodeTab> </CodeTabs>

The returned cart object will look like this:

json
{
  "id": "cart_123",
  "currency_code": "usd",
  "total": 10,
  "subtotal": 10,
  "tax_total": 0,
  "discount_total": 0,
  "discount_subtotal": 0,
  "discount_tax_total": 0,
  "original_total": 10,
  "original_tax_total": 0,
  "item_total": 10,
  "item_subtotal": 10,
  "item_tax_total": 0,
  "original_item_total": 10,
  "original_item_subtotal": 10,
  "original_item_tax_total": 0,
  "shipping_total": 10,
  "shipping_subtotal": 10,
  "shipping_tax_total": 0,
  "original_shipping_tax_total": 0,
  "original_shipping_subtotal": 10,
  "original_shipping_total": 10,
  "gift_card_total": 0,
  "gift_card_tax_total": 0,
  "credit_line_subtotal": 0,
  "credit_line_tax_total": 0,
  "credit_line_total": 0,
  "items": [
    {
      "id": "cali_123",
      // ...
      "unit_price": 10,
      "subtotal": 10,
      "total": 0,
      "original_total": 10,
      "discount_total": 0,
      "discount_subtotal": 0,
      "discount_tax_total": 0,
      "tax_total": 0,
      "original_tax_total": 0,
    }
  ],
  "shipping_methods": [
    {
      "id": "casm_01K10AYZDKZGQXE8WXW3QP9T22",
      // ...
      "amount": 10,
      "subtotal": 10,
      "total": 10,
      "original_total": 10,
      "discount_total": 0,
      "discount_subtotal": 0,
      "discount_tax_total": 0,
      "tax_total": 0,
      "original_tax_total": 0,
    }
  ]
}

Cart Totals

The cart will include the following total fields:

  • total: The cart's final total after discounts and credit lines, including taxes.
  • subtotal: The cart's subtotal before discounts, excluding taxes. Calculated as the sum of item_subtotal and shipping_subtotal.
  • tax_total: The cart's tax total after discounts. Calculated as the sum of item_tax_total and shipping_tax_total.
  • discount_total: The total amount of discounts applied to the cart, including the tax portion of discounts.
  • discount_subtotal: The total amount of discounts applied to the cart's subtotal (excluding tax portion). Used in the final total calculation.
  • discount_tax_total: The total amount of discounts applied to the cart's tax. Represents the tax portion of discounts.
  • original_total: The cart's total before discounts, including taxes. Calculated as the sum of original_item_total and original_shipping_total.
  • original_tax_total: The cart's tax total before discounts. Calculated as the sum of original_item_tax_total and original_shipping_tax_total.
  • item_total: The sum of all line items' totals after discounts, including taxes.
  • item_subtotal: The sum of all line items' subtotals before discounts, excluding taxes.
  • item_tax_total: The sum of all line items' tax totals after discounts.
  • original_item_total: The sum of all line items' original totals before discounts, including taxes.
  • original_item_subtotal: The sum of all line items' original subtotals before discounts, excluding taxes.
  • original_item_tax_total: The sum of all line items' original tax totals before discounts.
  • shipping_total: The sum of all shipping methods' totals after discounts, including taxes.
  • shipping_subtotal: The sum of all shipping methods' subtotals before discounts, excluding taxes.
  • shipping_tax_total: The sum of all shipping methods' tax totals after discounts.
  • original_shipping_tax_total: The sum of all shipping methods' original tax totals before discounts.
  • original_shipping_subtotal: The sum of all shipping methods' original subtotals before discounts, excluding taxes.
  • original_shipping_total: The sum of all shipping methods' original totals before discounts, including taxes.
  • gift_card_total: The total amount of gift cards applied to the cart.
  • gift_card_tax_total: The tax total of gift cards applied to the cart.
  • credit_line_subtotal: The subtotal of credit lines applied to the cart, excluding taxes.
  • credit_line_tax_total: The tax total of credit lines applied to the cart.
  • credit_line_total: The total amount of credit lines applied to the cart, including taxes. Subtracted from the final total.

Cart Line Item Totals

The items array in the cart object contains total fields for each line item:

  • unit_price: The price of a single unit of the line item. This field is not calculated and is stored in the database.
  • subtotal: The line item's subtotal before discounts, excluding taxes.
  • total: The line item's total after discounts, including taxes.
  • original_total: The line item's original total before discounts, including taxes.
  • discount_total: The total amount of discounts applied to the line item, including the tax portion of discounts.
  • discount_subtotal: The total amount of discounts applied to the line item's subtotal (excluding tax portion).
  • discount_tax_total: The total amount of discounts applied to the line item's tax. Represents the tax portion of discounts.
  • tax_total: The line item's tax total after discounts.
  • original_tax_total: The line item's original tax total before discounts.

Cart Shipping Method Totals

The shipping_methods array in the cart object contains total fields for each shipping method:

  • amount: The amount charged for the shipping method. This field is not calculated and is stored in the database.
  • subtotal: The shipping method's subtotal before discounts, excluding taxes.
  • total: The shipping method's total after discounts, including taxes.
  • original_total: The shipping method's original total before discounts, including taxes.
  • discount_total: The total amount of discounts applied to the shipping method, including the tax portion of discounts.
  • discount_subtotal: The total amount of discounts applied to the shipping method's subtotal (excluding tax portion).
  • discount_tax_total: The total amount of discounts applied to the shipping method's tax. Represents the tax portion of discounts.
  • tax_total: The shipping method's tax total after discounts.
  • original_tax_total: The shipping method's original tax total before discounts.

Caveats of Retrieving Cart Totals

Using Asterisk (*) in Cart's Query

Cart totals are calculated based on the cart's line items, shipping methods, taxes, and any discounts applied. They are not stored in the Cart data model.

For that reason, you cannot retrieve cart totals by passing * to the Query's fields. For example, the following query will not return cart totals:

<CodeTabs group="query-type"> <CodeTab label="useQueryGraphStep" value="useQueryGraphStep">
ts
const { data: carts } = useQueryGraphStep({
  entity: "cart",
  fields: ["*"],
  filters: {
    id: "cart_123",
  },
})

// carts don't include cart totals
</CodeTab> <CodeTab label="query.graph" value="query.graph">
ts
const { data: [cart] } = await query.graph({
  entity: "cart",
  fields: ["*"],
  filters: {
    id: "cart_123",
  },
})

// cart doesn't include cart totals
</CodeTab> </CodeTabs>

This will return the cart data stored in the database, but not the calculated totals.

You also can't pass * along with total in the Query's fields option. Passing * will override the total field, and you will not retrieve cart totals. For example, the following query will not return cart totals:

<CodeTabs group="query-type"> <CodeTab label="useQueryGraphStep" value="useQueryGraphStep">
ts
const { data: carts } = useQueryGraphStep({
  entity: "cart",
  fields: ["*", "total"],
  filters: {
    id: "cart_123",
  },
})

// carts don't include cart totals
</CodeTab> <CodeTab label="query.graph" value="query.graph">
ts
const { data: [cart] } = await query.graph({
  entity: "cart",
  fields: ["*", "total"],
  filters: {
    id: "cart_123",
  },
})

// cart doesn't include cart totals
</CodeTab> </CodeTabs>

Instead, when you need to retrieve cart totals, explicitly pass the total field in the Query's fields option, as shown in the previous section. You can also include other fields and relations you need, such as email and items.*.

Applying Filters on Cart Totals

You can't apply filters directly on the cart totals, as they are not stored in the Cart data model. You can still filter the cart based on its properties, such as id, email, or currency_code, but not on the calculated totals.