- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
Calculate Product Variant Price with Taxes
In this document, you'll learn how to calculate a product variant's price with taxes.
Step 0: Resolve Resources#
You'll need the following resources for the taxes calculation:
- Query to retrieve the product's variants' prices for a context. Learn more about that in this guide.
- The Tax Module's main service to get the tax lines for each product.
Step 1: Retrieve Prices for a Context#
After resolving the resources, use Query to retrieve the products with the variants' prices for a context:
1import { QueryContext } from "@medusajs/framework/utils"2 3// ...4 5const { data: products } = await query.graph({6 entity: "product",7 fields: [8 "*",9 "variants.*",10 "variants.calculated_price.*",11 ],12 filters: {13 id: "prod_123",14 },15 context: {16 variants: {17 calculated_price: QueryContext({18 region_id: "region_123",19 currency_code: "usd",20 }),21 },22 },23})
Step 2: Get Tax Lines for Products#
To retrieve the tax line of each product, first, add the following utility method:
1// other imports...2import {3 HttpTypes,4 TaxableItemDTO,5} from "@medusajs/framework/types"6 7// ...8const asTaxItem = (product: HttpTypes.StoreProduct): TaxableItemDTO[] => {9 return product.variants10 ?.map((variant) => {11 if (!variant.calculated_price) {12 return13 }14 15 return {16 id: variant.id,17 product_id: product.id,18 product_name: product.title,19 product_categories: product.categories?.map((c) => c.name),20 product_category_id: product.categories?.[0]?.id,21 product_sku: variant.sku,22 product_type: product.type,23 product_type_id: product.type_id,24 quantity: 1,25 unit_price: variant.calculated_price.calculated_amount,26 currency_code: variant.calculated_price.currency_code,27 }28 })29 .filter((v) => !!v) as unknown as TaxableItemDTO[]30}
This formats the products as items to calculate tax lines for.
Then, use it when retrieving the tax lines of the products retrieved earlier:
1// other imports...2import {3 ItemTaxLineDTO,4} from "@medusajs/framework/types"5 6// ...7const taxLines = (await taxModuleService.getTaxLines(8 products.map(asTaxItem).flat(),9 {10 // example of context properties. You can pass other ones.11 address: {12 country_code,13 },14 }15)) as unknown as ItemTaxLineDTO[]
You use the Tax Module's main service's getTaxLines method to retrieve the tax line.
For the first parameter, you use the asTaxItem
function to format the products as expected by the getTaxLines
method.
For the second parameter, you pass the current context. You can pass other details such as the customer's ID.
Step 3: Calculate Price with Tax for Variant#
To calculate the price with and without taxes for a variant, first, group the tax lines retrieved in the previous step by variant IDs:
Notice that the variant's ID is stored in the line_item_id
property of a tax line since tax lines are used for line items in a cart.
Then, loop over the products and their variants to retrieve the prices with and without taxes:
1// other imports...2import {3 calculateAmountsWithTax,4} from "@medusajs/framework/utils"5 6// ...7products.forEach((product) => {8 product.variants?.forEach((variant) => {9 if (!variant.calculated_price) {10 return11 }12 13 const taxLinesForVariant = taxLinesMap.get(variant.id) || []14 const { priceWithTax, priceWithoutTax } = calculateAmountsWithTax({15 taxLines: taxLinesForVariant,16 amount: variant.calculated_price!.calculated_amount!,17 includesTax:18 variant.calculated_price!.is_calculated_price_tax_inclusive!,19 })20 21 // do something with prices...22 })23})
For each product variant, you:
- Retrieve its tax lines from the
taxLinesMap
. - Calculate its prices with and without taxes using the
calculateAmountsWithTax
function imported from@medusajs/framework/utils
. - The
calculateAmountsWithTax
function returns an object having two properties:priceWithTax
: The variant's price with the taxes applied.priceWithoutTax
: The variant's price without taxes applied.