How to Create a Tax Provider
In this document, you’ll learn how to create a tax provider in the Medusa backend and the methods you must implement in it.
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.
A tax provider class is defined in a TypeScript or JavaScript file under the src/services
directory and the class must extend the
AbstractTaxService
class imported from @medusajs/medusa
. The file's name is the tax provider's class name as a slug and without the word Service
.
For example, you can create the file src/services/my-tax.ts
with the following content:
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
Identifier Property
The TaxProvider
entity has 2 properties: identifier
and is_installed
. The identifier
property in the tax provider service is used when the tax provider is added to the database.
The value of this property is also used to reference the tax provider throughout Medusa. For example, it is used to change the tax provider to a region.
constructor
You can use the constructor
of your tax provider to access the different services in Medusa through dependency injection.
You can also use the constructor to initialize your integration with the third-party provider. For example, if you use a client to connect to the third-party provider’s APIs, you can initialize it in the constructor and use it in other methods in the service. Additionally, if you’re creating your tax provider as an external plugin to be installed on any Medusa backend and you want to access the options added for the plugin, you can access it in the constructor.
Example
// ...
import { LineItemService } from "@medusajs/medusa"
type InjectedDependencies = {
lineItemService: LineItemService
}
class MyTaxService extends AbstractTaxService {
protected readonly lineItemService_: LineItemService
constructor({ lineItemService }: InjectedDependencies) {
super(arguments[0])
this.lineItemService_ = lineItemService
// you can also initialize a client that
// communicates with a third-party service.
this.client = new Client(options)
}
// ...
}
export default MyTaxService
Parameters
container
Record<string, unknown>RequiredMedusaContainer
that allows you to access other resources, such as services, in your Medusa backend.config
Record<string, unknown>Methods
getTaxLines
This method is used when retrieving the tax lines for line items and shipping methods. This occurs during checkout or when calculating totals for orders, swaps, or returns.
Example
An example of how this method is implemented in the system
provider implemented in the Medusa backend:
// ...
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
}
}
Parameters
The line item lines to calculate taxes for.
The shipping method lines to calculate taxes for.
Context relevant and useful for the taxes calculation.
Returns
The list of calculated line item and shipping method tax lines.
If an item in the array has the shipping_method_id
property, then it's a shipping method tax line. Otherwise, if it has
the item_id
property, then it's a line item tax line.
shipping_method_id
property, then it's a shipping method tax line. Otherwise, if it has
the item_id
property, then it's a line item tax line.Test Implementation
If you created your tax provider in a plugin, refer to this guide on how to test plugins.
After finishing your tax provider implementation:
1. Run the build
command in the root of your Medusa backend:
2. Start the backend with the develop
command:
3. Use the tax provider in a region. You can do that either using the Admin APIs or the Medusa Admin.
4. To test out your tax provider implementation, you can trigger taxes calculation manually.