docs: create docs workspace (#5174)
* docs: migrate ui docs to docs universe * created yarn workspace * added eslint and tsconfig configurations * fix eslint configurations * fixed eslint configurations * shared tailwind configurations * added shared ui package * added more shared components * migrating more components * made details components shared * move InlineCode component * moved InputText * moved Loading component * Moved Modal component * moved Select components * Moved Tooltip component * moved Search components * moved ColorMode provider * Moved Notification components and providers * used icons package * use UI colors in api-reference * moved Navbar component * used Navbar and Search in UI docs * added Feedback to UI docs * general enhancements * fix color mode * added copy colors file from ui-preset * added features and enhancements to UI docs * move Sidebar component and provider * general fixes and preparations for deployment * update docusaurus version * adjusted versions * fix output directory * remove rootDirectory property * fix yarn.lock * moved code component * added vale for all docs MD and MDX * fix tests * fix vale error * fix deployment errors * change ignore commands * add output directory * fix docs test * general fixes * content fixes * fix announcement script * added changeset * fix vale checks * added nofilter option * fix vale error
This commit is contained in:
1 parent
19c5d5ba36
commit
fa7c94b4cc
3209 files changed
+32188
-31018
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,306 @@
|
||||
---
|
||||
description: 'Learn how to import products into Medusa using the Admin REST APIs. The steps include uploading a CSV file, creating a batch job for the import, and confirming the batch job.'
|
||||
addHowToData: true
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# How to Manage Tax Settings
|
||||
|
||||
In this document, you’ll learn how to manage tax settings using admin APIs.
|
||||
|
||||
## Overview
|
||||
|
||||
Tax settings are defined per region. You can change the tax settings of a region using the [Update Region endpoint](https://docs.medusajs.com/api/admin#regions_postregionsregion).
|
||||
|
||||
### Scenario
|
||||
|
||||
You want to add or use the following admin functionalities:
|
||||
|
||||
- List available tax providers in a store.
|
||||
- Change the tax provider of a region.
|
||||
- Change tax settings of a region.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Medusa Components
|
||||
|
||||
It is assumed that you already have a Medusa backend installed and set up. If not, you can follow the [quickstart guide](../../../development/backend/install.mdx) to get started.
|
||||
|
||||
### JS Client
|
||||
|
||||
This guide includes code snippets to send requests to your Medusa backend using Medusa’s JS Client, among other methods.
|
||||
|
||||
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client](../../../js-client/overview.md) installed and have [created an instance of the client](../../../js-client/overview.md#configuration).
|
||||
|
||||
### Medusa React
|
||||
|
||||
This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
|
||||
|
||||
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.mdx) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.mdx#usage).
|
||||
|
||||
### Authenticated Admin User
|
||||
|
||||
You must be an authenticated admin user before following along with the steps in the tutorial.
|
||||
|
||||
You can learn more about [authenticating as an admin user in the API reference](https://docs.medusajs.com/api/admin#authentication).
|
||||
|
||||
---
|
||||
|
||||
## List Tax Providers
|
||||
|
||||
You can list all tax providers of a store using the [List Tax Providers endpoint](https://docs.medusajs.com/api/admin#store_getstoretaxproviders):
|
||||
|
||||
<Tabs groupId="request-type" isCodeTabs={true}>
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.store.listTaxProviders()
|
||||
.then(({ tax_providers }) => {
|
||||
console.log(tax_providers.length)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminStoreTaxProviders } from "medusa-react"
|
||||
|
||||
const TaxProviders = () => {
|
||||
const {
|
||||
tax_providers,
|
||||
isLoading,
|
||||
} = useAdminStoreTaxProviders()
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isLoading && <span>Loading...</span>}
|
||||
{tax_providers && !tax_providers.length && (
|
||||
<span>No Tax Providers</span>
|
||||
)}
|
||||
{tax_providers && tax_providers.length > 0 && (
|
||||
<ul>
|
||||
{tax_providers.map((tax_provider) => (
|
||||
<li key={tax_provider.id}>{tax_provider.id}</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TaxProviders
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/store/tax-providers`, {
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ tax_providers }) => {
|
||||
console.log(tax_providers.length)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X GET '<BACKEND_URL>/admin/store/tax-providers' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint does not accept any parameters.
|
||||
|
||||
The request returns an array of tax provider objects.
|
||||
|
||||
---
|
||||
|
||||
## Change Tax Provider of a Region
|
||||
|
||||
You can change the tax provider of a region using the [Update Region endpoint](https://docs.medusajs.com/api/admin#regions_postregionsregion):
|
||||
|
||||
<Tabs groupId="request-type" isCodeTabs={true}>
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.regions.update(regionId, {
|
||||
tax_provider_id,
|
||||
})
|
||||
.then(({ region }) => {
|
||||
console.log(region.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminUpdateRegion } from "medusa-react"
|
||||
|
||||
const UpdateRegion = () => {
|
||||
const updateRegion = useAdminUpdateRegion(regionId)
|
||||
// ...
|
||||
|
||||
const handleUpdate = () => {
|
||||
updateRegion.mutate({
|
||||
tax_provider_id,
|
||||
})
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default UpdateRegion
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/regions/${regionId}`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
tax_provider_id,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ region }) => {
|
||||
console.log(region.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/regions/<REGION_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"tax_provider_id": "<TAX_PROVIDER_ID>"
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This endpoint requires the ID of the region to be passed as a path parameter.
|
||||
|
||||
In the body of the request, you can pass any of the region’s attributes to update. To update the tax provider of a region, you can pass the `tax_provider_id` request body parameter.
|
||||
|
||||
The request returns the updated region as an object.
|
||||
|
||||
---
|
||||
|
||||
## Change Tax Settings of a Region
|
||||
|
||||
In addition to changing the tax provider, you can use the same [Update Region endpoint](https://docs.medusajs.com/api/admin#regions_postregionsregion) to update the region’s other tax settings:
|
||||
|
||||
<Tabs groupId="request-type" isCodeTabs={true}>
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```ts
|
||||
medusa.admin.regions.update(regionId, {
|
||||
tax_provider_id,
|
||||
automatic_taxes,
|
||||
gift_cards_taxable,
|
||||
tax_code,
|
||||
tax_rate,
|
||||
})
|
||||
.then(({ region }) => {
|
||||
console.log(region.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="medusa-react" label="Medusa React">
|
||||
|
||||
```tsx
|
||||
import { useAdminUpdateRegion } from "medusa-react"
|
||||
|
||||
const UpdateRegion = () => {
|
||||
const updateRegion = useAdminUpdateRegion(regionId)
|
||||
// ...
|
||||
|
||||
const handleUpdate = () => {
|
||||
updateRegion.mutate({
|
||||
tax_provider_id,
|
||||
automatic_taxes,
|
||||
gift_cards_taxable,
|
||||
tax_code,
|
||||
tax_rate,
|
||||
})
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default UpdateRegion
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```ts
|
||||
fetch(`<BACKEND_URL>/admin/regions/${regionId}`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
tax_provider_id,
|
||||
automatic_taxes,
|
||||
gift_cards_taxable,
|
||||
tax_code,
|
||||
tax_rate,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ region }) => {
|
||||
console.log(region.id)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl -L -X POST '<BACKEND_URL>/admin/regions/<REGION_ID>' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"tax_provider_id": "<TAX_PROVIDER_ID>",
|
||||
"automatic_taxes": true,
|
||||
"gift_cards_taxable": true,
|
||||
"tax_code": "<TAX_CODE>",
|
||||
"tax_rate": 10
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You can pass the following parameters in the body of the request that are related to tax settings:
|
||||
|
||||
- `automatic_taxes`: a boolean value indicating whether taxes should be calculated automatically when calculating totals. The default value is `true`.
|
||||
- `gift_cards_taxable`: a boolean value indicating whether gift cards are taxable. The default value is `true`.
|
||||
- `tax_code`: a string indicating the tax code of the region.
|
||||
- `tax_rate`: a number indicating the default tax rate of the region.
|
||||
|
||||
The request returns the updated region as an object.
|
||||
@@ -0,0 +1,212 @@
|
||||
---
|
||||
description: 'Learn how to create a tax provider. You can create a tax provider in a Medusa backend or a plugin.'
|
||||
addHowToData: true
|
||||
---
|
||||
|
||||
# How to Create a Tax Provider
|
||||
|
||||
In this document, you’ll learn how to create a tax provider.
|
||||
|
||||
## Overview
|
||||
|
||||
A tax provider is used to retrieve the tax lines in a cart. The Medusa backend provides a default `system` provider. You can create your own tax provider, either in a plugin or directly in your Medusa backend, then use it in any region.
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create Tax Provider Class
|
||||
|
||||
A tax provider class should be defined in a TypeScript or JavaScript file under `src/services` and the class should extend `AbstractTaxService` imported from `@medusajs/medusa`.
|
||||
|
||||
For example, you can create the file `src/services/my-tax.ts` with the following content:
|
||||
|
||||
```ts title=src/services/my-tax.ts
|
||||
import {
|
||||
AbstractTaxService,
|
||||
ItemTaxCalculationLine,
|
||||
ShippingTaxCalculationLine,
|
||||
TaxCalculationContext,
|
||||
} from "@medusajs/medusa"
|
||||
import {
|
||||
ProviderTaxLine,
|
||||
} from "@medusajs/medusa/dist/types/tax-service"
|
||||
|
||||
class MyTaxService extends AbstractTaxService {
|
||||
async getTaxLines(
|
||||
itemLines: ItemTaxCalculationLine[],
|
||||
shippingLines: ShippingTaxCalculationLine[],
|
||||
context: TaxCalculationContext):
|
||||
Promise<ProviderTaxLine[]> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
}
|
||||
|
||||
export default MyTaxService
|
||||
```
|
||||
|
||||
Since the class extends `AbstractTaxService`, it must implement its abstract method `getTaxLines`, which is explained later in this guide.
|
||||
|
||||
### Using a Constructor
|
||||
|
||||
You can use a constructor to access services and resources registered in the dependency container using dependency injection. For example:
|
||||
|
||||
```ts title=src/services/my-tax.ts
|
||||
// ...
|
||||
import { LineItemService } from "@medusajs/medusa"
|
||||
|
||||
type InjectedDependencies = {
|
||||
lineItemService: LineItemService
|
||||
}
|
||||
|
||||
class MyTaxService extends AbstractTaxService {
|
||||
protected readonly lineItemService_: LineItemService
|
||||
|
||||
constructor({ lineItemService }: InjectedDependencies) {
|
||||
super()
|
||||
this.lineItemService_ = lineItemService
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
export default MyTaxService
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Define Identifier
|
||||
|
||||
Every tax provider must have a unique identifier. The identifier is defined as a static property in the class, and its value is used when registering the tax provider in the database and in the dependency container.
|
||||
|
||||
Add the static property `identifier` in your tax provider class:
|
||||
|
||||
```ts title=src/services/my-tax.ts
|
||||
class MyTaxService extends AbstractTaxService {
|
||||
static identifier = "my-tax"
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Make sure to change `my-tax` to the name of your tax provider.
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Implement getTaxLines Method
|
||||
|
||||
The `getTaxLines` method is the only required method in a tax provider. It’s used when retrieving the tax lines for line items and shipping methods, typically during checkout or when calculating totals, for example, for orders, swaps, or returns.
|
||||
|
||||
The method accepts three parameters. The first parameter is an array of tax calculation objects for line items. Each object having the following properties:
|
||||
|
||||
- `item`: a line item object.
|
||||
- `rates`: an array of objects, each object having the following properties:
|
||||
- `rate`: an optional number indicating the tax rate.
|
||||
- `name`: a string indicating the name of the tax rate.
|
||||
- `code`: an optional string indicating the tax code.
|
||||
|
||||
The second parameter is an array of tax calculation objects for shipping methods. Each object having the following properties:
|
||||
|
||||
- `shipping_method`: a shipping method object.
|
||||
- `rates`: an array of objects, each object having the following properties:
|
||||
- `rate`: an optional number indicating the tax rate.
|
||||
- `name`: a string indicating the name of the tax rate.
|
||||
- `code`: an optional string indicating the tax code.
|
||||
|
||||
The third parameter is a context object that can be helpful for the tax calculation. The object can have the following properties:
|
||||
|
||||
- `shipping_address`: an optional address object used for shipping.
|
||||
- `customer`: an optional customer object.
|
||||
- `region`: an optional region object.
|
||||
- `is_return`: a boolean value that determines whether the taxes are being calculated for a return flow.
|
||||
- `shipping_methods`: an array of shipping methods being used in the current context.
|
||||
- `allocation_map`: an object that indicates the gift cards and discounts applied on line items. Each object key or property is an ID of a line item, and the value is an object having the following properties:
|
||||
- `gift_card`: an optional object indicating the gift card applied on the line item.
|
||||
- `discount`: an optional object indicating the discount applied on the line item.
|
||||
|
||||
This method is expected to return an array of line item tax line or shipping method tax line objects.
|
||||
|
||||
The line item tax line object has the following properties:
|
||||
|
||||
- `rate`: a number indicating the tax rate.
|
||||
- `name`: a string indicating the name of the tax rate.
|
||||
- `code`: an optional string indicating the tax code.
|
||||
- `item_id`: the ID of the line item.
|
||||
- `metadata`: an optional object that can hold any necessary additional data to be added to the line item tax lines.
|
||||
|
||||
The shipping method tax line object has the following properties:
|
||||
|
||||
- `rate`: a number indicating the tax rate.
|
||||
- `name`: a string indicating the name of the tax rate.
|
||||
- `code`: an optional string indicating the tax code.
|
||||
- `shipping_method_id`: the ID of the shipping method.
|
||||
- `metadata`: an optional object that can hold any necessary additional data to be added to the shipping method tax lines.
|
||||
|
||||
The returned array would be a combination of both the line item tax lines and shipping method tax lines.
|
||||
|
||||
:::note
|
||||
|
||||
The Medusa backend determines whether an object in the returned array is a shipping method tax line item, depending on the availability of the `shipping_method_id` attribute. For line items, it depends on the availability of the `item_id` attribute.
|
||||
|
||||
:::
|
||||
|
||||
For example, the `system` tax provider returns the tax calculation line items in the first parameter and the tax calculation shipping methods in the second parameter as is:
|
||||
|
||||
```ts title=src/services/my-tax.ts
|
||||
// ...
|
||||
|
||||
class SystemTaxService extends AbstractTaxService {
|
||||
// ...
|
||||
|
||||
async getTaxLines(
|
||||
itemLines: ItemTaxCalculationLine[],
|
||||
shippingLines: ShippingTaxCalculationLine[],
|
||||
context: TaxCalculationContext
|
||||
): Promise<ProviderTaxLine[]> {
|
||||
let taxLines: ProviderTaxLine[] = itemLines.flatMap((l) => {
|
||||
return l.rates.map((r) => ({
|
||||
rate: r.rate || 0,
|
||||
name: r.name,
|
||||
code: r.code,
|
||||
item_id: l.item.id,
|
||||
}))
|
||||
})
|
||||
|
||||
taxLines = taxLines.concat(
|
||||
shippingLines.flatMap((l) => {
|
||||
return l.rates.map((r) => ({
|
||||
rate: r.rate || 0,
|
||||
name: r.name,
|
||||
code: r.code,
|
||||
shipping_method_id: l.shipping_method.id,
|
||||
}))
|
||||
})
|
||||
)
|
||||
|
||||
return taxLines
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Run the Build Command
|
||||
|
||||
In the directory of the Medusa backend, run the `build` command to transpile the files in the `src` directory into the `dist` directory:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Test it Out
|
||||
|
||||
Run your backend to test it out:
|
||||
|
||||
```bash npm2yarn
|
||||
npx medusa develop
|
||||
```
|
||||
|
||||
Before you can test out your tax provider, you must enable it in a region. You can do that either using the [Medusa Admin dashboard](../../../user-guide/taxes/manage.md#change-tax-provider) or using the [Update Region admin endpoint](../admin/manage-tax-settings.mdx#change-tax-provider-of-a-region).
|
||||
|
||||
Then, you can test out the tax provider by simulating a checkout process in that region. You should see the line item tax lines in the cart’s `items`, as each item object has a `tax_lines` array which are the tax lines that you return in the `getTaxLines` method for line items.
|
||||
|
||||
Similarly, you should see the shipping method tax lines in the cart’s `shipping_methods`, as each shipping method object has a `tax_lines` array which are the tax lines that you return in the `getTaxLines` method for shipping methods.
|
||||
@@ -0,0 +1,132 @@
|
||||
---
|
||||
description: 'Learn how to create a tax provider. You can create a tax provider in a Medusa backend or a plugin.'
|
||||
addHowToData: true
|
||||
---
|
||||
|
||||
# How to Override a Tax Calculation Strategy
|
||||
|
||||
In this document, you’ll learn how to override a tax calculation strategy.
|
||||
|
||||
## Overview
|
||||
|
||||
A tax calculation strategy is used to calculate taxes when calculating totals. The Medusa backend provides a tax calculation strategy that handles calculating the taxes accounting for defined tax rates, and settings such as whether tax-inclusive pricing is enabled.
|
||||
|
||||
You can override the tax calculation strategy to implement different calculation logic or to integrate a third-party service that handles the tax calculation. You can override it either in a Medusa backend setup or in a plugin.
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create Strategy Class
|
||||
|
||||
A tax calculation strategy should be defined in a TypeScript or JavaScript file created under the `src/strategies` directory. The class must also implement the `ITaxCalculationStrategy` interface imported from the `@medusajs/medusa` package.
|
||||
|
||||
For example, you can create the file `src/strategies/tax-calculation.ts` with the following content:
|
||||
|
||||
```ts title=src/strategies/tax-calculation.ts
|
||||
import {
|
||||
ITaxCalculationStrategy,
|
||||
LineItem,
|
||||
LineItemTaxLine,
|
||||
ShippingMethodTaxLine,
|
||||
TaxCalculationContext,
|
||||
} from "@medusajs/medusa"
|
||||
|
||||
class TaxCalculationStrategy
|
||||
implements ITaxCalculationStrategy {
|
||||
|
||||
async calculate(
|
||||
items: LineItem[],
|
||||
taxLines: (ShippingMethodTaxLine | LineItemTaxLine)[],
|
||||
calculationContext: TaxCalculationContext
|
||||
): Promise<number> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default TaxCalculationStrategy
|
||||
```
|
||||
|
||||
Note that you add a basic implementation of the `calculate` method because it’s required by the `ITaxCalculationStrategy` interface. You’ll learn about the method later in the guide.
|
||||
|
||||
### Using a Constructor
|
||||
|
||||
You can use a constructor to access services and resources registered in the dependency container using dependency injection. For example:
|
||||
|
||||
```ts title=src/strategies/tax-calculation.ts
|
||||
// ...
|
||||
import {
|
||||
LineItemService,
|
||||
} from "@medusajs/medusa"
|
||||
|
||||
type InjectedDependencies = {
|
||||
lineItemService: LineItemService
|
||||
}
|
||||
|
||||
class TaxCalculationStrategy
|
||||
implements ITaxCalculationStrategy {
|
||||
|
||||
protected readonly lineItemService_: LineItemService
|
||||
|
||||
constructor({ lineItemService }: InjectedDependencies) {
|
||||
this.lineItemService_ = lineItemService
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Implement the calculate Method
|
||||
|
||||
A tax calculation strategy is only required to implement the `calculate` method. This method is used whenever the totals are calculated.
|
||||
|
||||
:::tip
|
||||
|
||||
If automatic tax calculation is disabled, then the tax calculation strategy will only be used when taxes are calculated manually as explain [this guide](../storefront/manual-calculation.md).
|
||||
|
||||
:::
|
||||
|
||||
The `calculate` method expects three parameters:
|
||||
|
||||
- `items`: the first parameter is an array of [line item](../../../references/entities/classes/LineItem.md) objects.
|
||||
- `taxLines`: the second parameter is an array of either [shipping method tax line](../../../references/entities/classes/ShippingMethodTaxLine.md) or [line item tax line](../../../references/entities/classes/LineItemTaxLine.md) objects.
|
||||
- `calculationContext`: an object holding the context of the tax calculation. The object has the following properties:
|
||||
- `shipping_address`: an optional address object used for shipping.
|
||||
- `customer`: an optional customer object.
|
||||
- `region`: an optional region object.
|
||||
- `is_return`: a boolean value that determines whether the taxes are being calculated for a return flow.
|
||||
- `shipping_methods`: an array of shipping methods being used in the current context.
|
||||
- `allocation_map`: an object that indicates the gift cards and discounts applied on line items. Each object key or property is an ID of a line item, and the value is an object having the following properties:
|
||||
- `gift_card`: an optional object indicating the gift card applied on the line item.
|
||||
- `discount`: an optional object indicating the discount applied on the line item.
|
||||
|
||||
The method returns a number, being the tax amount for the line items, tax lines, and context provided.
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Run Build Command
|
||||
|
||||
In the directory of the Medusa backend, run the `build` command to transpile the files in the `src` directory into the `dist` directory:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Test it Out
|
||||
|
||||
Run your backend to test it out:
|
||||
|
||||
```bash npm2yarn
|
||||
npx medusa develop
|
||||
```
|
||||
|
||||
To test it out, you can simulate a checkout flow and check the calculated taxes to see if it matches the logic you implemented in the `calculate` method.
|
||||
|
||||
:::tip
|
||||
|
||||
As mentioned earlier, if automatic calculation of taxes is disabled in the region, you have to manually trigger tax calculation as explained in [this guide](../storefront/manual-calculation.md).
|
||||
|
||||
:::
|
||||
@@ -0,0 +1,206 @@
|
||||
---
|
||||
description: 'Learn what tax-inclusive pricing is and how it works in Medusa. Tax-inclusive pricing allows merchants to set the final prices for products and shipping options regardless of what tax rate is applicable for the customer.'
|
||||
---
|
||||
|
||||
# Tax Inclusive Pricing
|
||||
|
||||
In this document, you’ll learn how tax-inclusive pricing works in Medusa.
|
||||
|
||||
:::note
|
||||
|
||||
Tax Inclusive Pricing is currently in beta mode and guarded by a feature flag. To use Tax-Inclusive Pricing either:
|
||||
|
||||
1. Enable the `MEDUSA_FF_TAX_INCLUSIVE_PRICING` environment variable;
|
||||
2. Or enable the `tax_inclusive_pricing` key in the Medusa backend's settings.
|
||||
|
||||
You can learn more about enabling it in the [feature flags](../../development/feature-flags/toggle.md) documentation.
|
||||
|
||||
:::
|
||||
|
||||
## Introduction
|
||||
|
||||
Tax Inclusive pricing allows you to set the final prices for products and shipping options regardless of the customer's applicable tax rates. When tax-inclusive prices are used, Medusa automatically calculates the tax amount for a given price.
|
||||
|
||||
This can be useful when some countries have the same currency but have different tax rates. If you want your prices to be the same across these countries, you have to manage two price lists to account for the tax differences. Using tax-inclusive pricing you only have to specify the price once.
|
||||
|
||||
Then, Medusa handles calculating the tax amount using the tax rate and the tax-inclusive price. This is managed in the backend and relayed to accounting and analytics tools.
|
||||
|
||||
---
|
||||
|
||||
## How is Tax Inclusivity Defined
|
||||
|
||||
Tax inclusivity can be toggled for regions, currencies, price lists, and shipping options either during creation or while editing. This is represented by the boolean attribute `includes_tax` available in the entities `Region`, `Currency`, `PriceList`, and `ShippingOption`. By default, this attribute is set to `false`.
|
||||
|
||||
If you want to enable or disable this attribute for any of these entities, you can use the create or update endpoints related to these entities as shown in the [Admin API reference](https://docs.medusajs.com/api/admin/).
|
||||
|
||||
The value set for these entities can affect whether line items and shipping methods are tax inclusive or not.
|
||||
|
||||
### How is Tax Inclusivity Defined for Line Items
|
||||
|
||||
:::info
|
||||
|
||||
When a product is added to the cart, a line item is created to represent that product in the cart.
|
||||
|
||||
:::
|
||||
|
||||
The `LineItem` entity also has the `includes_tax` attribute. The value of this flag is set to `true` if:
|
||||
|
||||
- The region of the line item has the `includes_tax` attribute set to `true`;
|
||||
- Or the currency of the line item has the `includes_tax` attribute set to `true`;
|
||||
- Or a price list that includes the product variant associated with the line item has the `includes_tax` attribute set to `true`, and the tax-inclusive amount of one of the variant’s prices in the price list is less than the original price of the variant;
|
||||
- Or one of the variant’s prices in the price list uses a currency or region that has the `includes_tax` attribute set to `true`, and the tax-inclusive amount of the price is less than the original price of the variant.
|
||||
|
||||
### How is Tax Inclusivity Defined for Shipping Methods
|
||||
|
||||
:::info
|
||||
|
||||
When a shipping option is selected, a shipping method is created based on that shipping option. You can learn more about this in the [Shipping Architecture documentation](../carts-and-checkout/shipping.md).
|
||||
|
||||
:::
|
||||
|
||||
The `ShippingMethod` entity also has the `includes_tax` attribute. Its value is the same as the value of `includes_tax` of the shipping option the method is associated with.
|
||||
|
||||
---
|
||||
|
||||
## Tax Amount Calculation Formula
|
||||
|
||||
When a price is tax-inclusive, the tax amount is calculated using the following formula:
|
||||
|
||||
```jsx noReport
|
||||
const taxAmount = (taxRate * taxInclusivePrice) / (1 + taxRate)
|
||||
```
|
||||
|
||||
Where `taxRate` is the tax rate to be applied to the price, and `taxInclusivePrice` is the price entered by the store operator.
|
||||
|
||||
For example, if the tax rate is `0.25` and the price of a product is `100`, the resulting tax amount calculated by Medusa will be `0.25 * 100 / 1.25 = 20`.
|
||||
|
||||
---
|
||||
|
||||
## Retrieving Tax Amounts
|
||||
|
||||
This section covers at which point tax amounts are calculated for different entities, how they are calculated when the price is tax inclusive, and what fields can be returned in the endpoints relative to each of the entities.
|
||||
|
||||
:::note
|
||||
|
||||
If you have disabled the automatic calculation of taxes in a region, you must [manually calculate the taxes of the line items and the cart](./storefront/manual-calculation.md). Otherwise, taxes will not be calculated or retrieved during checkout for each entity mentioned here.
|
||||
|
||||
:::
|
||||
|
||||
### Products
|
||||
|
||||
Taxes are calculated for each product variant either when a [single product is retrieved](https://docs.medusajs.com/api/store#products_getproductsproduct) or a [list of products is retrieved](https://docs.medusajs.com/api/store#products_getproducts).
|
||||
|
||||
Among the pricing fields retrieved for each variant, the following fields are relevant to taxes:
|
||||
|
||||
- `original_price`: The original price of the variant.
|
||||
- `calculated_price`: The calculated price, which can be based on prices defined in a price list.
|
||||
- `original_tax`: The tax amount applied to the original price.
|
||||
- `calculated_tax`: The tax amount applied to the calculated price.
|
||||
- `original_price_incl_tax`: The price after applying the tax amount on the original price.
|
||||
- `calculated_price_incl_tax`: The price after applying the tax amount on the calculated price
|
||||
- `original_price_includes_tax`: a boolean value indicating whether the amount in `original_price` includes the tax amount by default or not.
|
||||
- `calculated_price_includes_tax`: a boolean value indicating whether the amount in `calculated_price` includes the tax amount by default or not.
|
||||
|
||||
If tax inclusivity is enabled for the current region or currency (based on whether the default price is specified for the region or currency, with region taking a higher precedence):
|
||||
|
||||
- `original_price` will include the tax amount by default.
|
||||
- `original_price_includes_tax` will be set to `true`.
|
||||
- `original_price_incl_tax` will have the same amount as `original_price`.
|
||||
- `original_tax` is automatically calculated by Medusa.
|
||||
|
||||
Also, for each of the product variant’s prices in a price list, if tax inclusivity is enabled (either if the price list itself has the `includes_tax` attribute set to `true`, or the variant’s price in the price list uses a currency or region that has the `includes_tax` attribute set to `true`), and the amount of the price is less than the original price of the variant:
|
||||
|
||||
- `calculated_tax` will include the tax amount by default.
|
||||
- `calculated_price_includes_tax` will be set to `true`.
|
||||
- `calculated_price_incl_tax` will have the same amount as `calculated_price`.
|
||||
|
||||
:::info
|
||||
|
||||
Price lists include a list of prices that can be used to override the original price of a product’s variants.
|
||||
|
||||
Each variant’s price in the price list is compared to the variant’s original price using the following condition:
|
||||
|
||||
```jsx noReport
|
||||
amount < (1 + taxRate) * calculatedPrice
|
||||
```
|
||||
|
||||
Where `amount` is the amount of the variant’s price in the price list, `taxRate` is the applied rate, and `calculatedPrice` is the original price of the variant.
|
||||
|
||||
:::
|
||||
|
||||
Here is an example of these fields when tax inclusivity is enabled for both the currency and the price list:
|
||||
|
||||
<!-- eslint-skip -->
|
||||
|
||||
```js noReport
|
||||
{
|
||||
original_price: 110,
|
||||
calculated_price: 100,
|
||||
calculated_price_type: "sale",
|
||||
original_price_includes_tax: true,
|
||||
calculated_price_includes_tax: true,
|
||||
calculated_price_incl_tax: 100,
|
||||
calculated_tax: 20,
|
||||
original_price_incl_tax: 110,
|
||||
original_tax: 22,
|
||||
}
|
||||
```
|
||||
|
||||
### Line Item
|
||||
|
||||
The taxes of line items are calculated and retrieved whenever the [cart is retrieved or updated](https://docs.medusajs.com/api/store#carts).
|
||||
|
||||
Each line item returned in any of the cart’s requests has total fields related to the price of the line item and its taxes. Among those fields, the following are relevant to tax-inclusive pricing:
|
||||
|
||||
- `unit_price`: The original price of the variant associated with the line item.
|
||||
- `tax_total`: The total tax amount applied on the original price taking into account any applied discounts as well.
|
||||
- `original_tax_total`: The total tax amount applied on the original price without taking into account any applied discounts.
|
||||
- `subtotal`: The total of the line item’s price subtracting the amount in `original_tax_total`.
|
||||
- `origial_total`: The `subtotal` including the `original_tax_total` amount.
|
||||
|
||||
If tax inclusivity is enabled for the line item, `unit_price` will include the tax amount. The tax amount, which will also be the value of `tax_total`, is calculated using [Medusa’s formula for tax inclusive pricing](#tax-amount-calculation-formula) based on the line item’s tax rates. The calculation takes into account any discounts applied on the item, which means the discount amount is deducted from the original price.
|
||||
|
||||
Then, the `subtotal` is calculated by subtracting the `tax_total` from the total of the line item’s price. `original_total` has the same value as `subtotal`.
|
||||
|
||||
:::info
|
||||
|
||||
The total of the line item’s price is the variant’s `unit_price` multiplied by its quantity in the cart.
|
||||
|
||||
:::
|
||||
|
||||
Finally, `original_tax_total` undergoes the same `tax_total` calculation, however, any discounts applied on the line item are not taken into account. This means the discount amount is not deducted from the original price.
|
||||
|
||||
### Shipping Options
|
||||
|
||||
Taxes for Shipping Options are calculated and retrieved when the [list of shipping options is retrieved](https://docs.medusajs.com/api/store#shipping-options).
|
||||
|
||||
Among the returned fields for each shipping option, the following are relevant to each of their pricing and taxes:
|
||||
|
||||
- `amount`: The original price of the shipping option.
|
||||
- `price_incl_tax`: The price of the shipping option with tax included.
|
||||
- `tax_amount`: The tax amount applied to the shipping option.
|
||||
|
||||
If tax inclusivity is enabled for the shipping option, `amount` and `price_incl_tax` have the same value. Also, the value of `tax_amount` is calculated using [Medusa’s formula for tax inclusive pricing](#tax-amount-calculation-formula).
|
||||
|
||||
### Carts and Orders
|
||||
|
||||
Carts and Orders have the same total fields relevant for taxes.
|
||||
|
||||
A cart’s totals, including its taxes, are calculated and retrieved whenever the cart is [updated or retrieved](https://docs.medusajs.com/api/store#carts).
|
||||
|
||||
An order’s totals, including its taxes, are calculated and retrieved whenever the order is retrieved both on the [storefront](https://docs.medusajs.com/api/store#orders) and on the [admin](https://docs.medusajs.com/api/admin#orders).
|
||||
|
||||
The relevant fields are:
|
||||
|
||||
- `shipping_total`: The total tax-exclusive price of the shipping methods used in the cart or order without any applied taxes.
|
||||
- `tax_total`: The total of the taxes applied on the cart or order, including taxes applied on line items and shipping methods.
|
||||
- `subtotal`: The subtotal of line items including taxes, but without shipping total.
|
||||
- `total`: The total of the cart or order, including the subtotal, shipping total, and taxes applied.
|
||||
|
||||
During the calculation of the totals of different components of the cart or order, such as shipping or line items, if tax inclusivity is enabled on that component, a process similar to those explained above will be applied to retrieve the total.
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Calculate taxes manually](./storefront/manual-calculation.md)
|
||||
@@ -0,0 +1,192 @@
|
||||
---
|
||||
description: "Taxes are additional costs or fees imposed by a government for goods or services. Learn about the available features and guides."
|
||||
---
|
||||
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
import Icons from '@theme/Icon';
|
||||
|
||||
# Taxes
|
||||
|
||||
Taxes are additional costs or fees imposed by a government for goods or services. This overview introduces the available features related to taxes.
|
||||
|
||||
:::note
|
||||
|
||||
Not a developer? Check out the [Taxes user guide](../../user-guide/taxes/index.md).
|
||||
|
||||
:::
|
||||
|
||||
## Features
|
||||
|
||||
### Tax Providers
|
||||
|
||||
Developers can integrate third-party tax providers or implement custom tax-provider logic.
|
||||
|
||||
Admins can specify the tax provider for a specific region.
|
||||
|
||||
Customers can view calculated taxes during their checkout process.
|
||||
|
||||
<DocCardList colSize={4} items={[
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/taxes/backend/create-tax-provider',
|
||||
label: 'Backend: Create Tax Provider',
|
||||
customProps: {
|
||||
icon: Icons['academic-cap-solid'],
|
||||
description: 'Learn how to create a tax provider.',
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/taxes/backend/tax-calculation-strategy',
|
||||
label: 'Backend: Tax Calculation Strategy',
|
||||
customProps: {
|
||||
icon: Icons['academic-cap-solid'],
|
||||
description: 'Learn how to override the tax calculation strategy.'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/taxes/admin/manage-tax-settings',
|
||||
label: 'Admin: Manage Tax Settings',
|
||||
customProps: {
|
||||
icon: Icons['academic-cap-solid'],
|
||||
description: 'Learn how to manage tax settings using Admin APIs.',
|
||||
}
|
||||
},
|
||||
]} />
|
||||
|
||||
<DocCardList colSize={6} items={[
|
||||
{
|
||||
type: 'link',
|
||||
href: '/user-guide/taxes/manage',
|
||||
label: 'User Guide: Manage Taxes',
|
||||
customProps: {
|
||||
icon: Icons['users-solid'],
|
||||
description: 'Learn how to manage taxes in Medusa Admin.'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/taxes/storefront/manual-calculation',
|
||||
label: 'Storefront: Manually Calculate Taxes',
|
||||
customProps: {
|
||||
icon: Icons['users-solid'],
|
||||
description: 'Learn how to manually calculate taxes during checkout.'
|
||||
}
|
||||
},
|
||||
]} />
|
||||
|
||||
### Tax Rates and Overrides
|
||||
|
||||
Admins can create additional tax rates aside from the default tax rate. They can also specify overrides of tax rates for specific products, product types, or shipping options.
|
||||
|
||||
Customers can review order edit requests and authorize additional payments if necessary.
|
||||
|
||||
<DocCardList colSize={4} items={[
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/taxes/admin/manage-tax-rates',
|
||||
label: 'Admin: Manage Tax Rates',
|
||||
customProps: {
|
||||
icon: Icons['academic-cap-solid'],
|
||||
description: 'Learn how to manage tax rates using Admin APIs.',
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '/user-guide/taxes/tax-rates',
|
||||
label: 'User Guide: Tax Rates',
|
||||
customProps: {
|
||||
icon: Icons['users-solid'],
|
||||
description: 'Learn how to manage tax rates using Medusa Admin.'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '/user-guide/taxes/tax-overrides',
|
||||
label: 'User Guide: Tax Overrides',
|
||||
customProps: {
|
||||
icon: Icons['users-solid'],
|
||||
description: 'Learn how to manage tax rates using Medusa Admin.'
|
||||
}
|
||||
},
|
||||
]} />
|
||||
|
||||
### Tax-Inclusive Pricing
|
||||
|
||||
Admins can enable tax-inclusive pricing for a region or currency. This would automatically calculate the taxes applied on a product for that region or currency.
|
||||
|
||||
<DocCardList colSize={6} items={[
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/taxes/inclusive-pricing',
|
||||
label: 'Architecture: Tax-Inclusive Pricing',
|
||||
customProps: {
|
||||
icon: Icons['circle-stack-solid'],
|
||||
description: 'Learn how tax-inclusive pricing works and its relation to other modules.'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '/user-guide/taxes/tax-inclusive',
|
||||
label: 'User Guide: Tax-Inclusive Pricing',
|
||||
customProps: {
|
||||
icon: Icons['users-solid'],
|
||||
description: 'Learn how to manage tax-inclusive pricing using Medusa Admin.'
|
||||
}
|
||||
},
|
||||
]} />
|
||||
|
||||
---
|
||||
|
||||
## Understand the Architecture
|
||||
|
||||
Learn how tax-related entities and concepts are built, their relation to other modules, and more.
|
||||
|
||||
<DocCardList colSize={6} items={[
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/taxes',
|
||||
label: 'Architecture: Tax',
|
||||
customProps: {
|
||||
icon: Icons['circle-stack-solid'],
|
||||
description: 'Learn about the Tax Architecture.',
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/taxes/inclusive-pricing',
|
||||
label: 'Architecture: Tax-Inclusive Pricing',
|
||||
customProps: {
|
||||
icon: Icons['circle-stack-solid'],
|
||||
description: 'Learn how tax-inclusive pricing works.'
|
||||
}
|
||||
},
|
||||
]} />
|
||||
|
||||
---
|
||||
|
||||
## Related Modules
|
||||
|
||||
Discover Taxes' relation to other modules in Medusa.
|
||||
|
||||
<DocCardList colSize={6} items={[
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/regions-and-currencies/overview',
|
||||
label: 'Regions',
|
||||
customProps: {
|
||||
icon: Icons['globe-europe-solid'],
|
||||
description: 'Taxes, tax rates, and tax overrides are associated with a region.'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
href: '/modules/carts-and-checkout/overview',
|
||||
label: 'Carts and Checkout',
|
||||
customProps: {
|
||||
icon: Icons['shopping-cart-solid'],
|
||||
description: 'Taxes can be automatically or manually calculated during checkout.'
|
||||
}
|
||||
},
|
||||
]} />
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
description: 'Learn how to manually calculate taxes during checkout in the Medusa backend. There are different methods including using endpoints or services.'
|
||||
addHowToData: true
|
||||
---
|
||||
|
||||
# Calculate Taxes Manually in Checkout
|
||||
|
||||
In this document, you’ll learn how to manually calculate taxes during checkout if you have automatic tax calculation disabled in a region.
|
||||
|
||||
## Overview
|
||||
|
||||
By default, taxes are automatically calculated by Medusa during checkout. This behavior can be disabled for a region using the Admin APIs or the Medusa admin to limit the requests being sent to a tax provider.
|
||||
|
||||
If you disable this behavior, you must manually trigger taxes calculation. When taxes are calculated, this means that requests will be sent to the tax provider to retrieve the tax rates.
|
||||
|
||||
---
|
||||
|
||||
## How to Manually Calculate Taxes in Checkout
|
||||
|
||||
This section explores different ways you can calculate taxes based on your purpose.
|
||||
|
||||
### Use Calculate Cart Taxes Endpoint
|
||||
|
||||
The [Calculate Cart Taxes](https://docs.medusajs.com/api/store#carts_postcartscarttaxes) endpoint forces the calculation of taxes for a cart during checkout. This bypasses the option set in admin to not calculate taxes automatically, which results in sending requests to the tax provider.
|
||||
|
||||
This calculates and retrieves the taxes on the cart and each of the line items in that cart.
|
||||
|
||||
### Use CartService's retrieve Method
|
||||
|
||||
The `CartService` class has a method `retrieve` that gets a cart by ID. In that method, taxes are calculated only if automatic taxes calculation is enabled for the region the cart belongs to.
|
||||
|
||||
You can, however, force calculating the taxes of the cart by passing in the third parameter an option containing the key `force_taxes` with its value set to `true`.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
cartService.retrieve(
|
||||
"cart_01G8Z...",
|
||||
{ },
|
||||
{
|
||||
force_taxes: true,
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
You can learn how to [retrieve and use services](../../../development/services/create-service.mdx#using-your-custom-service) in this documentation.
|
||||
|
||||
:::
|
||||
|
||||
### Use CartService's decorateTotals Method
|
||||
|
||||
Another way you can use the `CartService` to calculate taxes is using the method `decorateTotals`:
|
||||
|
||||
```jsx
|
||||
|
||||
export default () => {
|
||||
// ...
|
||||
|
||||
router.get("/store/line-taxes", async (req, res) => {
|
||||
// example of retrieving cart
|
||||
const cartService = req.scope.resolve("cartService")
|
||||
const cart = await cartService.retrieve(cart_id)
|
||||
|
||||
// ...
|
||||
// retrieve taxes of line items
|
||||
const data = await decorateTotals(cart, {
|
||||
force_taxes: true,
|
||||
})
|
||||
|
||||
return res.status(200).json({ cart: data })
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
The `decorateTotals` method accepts the cart as a first parameter and an options object as a second parameter. If you set `force_taxes` to `true` in that object, the totals of the line items can be retrieved regardless of whether the automatic calculation is enabled in the line item’s region.
|
||||
|
||||
### Use TotalsService
|
||||
|
||||
You can calculate and retrieve taxes of line items using the `getLineItemTotals` method available in the `TotalService` class. All you need to do is pass in the third argument to that method an options object with the key `include_tax` set to true:
|
||||
|
||||
```jsx
|
||||
const itemTotals = await totalsService
|
||||
.getLineItemTotals(item, cart, {
|
||||
include_tax: true,
|
||||
})
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
You can learn how to [retrieve and use services](../../../development/services/create-service.mdx#using-your-custom-service) in this documentation.
|
||||
|
||||
:::
|
||||
@@ -0,0 +1,90 @@
|
||||
---
|
||||
description: 'Learn about taxes in Medusa. This includes learning about the usage of taxes in regions, tax rates, tax providers, and more.'
|
||||
---
|
||||
|
||||
# Taxes Architecture Overview
|
||||
|
||||
In this document, you’ll learn about taxes in Medusa.
|
||||
|
||||
## Overview
|
||||
|
||||
Taxes are fees applied on items and shipping options when making a purchase. Taxes are typically different for each region around the world, both in amount and calculation logic.
|
||||
|
||||
In Medusa, there are different ways you can customize taxes, allowing you to implement what works for your setup or the regions your commerce store operates in. You can:
|
||||
|
||||
- Create a tax provider that defines the tax lines applied to line items and shipping methods.
|
||||
- Customize the tax calculation strategy to change how taxes are calculated.
|
||||
- Override tax rates for specific products, product types, or shipping options in a region using endpoints or services.
|
||||
|
||||
---
|
||||
|
||||
## Taxes in Regions
|
||||
|
||||
Since taxes are different for each country or region, taxes are configured per region.
|
||||
|
||||
In the `Region` entity, the following attributes are related to taxes:
|
||||
|
||||
- `tax_rate`: a number indicating the default tax rate to be applied in the region.
|
||||
- `tax_code`: a string indicating the tax code of the region. This can be useful to external systems for accounting purposes.
|
||||
- `gift_card_taxable`: a boolean value indicating whether gift cards in this region are taxable or not. By default, it’s `true`.
|
||||
- `automatic_taxes`: a boolean value indicating if taxes should be calculated automatically during checkout in that region. By default, it’s `true`.
|
||||
- `tax_provider_id`: the ID of the tax provider used in the region. By default, the `system` tax provider is used. The tax provider can also be accessed by expanding the `tax_provider` relation and accessing `region.tax_provider`.
|
||||
- `includes_tax`: a boolean value indicating if tax-inclusive pricing is enabled in the region. You can learn about tax-inclusive pricing [here](./inclusive-pricing.md).
|
||||
|
||||
### Tax Rates
|
||||
|
||||
A region has a default tax rate, defined in the `tax_rate` attribute. However, you can override this tax rate for specific products, product types, or shipping options in that region.
|
||||
|
||||
This is represented by the `TaxRate` entity. A region can have many tax rates, and the taxes rates can be accessed by expanding the `tax_rates` relation and accessing `region.tax_rates`.
|
||||
|
||||
Since a tax rate can be used to override taxes for specific conditions, the `TaxRate` entity has the following relations:
|
||||
|
||||
- `products`: an array of products that this tax rate applies to. You can access them by expanding the `products` relation and accessing `tax_rate.products`.
|
||||
- `product_types`: an array of product types that this tax rate applies to. You can access them by expanding the `product_types` relation and accessing `tax_rate.product_types`.
|
||||
- `shipping_options`: an array of shipping options that this tax rate applies to. You can access them by expanding the `shipping_options` relation and accessing `tax_rate.shipping_options`.
|
||||
|
||||
The `TaxRate` entity’s attributes include:
|
||||
|
||||
- `rate`: a number indicating the tax rate to apply for the specified conditions.
|
||||
- `code`: a string indicating the tax code of this rate.
|
||||
- `name`: a string indicating the name of the tax rate.
|
||||
- `region_id`: a string indicating the ID of the region this tax rate applies to. You can also access the region by expanding the `region` relation and accessing `tax_rate.region`.
|
||||
|
||||
### Tax Provider
|
||||
|
||||
Tax providers are used to return the tax line items for a set of line items and shipping methods during checkout. The Medusa backend has a `system` tax provider. It returns the line items as-is, without making any changes. You can also create your own tax provider that matches your use case.
|
||||
|
||||
Each region can use a different tax provider. By default, regions use the `system` tax provider.
|
||||
|
||||
For example, the tax provider allows you to use the shipping address of the cart to create tax lines.
|
||||
|
||||
---
|
||||
|
||||
## Tax Lines
|
||||
|
||||
During checkout, taxes are applied to line items and shipping methods as tax lines. The taxes applied to line items are represented by the `LineItemTaxLine` entity, and those applied to shipping methods are represented by the `ShippingMethodTaxLine` entity. Both entities extend the `TaxLine` class, which defines the following attributes:
|
||||
|
||||
- `rate`: a number indicating the applied tax rate.
|
||||
- `name`: a string indicating the name of the tax rate.
|
||||
- `code`: a string indicating the tax code.
|
||||
|
||||
In addition to these attributes, the `LineItemTaxLine` entity has an `item_id` attribute, which is a string indicating the ID of the line item this tax line is applied to. You can also access the line item by expanding the `item` relation and accessing `line_item_tax_line.item`.
|
||||
|
||||
On the other hand, the `ShippingMethodTaxLine` has the attributes of `TaxLine` along with the `shipping_method_id` attribute, which is a string indicating the ID of the shipping method this tax line is applied to. You can also access the shipping method by expanding the `shipping_method` relation and accessing `shipping_method_tax_line.shipping_method`.
|
||||
|
||||
---
|
||||
|
||||
## Tax Calculation Strategy
|
||||
|
||||
The tax calculation strategy is used to calculate taxes based on a set of line items, tax lines, and a context during checkout. The strategy is used throughout the Medusa backend, such as when calculating the totals of a cart.
|
||||
|
||||
Medusa defines a default tax calculation strategy. It calculates the taxes of line items and shipping methods, and returns the total of the two.
|
||||
|
||||
You can override the tax calculation strategy to define a calculation strategy that works for your use case.
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Tax Inclusive Pricing](./inclusive-pricing.md)
|
||||
- [How to calculate taxes manually during checkout](./storefront/manual-calculation.md)
|
||||
Reference in new issue
Block a user