In this document, you’ll learn how to create a Tax Module Provider to use with the Tax Module, and the methods to implement.
A Tax Module Provider is used to retrieve the tax lines in a provided context. The Tax Module provides a default system
provider. You can create your own Tax Module Provider, either in a plugin, in a module provider, or directly in your Medusa application's codebase, then use it in any tax region.
The Tax Module Provider handles calculating taxes with a third-party provirder. However, it's not responsible for managing tax concepts within Medusa, such as creating a tax region. The Tax Module uses your Tax Module Provider within core operations.
For example, during checkout, the Tax Module Provider of the tax region that the customer is in is used to calculate the tax for the cart and order. So, you only have to implement the third-party tax calculation logic in your Tax Module Provider.
Start by creating a new directory for your module provider.
If you're creating the module provider in a Medusa application, create it under the src/modules
directory. For example, src/modules/my-tax
.
If you're creating the module provider in a plugin, create it under the src/providers
directory. For example, src/providers/my-tax
.
src/modules/my-tax
directory as an example.Create the file src/modules/my-tax/service.ts
that holds the module provider's main service. It must implement the ITaxProvider
interface imported from @medusajs/framework/types
:
Each tax provider has a unique identifier defined in its class. The provider's ID
will be stored as tp_{identifier}_{id}
, where {id}
is the provider's id
property in the medusa-config.ts
.
For example:
You can use the constructor
of your tax provider to access the resources registered in the Module Container.
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 a plugin or a module provider to be installed in any Medusa application and you want to access its options, you can access them in the second parameter of the constructor.
For example:
This method is used to retrieve the tax lines of items and shipping methods. It's used during checkout
when the getTaxLines
method of the Tax Module's main service is called for a tax
region that uses this tax provider.
An example of how this method is implemented in the system
provider:
1// ...2 3export default class SystemTaxService implements ITaxProvider {4 // ...5 6 async getTaxLines(7 itemLines: TaxTypes.ItemTaxCalculationLine[],8 shippingLines: TaxTypes.ShippingTaxCalculationLine[],9 _: TaxTypes.TaxCalculationContext10 ): Promise<(TaxTypes.ItemTaxLineDTO | TaxTypes.ShippingTaxLineDTO)[]> {11 let taxLines: (TaxTypes.ItemTaxLineDTO | TaxTypes.ShippingTaxLineDTO)[] =12 itemLines.flatMap((l) => {13 return l.rates.map((r) => ({14 rate_id: r.id,15 rate: r.rate || 0,16 name: r.name,17 code: r.code,18 line_item_id: l.line_item.id,19 provider_id: this.getIdentifier(),20 }))21 })22 23 taxLines = taxLines.concat(24 shippingLines.flatMap((l) => {25 return l.rates.map((r) => ({26 rate_id: r.id,27 rate: r.rate || 0,28 name: r.name,29 code: r.code,30 shipping_line_id: l.shipping_line.id,31 provider_id: this.getIdentifier(),32 }))33 })34 )35 36 return taxLines37 }38}
itemLines
ItemTaxCalculationLine[]shippingLines
ShippingTaxCalculationLine[]context
TaxCalculationContextPromise
Promise<(ItemTaxLineDTO | ShippingTaxLineDTO)[]>shipping_line_id
property, then it's a shipping tax line. Otherwise, if it has
the line_item_id
property, then it's a line item tax line.Create the file src/modules/my-tax/index.ts
with the following content:
This exports the module provider's definition, indicating that the MyTaxProvider
is the module provider's service.
To use your Tax Module Provider, add it to the providers
array of the Tax Module in medusa-config.ts
:
1module.exports = defineConfig({2 // ...3 modules: [4 {5 resolve: "@medusajs/medusa/tax",6 options: {7 providers: [8 {9 // if module provider is in a plugin, use `plugin-name/providers/my-tax`10 resolve: "./src/modules/my-tax",11 id: "my-tax",12 options: {13 // provider options...14 },15 },16 ],17 },18 },19 ]20})