|
| 1 | +--- |
| 2 | +tags: |
| 3 | + - cart |
| 4 | + - name: how to |
| 5 | + label: Retrieve Cart Totals |
| 6 | + - server |
| 7 | +--- |
| 8 | + |
| 9 | +import { CodeTabs, CodeTab } from "docs-ui" |
| 10 | + |
| 11 | +export const metadata = { |
| 12 | + title: `Retrieve Cart Totals using Query`, |
| 13 | +} |
| 14 | + |
| 15 | +# {metadata.title} |
| 16 | + |
| 17 | +In this guide, you'll learn how to retrieve cart totals in your Medusa application using [Query](!docs!/learn/fundamentals/module-links/query). |
| 18 | + |
| 19 | +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. |
| 20 | + |
| 21 | +<Note title="Looking for a storefront guide?"> |
| 22 | + |
| 23 | +Refer to the [Retrieve Cart Totals in Storefront](../../../storefront-development/cart/totals/page.mdx) guide for a storefront-specific approach. |
| 24 | + |
| 25 | +</Note> |
| 26 | + |
| 27 | +## How to Retrieve Cart Totals with Query |
| 28 | + |
| 29 | +To retrieve cart totals, pass the `total` field within the `fields` option of Query. For example: |
| 30 | + |
| 31 | +<Note title="Tip"> |
| 32 | + |
| 33 | +Use `useQueryGraphStep` in workflows, and `query.graph` in custom API routes, scheduled jobs, and subscribers. |
| 34 | + |
| 35 | +</Note> |
| 36 | + |
| 37 | +<CodeTabs group="query-type"> |
| 38 | + <CodeTab label="useQueryGraphStep" value="useQueryGraphStep"> |
| 39 | + |
| 40 | +```ts highlights={[["12"]]} |
| 41 | +import { createWorkflow } from "@medusajs/framework/workflows-sdk" |
| 42 | +import { useQueryGraphStep } from "@medusajs/medusa/core-flows" |
| 43 | + |
| 44 | +export const myWorkflow = createWorkflow( |
| 45 | + "my-workflow", |
| 46 | + () => { |
| 47 | + const { data: carts } = useQueryGraphStep({ |
| 48 | + entity: "cart", |
| 49 | + fields: [ |
| 50 | + "id", |
| 51 | + "currency_code", |
| 52 | + "total", |
| 53 | + "items.*", |
| 54 | + "shipping_methods.*", |
| 55 | + ], |
| 56 | + filters: { |
| 57 | + id: "cart_123", // Specify the cart ID |
| 58 | + }, |
| 59 | + }) |
| 60 | + } |
| 61 | +) |
| 62 | +``` |
| 63 | + </CodeTab> |
| 64 | + <CodeTab label="query.graph" value="query.graph"> |
| 65 | + |
| 66 | +```ts highlights={[["8"]]} |
| 67 | +const query = container.resolve("query") // or req.scope.resolve in API routes |
| 68 | + |
| 69 | +const { data: [cart] } = await query.graph({ |
| 70 | + entity: "cart", |
| 71 | + fields: [ |
| 72 | + "id", |
| 73 | + "currency_code", |
| 74 | + "total", |
| 75 | + "items.*", |
| 76 | + "shipping_methods.*", |
| 77 | + ], |
| 78 | + filters: { |
| 79 | + id: "cart_123", // Specify the cart ID |
| 80 | + } |
| 81 | +}) |
| 82 | +``` |
| 83 | + </CodeTab> |
| 84 | +</CodeTabs> |
| 85 | + |
| 86 | +By specifying the `total` field, you retrieve totals related to the cart, line items, and shipping methods. The returned `cart` object will look like this: |
| 87 | + |
| 88 | +```json |
| 89 | +{ |
| 90 | + "id": "cart_123", |
| 91 | + "currency_code": "usd", |
| 92 | + "total": 10, |
| 93 | + "items": [ |
| 94 | + { |
| 95 | + "id": "cali_123", |
| 96 | + // ... |
| 97 | + "unit_price": 10, |
| 98 | + "subtotal": 10, |
| 99 | + "total": 0, |
| 100 | + "original_total": 10, |
| 101 | + "discount_total": 10, |
| 102 | + "discount_subtotal": 10, |
| 103 | + "discount_tax_total": 0, |
| 104 | + "tax_total": 0, |
| 105 | + "original_tax_total": 0, |
| 106 | + } |
| 107 | + ], |
| 108 | + "shipping_methods": [ |
| 109 | + { |
| 110 | + "id": "casm_01K10AYZDKZGQXE8WXW3QP9T22", |
| 111 | + // ... |
| 112 | + "amount": 10, |
| 113 | + "subtotal": 10, |
| 114 | + "total": 10, |
| 115 | + "original_total": 10, |
| 116 | + "discount_total": 0, |
| 117 | + "discount_subtotal": 0, |
| 118 | + "discount_tax_total": 0, |
| 119 | + "tax_total": 0, |
| 120 | + "original_tax_total": 0, |
| 121 | + } |
| 122 | + ] |
| 123 | +} |
| 124 | +``` |
| 125 | + |
| 126 | +### Cart Grand Total |
| 127 | + |
| 128 | +The cart's grand total is the `total` field in the `cart` object. It represents the total amount of the cart, including all line items, shipping methods, taxes, and discounts. |
| 129 | + |
| 130 | +### Cart Line Item Totals |
| 131 | + |
| 132 | +The `items` array in the `cart` object contains total fields for each line item: |
| 133 | + |
| 134 | +- `unit_price`: The price of a single unit of the line item. This field is not calculated and is stored in the database. |
| 135 | +- `subtotal`: The total price of the line item before any discounts or taxes. |
| 136 | +- `total`: The total price of the line item after applying discounts and taxes. |
| 137 | +- `original_total`: The total price of the line item before any discounts. |
| 138 | +- `discount_total`: The total amount of discounts applied to the line item. |
| 139 | +- `discount_subtotal`: The total amount of discounts applied to the line item's subtotal. |
| 140 | +- `discount_tax_total`: The total amount of discounts applied to the line item's tax. |
| 141 | +- `tax_total`: The total tax amount applied to the line item. |
| 142 | +- `original_tax_total`: The total tax amount applied to the line item before any discounts. |
| 143 | + |
| 144 | +### Cart Shipping Method Totals |
| 145 | + |
| 146 | +The `shipping_methods` array in the `cart` object contains total fields for each shipping method: |
| 147 | + |
| 148 | +- `amount`: The amount charged for the shipping method. This field is not calculated and is stored in the database. |
| 149 | +- `subtotal`: The total price of the shipping method before any discounts or taxes. |
| 150 | +- `total`: The total price of the shipping method after applying discounts and taxes. |
| 151 | +- `original_total`: The total price of the shipping method before any discounts. |
| 152 | +- `discount_total`: The total amount of discounts applied to the shipping method. |
| 153 | +- `discount_subtotal`: The total amount of discounts applied to the shipping method's subtotal. |
| 154 | +- `discount_tax_total`: The total amount of discounts applied to the shipping method's tax. |
| 155 | +- `tax_total`: The total tax amount applied to the shipping method. |
| 156 | +- `original_tax_total`: The total tax amount applied to the shipping method before any discounts. |
| 157 | + |
| 158 | +--- |
| 159 | + |
| 160 | +## Caveats of Retrieving Cart Totals |
| 161 | + |
| 162 | +### Using Astrisk (*) in Cart's Query |
| 163 | + |
| 164 | +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. |
| 165 | + |
| 166 | +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: |
| 167 | + |
| 168 | +<CodeTabs group="query-type"> |
| 169 | + <CodeTab label="useQueryGraphStep" value="useQueryGraphStep"> |
| 170 | + |
| 171 | +```ts |
| 172 | +const { data: carts } = useQueryGraphStep({ |
| 173 | + entity: "cart", |
| 174 | + fields: ["*"], |
| 175 | + filters: { |
| 176 | + id: "cart_123", |
| 177 | + }, |
| 178 | +}) |
| 179 | + |
| 180 | +// carts don't include cart totals |
| 181 | +``` |
| 182 | + </CodeTab> |
| 183 | + <CodeTab label="query.graph" value="query.graph"> |
| 184 | + |
| 185 | +```ts |
| 186 | +const { data: [cart] } = await query.graph({ |
| 187 | + entity: "cart", |
| 188 | + fields: ["*"], |
| 189 | + filters: { |
| 190 | + id: "cart_123", |
| 191 | + } |
| 192 | +}) |
| 193 | + |
| 194 | +// cart doesn't include cart totals |
| 195 | +``` |
| 196 | + </CodeTab> |
| 197 | +</CodeTabs> |
| 198 | + |
| 199 | +This will return the cart data stored in the database, but not the calculated totals. |
| 200 | + |
| 201 | +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: |
| 202 | + |
| 203 | +<CodeTabs group="query-type"> |
| 204 | + <CodeTab label="useQueryGraphStep" value="useQueryGraphStep"> |
| 205 | + |
| 206 | +```ts |
| 207 | +const { data: carts } = useQueryGraphStep({ |
| 208 | + entity: "cart", |
| 209 | + fields: ["*", "total"], |
| 210 | + filters: { |
| 211 | + id: "cart_123", |
| 212 | + }, |
| 213 | +}) |
| 214 | + |
| 215 | +// carts don't include cart totals |
| 216 | +``` |
| 217 | + </CodeTab> |
| 218 | + <CodeTab label="query.graph" value="query.graph"> |
| 219 | + |
| 220 | +```ts |
| 221 | +const { data: [cart] } = await query.graph({ |
| 222 | + entity: "cart", |
| 223 | + fields: ["*", "total"], |
| 224 | + filters: { |
| 225 | + id: "cart_123", |
| 226 | + } |
| 227 | +}) |
| 228 | + |
| 229 | +// cart doesn't include cart totals |
| 230 | +``` |
| 231 | + </CodeTab> |
| 232 | +</CodeTabs> |
| 233 | + |
| 234 | +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](#how-to-retrieve-cart-totals-with-query). You can also include other fields and relations you need, such as `email` and `items.*`. |
| 235 | + |
| 236 | +### Applying Filters on Cart Totals |
| 237 | + |
| 238 | +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. |
0 commit comments