* Fix issue on fixed total amount discount when using includes tax (#3472) The calculation of the fixed discount amount breaks when having includes_tax setting active, due to the line item totals are incorrect and returning everything as 0, thus the totalItemPercentage will be Infinitiy due to the division by a subtotal of 0 * chore: Add missing changeset for @medusajs/medusa * feat(medusa): Improve performance of Products domain (#3417) * feat(medusa): Improve product update performances * fix tests and update * update mock repo * improve repo * cleanup * fix * cleanup + bulk emit + unit test fix * improvements * improve * fix unit tests * fix export * fix product update handler * enhance mock repo * fix import integration * fix end point tests * revert mock repo product variant * fix unit * cleanup * cleanup * address feedback * fix quotes in tests * address feedback * Create new-tips-mate.md * use types * chore: Remove integration-tests from changeset * chore(release): v1.7.14 * chore(docs): Generated Docs Announcement Bar (automated) (#3489) Co-authored-by: olivermrbl <olivermrbl@users.noreply.github.com> * fix(medusa): EventBusService.emit using Redis mock (#3491) * Fix eventBusService.emit using redis mock * revert gitignore * enqueuer * unit test add redis_url * fix test * chore(docs): Generated Services Reference (automated) (#3490) Co-authored-by: olivermrbl <olivermrbl@users.noreply.github.com> * docs: publish restructure (#3496) * docs: added features and guides overview page * added image * added version 2 * added version 3 * added version 4 * docs: implemented new color scheme * docs: redesigned sidebar (#3193) * docs: redesigned navbar for restructure (#3199) * docs: redesigned footer (#3209) * docs: redesigned cards (#3230) * docs: redesigned admonitions (#3231) * docs: redesign announcement bar (#3236) * docs: redesigned large cards (#3239) * docs: redesigned code blocks (#3253) * docs: redesigned search modal and page (#3264) * docs: redesigned doc footer (#3268) * docs: added new sidebars + refactored css and assets (#3279) * docs: redesigned api reference sidebar * docs: refactored css * docs: added code tabs transition * docs: added new sidebars * removed unused assets * remove unusued assets * Fix deploy errors * fix incorrect link * docs: fixed code responsivity + missing icons (#3283) * docs: changed icons (#3296) * docs: design fixes to the sidebar (#3297) * redesign fixes * docs: small design fixes * docs: several design fixes after restructure (#3299) * docs: bordered icon fixes * docs: desgin fixes * fixes to code blocks and sidebar scroll * design adjustments * docs: restructured homepage (#3305) * docs: restructured homepage * design fixes * fixed core concepts icon * docs: added core concepts page (#3318) * docs: restructured homepage * design fixes * docs: added core concepts page * changed text of different components * docs: added architecture link * added missing prop for user guide * docs: added regions overview page (#3327) * docs: added regions overview * moved region pages to new structure * docs: fixed description of regions architecture page * small changes * small fix * docs: added customers overview page (#3331) * docs: added regions overview * moved region pages to new structure * docs: fixed description of regions architecture page * small changes * small fix * docs: added customers overview page * fix link * resolve link issues * docs: updated regions architecture image * docs: second-iteration fixes (#3347) * docs: redesigned document * design fixes * docs: added products overview page (#3354) * docs: added carts overview page (#3363) * docs: added orders overview (#3364) * docs: added orders overview * added links in overview * docs: added vercel redirects * docs: added soon badge for cards (#3389) * docs: resolved feedback changes + organized troubleshooting pages (#3409) * docs: resolved feedback changes * added extra line * docs: changed icons for restructure (#3421) * docs: added taxes overview page (#3422) * docs: added taxes overview page * docs: fix sidebar label * added link to taxes overview page * fixed link * docs: fixed sidebar scroll (#3429) * docs: added discounts overview (#3432) * docs: added discounts overview * fixed links * docs: added gift cards overview (#3433) * docs: added price lists overview page (#3440) * docs: added price lists overview page * fixed links * docs: added sales channels overview page (#3441) * docs: added sales overview page * fixed links * docs: added users overview (#3443) * docs: fixed sidebar border height (#3444) * docs: fixed sidebar border height * fixed svg markup * docs: added possible solutions to feedback component (#3449) * docs: added several overview pages + restructured files (#3463) * docs: added several overview pages * fixed links * docs: added feature flags + PAK overview pages (#3464) * docs: added feature flags + PAK overview pages * fixed links * fix link * fix link * fixed links colors * docs: added strategies overview page (#3468) * docs: automated upgrade guide (#3470) * docs: automated upgrade guide * fixed vercel redirect * docs: restructured files in docs codebase (#3475) * docs: restructured files * docs: fixed eslint exception * docs: finished restructure loose-ends (#3493) * fixed uses of backend * docs: finished loose ends * eslint fixes * fixed links * merged master * added update instructions for v1.7.12 * docs: fixed discount details (#3499) * docs: fix trailing slash causing 404 (#3508) * docs: fix error during navigation (#3509) * docs: removed the gatsby storefront guide (#3527) * docs: removed the gatsby storefront guide * docs: fixed query value * chore(docs): Removed Docs Announcement Bar (automated) (#3536) Co-authored-by: shahednasser <shahednasser@users.noreply.github.com> * fix(medusa): Variant update should include the id for the listeners to be able to identify the entity (#3539) * fix(medusa): Variant update should include the id for the listeners to be able to identify the entity * fix unit tests * Create brave-seahorses-film.md * docs: fix admin redirects (#3548) * chore(release): v1.7.15 * chore(docs): Generated Docs Announcement Bar (automated) (#3550) Co-authored-by: olivermrbl <olivermrbl@users.noreply.github.com> * chore(docs): Generated Services Reference (automated) (#3551) Automated changes by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> * chore: updated READMEs of plugins (#3546) * chore: updated READMEs of plugins * added notice to plugins * docs: added a deploy guide for next.js storefront (#3558) * docs: added a deploy next.js guide * docs: fix image zoom * docs: fixes to next.js deployment guide to vercel (#3562) * chore(workflows): Enable manual workflow in pre-release mode (#3566) * chore(docs): Removed Docs Announcement Bar (automated) (#3598) Co-authored-by: shahednasser <shahednasser@users.noreply.github.com> * fix(medusa): Rounding issues on line item adjustments (#3446) * chores(medusa): Attempt to fix discount rounding issues * add migration * update entities * apply multipler factor properly * fix discount service * WIP * fix rounding issues in discounts * fix some tests * Exclude raw_discount_total from responses * fix adjustments * cleanup response * fix * fix draft order integration * fix order integration * fix order integration * address feedback * fix test * Create .changeset/polite-llamas-sit.md * remove comment --------- Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> * chore(workflows): Add release notification (#3629) --------- Co-authored-by: pepijn-vanvlaanderen <pepijn@webbers.com> Co-authored-by: olivermrbl <oliver@mrbltech.com> Co-authored-by: Adrien de Peretti <adrien.deperetti@gmail.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: olivermrbl <olivermrbl@users.noreply.github.com> Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com> Co-authored-by: shahednasser <shahednasser@users.noreply.github.com> Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
11 KiB
description
| 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:
- Enable the
MEDUSA_FF_TAX_INCLUSIVE_PRICINGenvironment variable; - Or enable the
tax_inclusive_pricingkey in the Medusa backend's settings.
You can learn more about enabling it in the feature flags 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.
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_taxattribute set totrue; - Or the currency of the line item has the
includes_taxattribute set totrue; - Or a price list that includes the product variant associated with the line item has the
includes_taxattribute set totrue, 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_taxattribute set totrue, 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.
:::
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:
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. 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 or a list of products is retrieved.
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 priceoriginal_price_includes_tax: a boolean value indicating whether the amount inoriginal_priceincludes the tax amount by default or not.calculated_price_includes_tax: a boolean value indicating whether the amount incalculated_priceincludes 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_pricewill include the tax amount by default.original_price_includes_taxwill be set totrue.original_price_incl_taxwill have the same amount asoriginal_price.original_taxis 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_taxwill include the tax amount by default.calculated_price_includes_taxwill be set totrue.calculated_price_incl_taxwill have the same amount ascalculated_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:
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:
{
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.
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 inoriginal_tax_total.origial_total: Thesubtotalincluding theoriginal_tax_totalamount.
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 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.
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.
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.
An order’s totals, including its taxes, are calculated and retrieved whenever the order is retrieved both on the storefront and on the admin.
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.