docs: document tax-inclusive promotions concept (#12849)
This commit is contained in:
@@ -76,3 +76,11 @@ A region’s price preference’s `is_tax_inclusive`'s value takes higher preced
|
||||
- both the `region_id` and `currency_code` are provided in the calculation context;
|
||||
- the selected price belongs to the region;
|
||||
- and the region has a price preference
|
||||
|
||||
---
|
||||
|
||||
## Tax-Inclusive Pricing with Promotions
|
||||
|
||||
When you enable tax-inclusive prices for regions or currencies, this can impact how promotions are applied to the cart. So, it's recommended to enable tax-inclusiveness for promotions as well.
|
||||
|
||||
Learn more in the [Tax-Inclusive Promotions](../../promotion/promotion-taxes/page.mdx) guide.
|
||||
|
||||
@@ -29,6 +29,7 @@ export interface AddItemAdjustmentAction {
|
||||
amount: number
|
||||
code: string
|
||||
description?: string
|
||||
is_tax_inclusive?: boolean
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
---
|
||||
tags:
|
||||
- tax
|
||||
product:
|
||||
- cart
|
||||
- tax
|
||||
---
|
||||
|
||||
export const metadata = {
|
||||
title: `Tax-Inclusive Promotions`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this guide, you’ll learn how taxes are applied to promotions in a cart.
|
||||
|
||||
<Note>
|
||||
|
||||
This feature is available from [Medusa v2.8.5](https://github.com/medusajs/medusa/releases/tag/v2.8.5).
|
||||
|
||||
</Note>
|
||||
|
||||
## What are Tax-Inclusive Promotions?
|
||||
|
||||
By default, promotions are tax-exclusive, meaning that the discount amount is applied as-is to the cart before taxes are calculated and applied to the cart total.
|
||||
|
||||
A tax-inclusive promotion is a promotion for which taxes are calculated from the discount amount entered by the merchant.
|
||||
|
||||
When a promotion is tax-inclusive, the discount amount is reduced by the calculated tax amount based on the [tax region's rate](../../tax/tax-region/page.mdx). The reduced discount amount is then applied to the cart total.
|
||||
|
||||
<Note>
|
||||
|
||||
Tax-inclusiveness doesn't apply to Buy X Get Y promotions.
|
||||
|
||||
</Note>
|
||||
|
||||
### When to Use Tax-Inclusive Promotions
|
||||
|
||||
Tax-inclusive promotions are most useful when using [tax-inclusive prices](../../pricing/tax-inclusive-pricing/page.mdx) for items in the cart.
|
||||
|
||||
In this scenario, Medusa applies taxes consistently across the cart, ensuring that the total price reflects the taxes and promotions correctly.
|
||||
|
||||
You can see this in action in the [examples below](#tax-inclusiveness-examples).
|
||||
|
||||
---
|
||||
|
||||
## What Makes a Promotion Tax-Inclusive?
|
||||
|
||||
The [Promotion data model](/references/promotion/models/Promotion) has an `is_tax_inclusive` property that determines whether the promotion is tax-inclusive.
|
||||
|
||||
If `is_tax_inclusive` is disabled (which is the default), the promotion's discount amount will be applied as-is to the cart, before taxes are calculated. See an example in the [Tax-Exclusive Promotion Example](#tax-exclusive-promotion-example) section.
|
||||
|
||||
If `is_tax_inclusive` is enabled, the promotion's discount amount will first be reduced by the calculated tax amount (based on the [tax region's rate](../../tax/tax-region/page.mdx)). The reduced discount amount is then applied to the cart total. See an example in the [Tax-Inclusive Promotion Example](#tax-inclusive-promotion-example) section.
|
||||
|
||||
---
|
||||
|
||||
## How to Set a Promotion as Tax-Inclusive
|
||||
|
||||
<Note title="Looking for no-code approach?">
|
||||
|
||||
You can enable tax-inclusiveness for a promotion when [creating it in the Medusa Admin](!user-guide!/promotions/create).
|
||||
|
||||
</Note>
|
||||
|
||||
You can set the `is_tax_inclusive` property when creating a promotion by using either the [Promotion workflows](../workflows/page.mdx) or the [Promotion Module's service](/references/promotion).
|
||||
|
||||
<Note>
|
||||
|
||||
For most use cases, it's recommended to use [workflows](!docs!/learn/fundamentals/workflows) instead of directly using the module's service, as they implement the necessary rollback mechanisms in case of errors.
|
||||
|
||||
</Note>
|
||||
|
||||
For example, if you're creating a promotion with the [createPromotionsWorkflow](/references/medusa-workflows/createPromotionsWorkflow) in an API route:
|
||||
|
||||
```ts highlights={[["17"]]}
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "@medusajs/framework/http"
|
||||
import { createPromotionsWorkflow } from "@medusajs/medusa/core-flows"
|
||||
|
||||
export async function POST(
|
||||
req: MedusaRequest,
|
||||
res: MedusaResponse
|
||||
) {
|
||||
const { result } = await createPromotionsWorkflow(req.scope)
|
||||
.run({
|
||||
input: {
|
||||
promotionsData: [{
|
||||
code: "10OFF",
|
||||
// ...
|
||||
is_tax_inclusive: true,
|
||||
}],
|
||||
}
|
||||
})
|
||||
|
||||
res.send(result)
|
||||
}
|
||||
```
|
||||
|
||||
In the above example, you set the `is_tax_inclusive` property to `true` when creating the promotion, making it tax-inclusive.
|
||||
|
||||
### Updating a Promotion's Tax-Inclusiveness
|
||||
|
||||
A promotion's tax-inclusiveness cannot be updated after it has been created. If you need to change a promotion's tax-inclusiveness, you must delete the existing promotion and create a new one with the desired `is_tax_inclusive` value.
|
||||
|
||||
---
|
||||
|
||||
## Tax-Inclusiveness Examples
|
||||
|
||||
The following sections provide examples of how tax-inclusive promotions work in different scenarios, including both tax-exclusive and tax-inclusive promotions.
|
||||
|
||||
These examples will help you understand how tax-inclusive promotions affect the cart total, allowing you to decide when to use them effectively.
|
||||
|
||||
### Tax-Exclusive Promotion Example
|
||||
|
||||
Consider the following scenario:
|
||||
|
||||
- A tax-exclusive promotion gives a `$10` discount on the cart's total.
|
||||
- The cart's tax region has a `25%` tax rate.
|
||||
- The cart total before applying the promotion is `$100`.
|
||||
- [The prices in the cart's tax region are tax-exclusive](../../pricing/tax-inclusive-pricing/page.mdx).
|
||||
|
||||
The result:
|
||||
|
||||
1. Apply `$10` discount to cart total: `$100` - `$10` = `$90`
|
||||
2. Calculate tax on discounted total: `$90` x `25%` = `$22.50`
|
||||
3. Final total: `$90` + `$22.50` = `$112.50`
|
||||
|
||||
### Tax-Inclusive Promotion Example
|
||||
|
||||
Consider the following scenario:
|
||||
|
||||
- A tax-inclusive promotion gives a `$10` discount on the cart's total.
|
||||
- The cart's tax region has a `25%` tax rate.
|
||||
- The cart total before applying the promotion is `$100`.
|
||||
- [The prices in the cart's tax region are tax-exclusive](../../pricing/tax-inclusive-pricing/page.mdx).
|
||||
|
||||
The result:
|
||||
|
||||
1. Calculate actual discount (removing tax): `$10` ÷ `1.25` = `$8`
|
||||
2. Apply discount to cart total: `$100` - `$8` = `$92`
|
||||
3. Calculate tax on discounted total: `$92` x `25%` = `$23`
|
||||
4. Final total: `$92` + `$23` = `$115`
|
||||
|
||||
### Tax-Inclusive Promotions with Tax-Inclusive Prices
|
||||
|
||||
Consider the following scenario:
|
||||
|
||||
- A tax-inclusive promotion gives a `$10` discount on the cart's total.
|
||||
- The cart's tax region has a `25%` tax rate.
|
||||
- The cart total before applying the promotion is `$100`.
|
||||
- [The prices in the cart's tax region are tax-inclusive](../../pricing/tax-inclusive-pricing/page.mdx).
|
||||
|
||||
The result:
|
||||
|
||||
1. Calculate actual discount (removing tax): `$10` ÷ `1.25` = `$8`
|
||||
2. Calculate cart total without tax: `$100` ÷ `1.25` = `$80`
|
||||
3. Apply discount to cart total without tax: `$80` - `$8` = `$72`
|
||||
4. Add tax back to total: `$72` x `1.25` = `$90`
|
||||
|
||||
The final total is `$90`, which correctly applies both the tax-inclusive promotion and tax-inclusive pricing.
|
||||
Reference in New Issue
Block a user