Documentation You are here: start » v » 2.0 » taxes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
v:2.0:taxes [2021/10/22 20:01] – [Custom Tax Endpoint] marijav:2.0:taxes [2024/04/12 17:03] (current) – [Using 3rd Party Tax Integrations: Important Notes] foxybrett
Line 84: Line 84:
 Note that **no validation on the number is performed**.  Note that **no validation on the number is performed**. 
  
 +
 +==== Tax-Inclusive Pricing ====
 +
 +For users in countries where tax-inclusive pricing is common, Foxy allows tax-inclusive pricing. This can get a little more complicated than you might anticipate, so please test this functionality (particularly if you're using coupons and discounts) to ensure thing function as expected for your region.
 +
 +Foxy's tax-inclusive functionality is largely a //display-only// change, and is set (inclusive or exclusive) on the [[./template_sets|template set]]. (As such, you cannot display both tax-inclusive and tax-exclusive in the same cart.) The ''price'' value of your products will always be the tax-//exclusive// value.
 +
 +This is easiest to communicate by way of example. Assume an $83.33 product and a 20% tax. In both cases, the item should be ''price=83.33''. (Note that there may be situations where, due to rounding, you may need to specify a more accurate price, such as ''price=83.3333''. Foxy can handle that specificity to fix rounding issues.)
 +
 +  - In a tax-exclusive cart, the item will be displayed as $83.33, the tax will be $16.67, and the order total will be $100.
 +  - In a tax-inclusive cart, the item will be displayed as $100, the tax will be $16.67 (and will show an "inclusive" note in the heading), and the order total will still be $100.
 +
 +In that sense, this can be considered a "display only" change. All other aspects of Foxy's tax functionality remain effectively unchanged. For example, a tax-exempt customer will pay the ''price'' value of the item(s) in the cart, and it will look identical to how it'd look for a tax-exclusive cart.
 +
 +Please also review the [[./coupons_and_discounts|coupon and discount documentation]] if you're doing tax-inclusive pricing with coupons or discounts, as that has some possibilities that each individual merchant (and/or their accountants) will want to review.
  
  
Line 112: Line 127:
 We will then contact the tax database provider to alert them. Typically, the rate will then be corrected on the next monthly update. Please note that we can't guarantee whether updates will be made, but we can say from experience that updates do tend to be pretty quick. We will then contact the tax database provider to alert them. Typically, the rate will then be corrected on the next monthly update. Please note that we can't guarantee whether updates will be made, but we can say from experience that updates do tend to be pretty quick.
  
-If this uncertainty presents too significant a challenge, we do support other tax rate integrations with [[http://avatax.com/|AvaTax]], [[https://www.taxjar.com/|TaxJar]], and [[https://tax.thomsonreuters.com/products/brands/onesource/indirect-tax/|Thomson Reuters ONESOURCE Indirect]].+If this uncertainty presents too significant a challenge, we do support other tax rate integrations with [[https://offers.avalara.com/mvp/|AvaTax]], [[https://taxjar.grsm.io/foxy5141|TaxJar]], and [[https://tax.thomsonreuters.com/products/brands/onesource/indirect-tax/|Thomson Reuters ONESOURCE Indirect]].
  
  
Line 133: Line 148:
  
 ==== Using 3rd Party Tax Integrations: Important Notes ==== ==== Using 3rd Party Tax Integrations: Important Notes ====
-The following notes apply for AvaTax, TaxJar, OneSource Indirect, and any other 3rd party tax integrations that may be added to Foxy.+The following notes apply for AvaTax, TaxJar, OneSource Indirect, and any other 3rd party tax integrations that may be added to Foxy. The custom tax endpoint has similar considerations. 
 + 
 +tl;dr: 
 + 
 +  * You should only have 1 approach to taxes for your store. You should not mix an external tax provider (TaxJar, AvaTax, OneSource Indirect, custom tax endpoint) with flat rates or the built-in automatic rates. 
 +  * Only set a 3rd-party tax integration at the country level. Details below. 
 +  * You should approach the tax integration as though all products will be sent to your tax service, all the time. If you have product categories that are not taxed, you must map that category in Foxy to an untaxed product type in your tax provider. 
 + 
 +Basically, you should consider the tax provider to be the authority, and Foxy will do everything it can to ensure that system has all transaction data.
  
 === Tax Services Override Other Rates Within a Country === === Tax Services Override Other Rates Within a Country ===
 +
 If your store is configured with an AvaTax, TaxJar, or OneSource Indirect tax rate for a specific country, that provider will //always// be the authority for transactions in that country, even if the tax configuration in Foxy doesn't specify using that provider for a specific region (state, province, country, etc.). This ensures that the correct tax is charged //even if// you forgot to update your Foxy settings to match your AvaTax settings. If your store is configured with an AvaTax, TaxJar, or OneSource Indirect tax rate for a specific country, that provider will //always// be the authority for transactions in that country, even if the tax configuration in Foxy doesn't specify using that provider for a specific region (state, province, country, etc.). This ensures that the correct tax is charged //even if// you forgot to update your Foxy settings to match your AvaTax settings.
  
 For instance, if you only have a state-level tax configured in Foxy to use AvaTax for California, but you have California //and// Texas configured in AvaTax, the customer will ultimately be charged Texas sales tax, even though no taxes for Texas are configured in Foxy. This is because Foxy will always defer to AvaTax, if any AvaTax taxes are configured. Similarly, if you have another tax rate (for instance, a static rate) configured in Foxy but //not// in AvaTax, that tax will ultimately be ignored, as AvaTax is the authority. For instance, if you only have a state-level tax configured in Foxy to use AvaTax for California, but you have California //and// Texas configured in AvaTax, the customer will ultimately be charged Texas sales tax, even though no taxes for Texas are configured in Foxy. This is because Foxy will always defer to AvaTax, if any AvaTax taxes are configured. Similarly, if you have another tax rate (for instance, a static rate) configured in Foxy but //not// in AvaTax, that tax will ultimately be ignored, as AvaTax is the authority.
  
-There are three important items to note here:+There are four important items to note here:
  
   - AvaTax, TaxJar, OneSource Indirect, or other tax integrations we support should be configured at the country level. (Currently we do allow them to be configured at the state/province level, but we will be disallowing this in a future update.) <wrap tip>Note that we aren't saying you should collect taxes in all 50 states.</wrap> The tax service will know which states you should collect in.   - AvaTax, TaxJar, OneSource Indirect, or other tax integrations we support should be configured at the country level. (Currently we do allow them to be configured at the state/province level, but we will be disallowing this in a future update.) <wrap tip>Note that we aren't saying you should collect taxes in all 50 states.</wrap> The tax service will know which states you should collect in.
Line 157: Line 181:
 ==== Avalara AvaTax 15 Automatic Tax Rates ==== ==== Avalara AvaTax 15 Automatic Tax Rates ====
 If you have an Avalara account, you can add your credentials to the integrations page as shown (Here, the ''service url:'' is for a sandbox environment. If you're using an Avalara production account, you should use https://avatax.avalara.net) : If you have an Avalara account, you can add your credentials to the integrations page as shown (Here, the ''service url:'' is for a sandbox environment. If you're using an Avalara production account, you should use https://avatax.avalara.net) :
-{{ :v:2.0:avalara_integrations.png?direct |Avalara AvaTax 15 Native Integration }}+{{ :v:2.0:avalara_integrations.png?500 |Avalara AvaTax 15 Native Integration }}
  
 **Important Notes** **Important Notes**
Line 171: Line 195:
 <wrap tip>Please see the "Possible Mismatch between Displayed & Charged Taxes" section above.</wrap> <wrap tip>Please see the "Possible Mismatch between Displayed & Charged Taxes" section above.</wrap>
  
-Once your native Avalara integration is configured, you can select it as a service provider when configuring a tax+Once your native Avalara integration is configured, you can select it as a service provider when configuring a tax.
- +
-{{ :v:2.0:tax_avalara.png?direct |Avalara Tax Service Provider }}+
  
 **Address Validation** **Address Validation**
Line 230: Line 252:
    "ok":true,    "ok":true,
    "details":"",    "details":"",
-   "name":"custom tax",+   "name":"Custom Tax",
    "expand_taxes":[    "expand_taxes":[
       {       {
-         "name":"super tax",+         "name":"Super Tax",
          "rate":0.045,          "rate":0.045,
          "amount":0.23          "amount":0.23
       },       },
       {       {
-         "name":"mega tax",+         "name":"Mega Tax",
          "rate":0.053,          "rate":0.053,
          "amount":0.27          "amount":0.27
       },       },
       {       {
-         "name":"litle tax",+         "name":"Little Tax",
          "rate":0.021,          "rate":0.021,
          "amount":0.11          "amount":0.11
Line 253: Line 275:
 </code> </code>
  
-//**ok**// - show that tax was calculate normally or there is some error.+^ Attribute ^ Description ^ 
 +| ''ok'' | Show that tax was calculate normally or there is some error. 
 +| ''details'' | If you have any errors write them here. | 
 +| ''name'' | This name will be shown on the cart/checkout page. | 
 +| ''expand_taxes'' | More detail description of applied taxes, should be at least one item. These details are shown on receipt and in the admin, so if there is more than one tax included within ''expand_taxes'', they will be shown individually on the receipt and in the admin. | 
 +| ''expand_taxes.name'' | Name of the individual tax. | 
 +| ''expand_taxes.amount'' | Tax amount for the individual tax. | 
 +| ''expand_taxes.rate'' | Rate for the individual tax, as a decimal (5% is ''0.05''). | 
 +| ''total_amount'' | Total tax amount, this amount is used for adding to the total order amount. Should be the combined total of the tax ''amount''s within the ''expand_taxes'' array. | 
 +| ''total_rate'' | Total combined tax rate, as a decimal (5% is ''0.05''), shown on the cart/checkout page. Should be the combined total of the ''rate''s within the ''expand_taxes'' array. |
  
-//**details**// - if you have any errors write them here+If you want to return a successful response that has no taxes to display, you can return a payload as follows:
  
-//**name**// - this title will be on cart/checkout page+<code json> 
 +
 +    "ok": true, 
 +    "details": "", 
 +    "name": "", 
 +    "expand_taxes": [ ], 
 +    "total_amount": 0, 
 +    "total_rate":
 +
 +</code>
  
-//**total_amount**// - total tax amount, we will use this amount for calculate total order amount+An example of an error response payload is as follows. **NOTE** that this will prevent customers from checking out. Similarlyif we don't get a valid response from your custom endpoint, it will display a default error and prevent the checkout.
  
-//**total_rate**// - will show it on cart/checkout page+<code json> 
 +
 +   "ok":false, 
 +   "details":"Your error" 
 +
 +</code>
  
-//**expand_taxes**// - more detail description of applied taxesshould be at least one item. We show it on receipt page and in admin panel.+To display taxes //without a % rate// omit the ''rate'' param:  
 +<code json> 
 +
 +    "ok": true, 
 +    "details": "", 
 +    "name": "", 
 +    "expand_taxes": [ ], 
 +    "total_amount":
 +
 +</code>
  
-This functionality is in betaand more documentation will come soon.+To display 0% taxesset the rate to ''0'':  
 +<code json> 
 +
 +    "ok": true, 
 +    "details": "", 
 +    "name": "Zero Amount", 
 +    "expand_taxes":
 +        { 
 +            "name": "Tax", 
 +            "rate": 0, 
 +            "amount":
 +        } 
 +    ], 
 +    "total_amount": 0, 
 +    "total_rate":
 +
 +</code>
  
  
 +
 +=== Carts and Transactions ===
 +There are currently the following types of requests, differentiated by a header named ''foxy-webhook-event'' with the following values:
 +  * ''tax/calculate'': This is for ''cart'' resources and mostly mirrors the custom shipping endpoint (which itself looks like [[https://api.foxycart.com/rels/cart|the API's ''cart'' resource]]).
 +  * ''tax/report'': This happens when the transaction is completed, and the request body mirrors [[https://api.foxycart.com/rels/transaction|a zoomed ''transaction'' API resource]].
 +  * ''tax/refund'': Similar to ''tax/report'', but sent when a //full// refund is issued.
 +  * ''tax/void'': Identical to ''tax/refund'', but sent when a payment is voided. (For accounting or reporting purposes, this may necessitate different handling on your end.)
 +  * ''tax/update'': Similar to ''tax/report'', but sent when a //partial// refund is issued. 
 +
 +There is a separate header to indicate the trigger for the event. Currently we only have one trigger:
 +  * ''checkout/submit'': This accompanies a ''tax/calculate'' event, and will //only// be present if the customer has clicked the button to submit their checkout. In other words, this header is //not// when the cart changes, or when the checkout updates with the customer's address. It happens right before the [[./pre_payment_webhook|pre-payment webhook]].
 +
 +=== Starter Code ===
 +
 +Foxy has a Netlify function available for the Custom Tax Endpoint to help you get started. You'll need a [[https://app.netlify.com/signup|Netlify]] account, then you can follow the directions on our [[https://github.com/Foxy/foxy-node-netlify-functions/tree/main/src/functions/custom-tax-endpoint|Netlify repo]] on GitHub and follow the instructions in the readme for setting up the function.
 +
 +The repository provides an example function, which you can tailor to your needs.
  
 ===== Current Limitations and Future Improvements ===== ===== Current Limitations and Future Improvements =====
Line 273: Line 360:
 Please see the [[#using_3rd_party_tax_integrationsimportant_notes|"Using 3rd Party Tax Integrations: Important Notes" section above.]] Please see the [[#using_3rd_party_tax_integrationsimportant_notes|"Using 3rd Party Tax Integrations: Important Notes" section above.]]
  
-==== Tax-Inclusive Pricing ==== +
-While there are currently workarounds to get tax-inclusive products, [[http://requests.foxycart.com/forums/4162-general-requests/suggestions/149236-tax-inclusive-prices-tax-rates|vote for native tax-inclusive pricing support]] if that'd benefit you.+
  
 ==== Cumulative Taxes ==== ==== Cumulative Taxes ====
-Though cumulative taxes can almost always be supported (with FoxyCart's current functionality) with just a little bit of basic algebra, please [[http://requests.foxycart.com/forums/4162-general-requests/suggestions/201650-cumulative-taxes|vote for native cumulative tax functionality]] if that'd benefit you.+Though cumulative taxes can almost always be supported (with FoxyCart's current functionality) with just a little bit of basic algebra, please contact us if this is of interest to you.

Site Tools