{"id":13544737,"url":"https://github.com/valeriansaliou/node-sales-tax","last_synced_at":"2025-04-13T18:34:21.196Z","repository":{"id":37851951,"uuid":"90350995","full_name":"valeriansaliou/node-sales-tax","owner":"valeriansaliou","description":":moneybag: International sales tax calculator for Node (offline, but provides optional online VAT number fraud check). Tax rates are kept up-to-date.","archived":false,"fork":false,"pushed_at":"2025-01-06T21:18:52.000Z","size":219,"stargazers_count":318,"open_issues_count":15,"forks_count":52,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-06T15:07:45.108Z","etag":null,"topics":["billing","gst","invoice","sales","salestax","tax","vat","vatmoss"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/sales-tax","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/valeriansaliou.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"valeriansaliou"}},"created_at":"2017-05-05T07:47:56.000Z","updated_at":"2025-03-22T19:20:21.000Z","dependencies_parsed_at":"2025-01-11T11:10:59.183Z","dependency_job_id":null,"html_url":"https://github.com/valeriansaliou/node-sales-tax","commit_stats":{"total_commits":187,"total_committers":12,"mean_commits":"15.583333333333334","dds":0.08556149732620322,"last_synced_commit":"f01d3c2bfeb74252ca3b529784fa33b3bea261bc"},"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valeriansaliou%2Fnode-sales-tax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valeriansaliou%2Fnode-sales-tax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valeriansaliou%2Fnode-sales-tax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valeriansaliou%2Fnode-sales-tax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/valeriansaliou","download_url":"https://codeload.github.com/valeriansaliou/node-sales-tax/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248760936,"owners_count":21157461,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["billing","gst","invoice","sales","salestax","tax","vat","vatmoss"],"created_at":"2024-08-01T11:00:52.914Z","updated_at":"2025-04-13T18:34:21.173Z","avatar_url":"https://github.com/valeriansaliou.png","language":"JavaScript","funding_links":["https://github.com/sponsors/valeriansaliou","https://www.buymeacoffee.com/valeriansaliou"],"categories":["Calculators \u0026 Tax","VAT, Customs, and Trade"],"sub_categories":[],"readme":"# node-sales-tax\n\n[![Test and Build](https://github.com/valeriansaliou/node-sales-tax/workflows/Test%20and%20Build/badge.svg?branch=master)](https://github.com/valeriansaliou/node-sales-tax/actions?query=workflow%3A%22Test+and+Build%22) [![Build and Release](https://github.com/valeriansaliou/node-sales-tax/workflows/Build%20and%20Release/badge.svg)](https://github.com/valeriansaliou/node-sales-tax/actions?query=workflow%3A%22Build+and+Release%22) [![NPM](https://img.shields.io/npm/v/sales-tax.svg)](https://www.npmjs.com/package/sales-tax) [![Downloads](https://img.shields.io/npm/dt/sales-tax.svg)](https://www.npmjs.com/package/sales-tax) [![Buy Me A Coffee](https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg)](https://www.buymeacoffee.com/valeriansaliou)\n\nInternational sales tax calculator for Node (offline, but provides optional online VAT number fraud check). Tax rates are kept up-to-date.\n\nYou may use it to calculate VAT rates for countries in the European Union (VAT MOSS), GST in Canada, or get VAT for countries such as China, or even Hong Kong (which has no VAT).\n\nInternational tax is hard (especially VAT). This library ensures rules are enforced in the code. If you see a rule that is missing or not correctly enforced, please [open an issue](https://github.com/valeriansaliou/node-sales-tax/issues). Also, when you use the library, make sure to [specify your origin country](#white_check_mark-specify-the-country-you-charge-from); as it will return full international tax rates if you don't specify it (ie. the country you invoice your customers from).\n\n_You can find the raw sales tax rates JSON file here: [sales_tax_rates.json](https://github.com/valeriansaliou/node-sales-tax/blob/master/res/sales_tax_rates.json)_\n\n**🇺🇸 Crafted in Portland, Maine, USA.**\n\n## Who uses it?\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003ca href=\"https://crisp.chat/\"\u003e\u003cimg src=\"https://valeriansaliou.github.io/node-sales-tax/images/crisp.png\" width=\"64\" /\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ca href=\"https://locize.com/\"\u003e\u003cimg src=\"https://valeriansaliou.github.io/node-sales-tax/images/locize.png\" width=\"64\" /\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ca href=\"https://turnshift.app/\"\u003e\u003cimg src=\"https://valeriansaliou.github.io/node-sales-tax/images/turnshift.png\" width=\"64\" /\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003ca href=\"https://tally.so/\"\u003e\u003cimg src=\"https://valeriansaliou.github.io/node-sales-tax/images/tally.png\" width=\"64\" /\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eCrisp\u003c/td\u003e\n\u003ctd align=\"center\"\u003eLocize\u003c/td\u003e\n\u003ctd align=\"center\"\u003eTurnShift\u003c/td\u003e\n\u003ctd align=\"center\"\u003eTally\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n_👋 You use sales-tax and you want to be listed there? [Contact me](https://valeriansaliou.name/)._\n\n## Last changes\n\nThe version history can be found in the [CHANGELOG.md](https://github.com/valeriansaliou/node-sales-tax/blob/master/CHANGELOG.md) file.\n\n_As this library is SemVer-compatible, any breaking change would be released as a MAJOR version only. Non-breaking changes and features are released as MINOR. Tax rate updates and bug fixes are released as PATCH (note that tax rate updates may as well be bundled under a MINOR release, if it comes with new features or minor changes)._\n\n## How to install?\n\nInclude `sales-tax` in your `package.json` dependencies:\n\n```bash\nnpm install --save sales-tax\n```\n\nIf you are using TypeScript, type definitions are automatically imported.\n\n## How to use?\n\nThis module may be used to acquire the billable VAT percentage for a given customer. You may also use it directly to process the total amount including VAT you should bill; and even to validate a customer's VAT number.\n\n**:red_circle: Important: in order to fetch the sales tax for a customer, you need to know their country (and sometimes state). The country (sometimes state) must be passed to all module methods, formatted as ISO ALPHA-2 (eg. France is FR, United States is US).**\n\n### :arrow_right: Import the module\n\nImport the module in your code:\n\n`var SalesTax = require(\"sales-tax\");`\n\nEnsure that you [specify your origin country](#white_check_mark-specify-the-country-you-charge-from) before you use the library. This will affect how `worldwide`, `regional` and `national` area taxes are handled from your point of view (`regional` stands for the economic community, eg. the European Union).\n\nAlso, ensure that you consume correctly the `charge` values that get returned. It tells you if the VAT charge should be directly invoiced to the customer via the `direct` tag (you charge the VAT on your end), or if the customer should pay the VAT on their end via the `reverse` tag (see [VAT reverse charge](https://www.vatlive.com/eu-vat-rules/eu-vat-returns/reverse-charge-on-eu-vat/)). If the charge is not `direct`, then the VAT rate will be `0.00` (it is up to the customer to apply their own VAT rate).\n\n### :white_check_mark: Specify the country you charge from\n\n**Prototype:** `SalesTax.setTaxOriginCountry(countryCode\u003cstring\u003e, useRegionalTax\u003cboolean?\u003e)\u003cundefined\u003e`\n\n:fr: **Charge customers from France** if liable to VAT MOSS (thus `worldwide`, `regional` and `national` VAT gets calculated from a French point of view):\n\n```javascript\nSalesTax.setTaxOriginCountry(\"FR\")\n```\n\n:fr: **Charge customers from France** if not liable to VAT MOSS (thus `worldwide`, `regional` and `national` VAT gets calculated from a French point of view):\n\n```javascript\n// Set the 'useRegionalTax' argument to false if not liable to VAT MOSS (eg. not enough turnover in another regional country)\nSalesTax.setTaxOriginCountry(\"FR\", false)\n```\n\n:triangular_flag_on_post: **Unset your origin country** (use default origin, full VAT rates will be applied for all countries worldwide — **_this is obviously not usable for your invoices_**):\n\n```javascript\nSalesTax.setTaxOriginCountry(null)\n```\n\n### :white_check_mark: Check if a country has sales tax\n\n**Prototype:** `SalesTax.hasSalesTax(countryCode\u003cstring\u003e)\u003cboolean\u003e`\n\n**Notice: this method is origin-neutral. It means it return values regardless of your configured tax origin country.**\n\n**Check some countries for sales tax** (returns `true` or `false`):\n\n```javascript\nvar franceHasSalesTax = SalesTax.hasSalesTax(\"FR\")  // franceHasSalesTax === true\nvar brazilHasSalesTax = SalesTax.hasSalesTax(\"BR\")  // brazilHasSalesTax === true\nvar hongKongHasSalesTax = SalesTax.hasSalesTax(\"HK\")  // hongKongHasSalesTax === false\n```\n\n### :white_check_mark: Check if a state has sales tax (in a country)\n\n**Prototype:** `SalesTax.hasStateSalesTax(countryCode\u003cstring\u003e, stateCode\u003cstring\u003e)\u003cboolean\u003e`\n\n**Notice: this method is origin-neutral. It means it return values regardless of your configured tax origin country.**\n\n:canada: **Check some Canada states for sales tax** (returns `true` or `false`):\n\n```javascript\nvar canadaQuebecHasSalesTax = SalesTax.hasStateSalesTax(\"CA\", \"QC\")  // canadaQuebecHasSalesTax === true\nvar canadaYukonHasSalesTax = SalesTax.hasStateSalesTax(\"CA\", \"YT\")  // canadaYukonHasSalesTax === false\n```\n\n:us: **Check some US states for sales tax** (returns `true` or `false`):\n\n```javascript\nvar unitedStatesCaliforniaHasSalesTax = SalesTax.hasStateSalesTax(\"US\", \"CA\")  // unitedStatesCaliforniaHasSalesTax === true\nvar unitedStatesDelawareHasSalesTax = SalesTax.hasStateSalesTax(\"US\", \"DE\")  // unitedStatesDelawareHasSalesTax === false\n```\n\n### :white_check_mark: Get the sales tax for a customer\n\n**Prototype:** `SalesTax.getSalesTax(countryCode\u003cstring\u003e, stateCode\u003cstring?\u003e, taxNumber\u003cstring?\u003e)\u003cPromise\u003cobject\u003e\u003e`\n\n**Notice: this method is origin-aware. It means it return values relative to your configured tax origin country.**\n\n:fr: **Given a French customer VAT number** (eg. here `SARL CRISP IM` with VAT number `FR 50833085806`):\n\n```javascript\nSalesTax.getSalesTax(\"FR\", null, \"FR50833085806\")\n  .then((tax) =\u003e {\n    // This customer is VAT-exempt (as it is a business)\n    /* tax ===\n      {\n        type     : \"vat\",\n        rate     : 0.00,\n        currency : \"EUR\",\n        area     : \"worldwide\",\n        exchange : \"business\",\n\n        charge   : {\n          direct  : false,\n          reverse : true\n        },\n\n        details  : []\n      }\n     */\n  });\n```\n\nNote: Crisp is a real living business from France, check [their website there](https://crisp.chat/).\n\n:fr: **Given a French customer VAT number from a :fr: French tax origin** (eg. here `SARL CRISP IM` with VAT number `FR 50833085806`):\n\n```javascript\n// Set this once when initializing the library (to France)\nSalesTax.setTaxOriginCountry(\"FR\")\n\nSalesTax.getSalesTax(\"FR\", null, \"FR50833085806\")\n  .then((tax) =\u003e {\n    // This customer owes VAT in France (as it is a business, and billing is FR-to-FR)\n    // The `direct` tag is set to `true`, thus VAT should be charged\n    // The `area` tag is set to `national` as the exchange is done in France\n    /* tax ===\n      {\n        type     : \"vat\",\n        rate     : 0.20,\n        currency : \"EUR\",\n        area     : \"national\",\n        exchange : \"business\",\n\n        charge   : {\n          direct  : true,\n          reverse : false\n        },\n\n        details  : [\n          {\n            type : \"vat\",\n            rate : 0.20\n          }\n        ]\n      }\n     */\n  });\n```\n\n:fr: **Given a French customer VAT number from a :latvia: Latvian tax origin** (eg. here `SARL CRISP IM` with VAT number `FR 50833085806`):\n\n```javascript\n// Set this once when initializing the library (to Latvia)\nSalesTax.setTaxOriginCountry(\"LV\")\n\nSalesTax.getSalesTax(\"FR\", null, \"FR50833085806\")\n  .then((tax) =\u003e {\n    // This customer owes a VAT reverse charge in their country (France), no VAT is due in Latvia\n    // The `reverse` tag is set to `true`, thus the customer should apply a reverse VAT charge in their country\n    // The `area` tag is set to `regional` as the exchange is done in the European Union\n    /* tax ===\n      {\n        type     : \"vat\",\n        rate     : 0.00,\n        currency : \"EUR\",\n        area     : \"regional\",\n        exchange : \"business\",\n\n        charge   : {\n          direct  : false,\n          reverse : true\n        },\n\n        details  : []\n      }\n     */\n  });\n```\n\n:us: **Given an United States \u003e California customer without any VAT number** (eg. a consumer):\n\n```javascript\nSalesTax.getSalesTax(\"US\", \"CA\")\n  .then((tax) =\u003e {\n    // This customer has to pay 8.25% VAT (as it is a consumer)\n    /* tax ===\n      {\n        type     : \"vat\",\n        rate     : 0.0825,\n        currency : \"USD\",\n        area     : \"worldwide\",\n        exchange : \"consumer\",\n\n        charge   : {\n          direct  : true,\n          reverse : false\n        },\n\n        details  : [\n          {\n            type : \"vat\",\n            rate : 0.0825\n          }\n        ]\n      }\n     */\n  });\n```\n\n:canada: **Given a Canada \u003e Ontario customer without any VAT number** (eg. a consumer):\n\n```javascript\nSalesTax.getSalesTax(\"CA\", \"ON\")\n  .then((tax) =\u003e {\n    // This customer has to pay 5% GST + 8% HST (as it is a consumer)\n    /* tax ===\n      {\n        type     : \"gst+hst\",\n        rate     : 0.13,\n        currency : \"CAD\",\n        area     : \"worldwide\",\n        exchange : \"consumer\",\n\n        charge   : {\n          direct  : true,\n          reverse : false\n        },\n\n        details  : [\n          {\n            type : \"gst\",\n            rate : 0.05\n          },\n\n          {\n            type : \"hst\",\n            rate : 0.08\n          }\n        ]\n      }\n     */\n  });\n```\n\n:latvia: **Given a Latvian customer without any VAT number** (eg. a consumer):\n\n```javascript\nSalesTax.getSalesTax(\"LV\")\n  .then((tax) =\u003e {\n    // This customer has to pay 21% VAT (as it is a consumer)\n    /* tax ===\n      {\n        type     : \"vat\",\n        rate     : 0.21,\n        currency : \"EUR\",\n        area     : \"worldwide\",\n        exchange : \"consumer\",\n\n        charge   : {\n          direct  : true,\n          reverse : false\n        },\n\n        details  : [\n          {\n            type : \"vat\",\n            rate : 0.21\n          }\n        ]\n      }\n     */\n  });\n```\n\n:latvia: **Given a Latvian customer without any VAT number from a :fr: French tax origin** (eg. a consumer):\n\n```javascript\n// Set this once when initializing the library (to France)\nSalesTax.setTaxOriginCountry(\"FR\")\n\nSalesTax.getSalesTax(\"LV\")\n  .then((tax) =\u003e {\n    // This customer owes VAT in Latvia (as it is a consumer, and billing is FR-to-LV)\n    // The `direct` tag is set to `true`, thus VAT should be charged\n    // The `area` tag is set to `regional` as the exchange is done in the European Union\n    /* tax ===\n      {\n        type     : \"vat\",\n        rate     : 0.21,\n        currency : \"EUR\",\n        area     : \"regional\",\n        exchange : \"consumer\",\n\n        charge   : {\n          direct  : true,\n          reverse : false\n        },\n\n        details  : [\n          {\n            type : \"vat\",\n            rate : 0.21\n          }\n        ]\n      }\n     */\n  });\n```\n\n:hong_kong: **Given an Hong Kong-based customer** (eg. a consumer):\n\n```javascript\nSalesTax.getSalesTax(\"HK\")\n  .then((tax) =\u003e {\n    // Hong Kong has no VAT\n    /* tax ===\n      {\n        type     : \"none\",\n        rate     : 0.00,\n        currency : null,\n        area     : \"worldwide\",\n        exchange : \"consumer\",\n\n        charge   : {\n          direct  : false,\n          reverse : false\n        },\n\n        details  : []\n      }\n     */\n  });\n```\n\n:es: **Given a Spanish customer who provided an invalid VAT number** (eg. a rogue business):\n\n```javascript\nSalesTax.getSalesTax(\"ES\", null, \"ESX12345523\")\n  .then((tax) =\u003e {\n    // This customer has to pay 21% VAT (VAT number could not be authenticated against the VIES VAT API)\n    /* tax ===\n      {\n        type     : \"vat\",\n        rate     : 0.21,\n        currency : \"EUR\",\n        area     : \"worldwide\",\n        exchange : \"consumer\",\n\n        charge   : {\n          direct  : true,\n          reverse : false\n        },\n\n        details  : [\n          {\n            type : \"vat\",\n            rate : 0.21\n          }\n        ]\n      }\n     */\n  });\n```\n\n### :white_check_mark: Process the price including sales tax for a customer\n\n**Prototype:** `SalesTax.getAmountWithSalesTax(countryCode\u003cstring\u003e, stateCode\u003cstring?\u003e, amount\u003cnumber?\u003e, taxNumber\u003cstring?\u003e)\u003cPromise\u003cobject\u003e\u003e`\n\n**Notice: this method is origin-aware. It means it return values relative to your configured tax origin country.**\n\n:estonia: **Given an Estonian customer without any VAT number, buying 100.00€ of goods** (eg. a consumer):\n\n```javascript\nSalesTax.getAmountWithSalesTax(\"EE\", null, 100.00)\n  .then((amountWithTax) =\u003e {\n    // This customer has to pay 20% VAT\n    /* amountWithTax ===\n      {\n        type     : \"vat\",\n        rate     : 0.20,\n        currency : \"EUR\",\n        price    : 100.00,\n        total    : 120.00,\n        area     : \"worldwide\",\n        exchange : \"consumer\",\n\n        charge   : {\n          direct  : true,\n          reverse : false\n        },\n\n        details  : [\n          {\n            type   : \"vat\",\n            rate   : 0.20,\n            amount : 20.00\n          }\n        ]\n      }\n     */\n  });\n```\n\n### :white_check_mark: Validate tax number for a customer\n\n**Prototype:** `SalesTax.validateTaxNumber(countryCode\u003cstring\u003e, taxNumber\u003cstring?\u003e)\u003cPromise\u003cboolean\u003e\u003e`\n\n:fr: **Given a French customer VAT number** (eg. here `SARL CRISP IM` with VAT number `FR 50833085806`):\n\n```javascript\nSalesTax.validateTaxNumber(\"FR\", \"FR50833085806\")\n  .then((isValid) =\u003e {\n    // isValid === true\n  });\n```\n\n:us: **Given an United States customer without any VAT number** (eg. a consumer):\n\n```javascript\nSalesTax.validateTaxNumber(\"US\")\n  .then((isValid) =\u003e {\n    // isValid === false\n  });\n```\n\n:latvia: **Given a Latvian customer without any VAT number** (eg. a consumer):\n\n```javascript\nSalesTax.validateTaxNumber(\"LV\")\n  .then((isValid) =\u003e {\n    // isValid === false\n  });\n```\n\n:es: **Given a Spanish customer who provided an invalid VAT number** (eg. a rogue business):\n\n```javascript\nSalesTax.validateTaxNumber(\"ES\", \"ESX12345523\")\n  .then((isValid) =\u003e {\n    // isValid === false\n  });\n```\n\n### :white_check_mark: Get tax exchange status for a customer (exempt + area + exchange)\n\n**Prototype:** `SalesTax.getTaxExchangeStatus(countryCode\u003cstring\u003e, stateCode\u003cstring?\u003e, taxNumber\u003cstring?\u003e)\u003cPromise\u003cobject\u003e\u003e`\n\n**Notice: this method is origin-aware. It means it return values relative to your configured tax origin country.**\n\n:fr: **Given a French customer VAT number** (eg. here `SARL CRISP IM` with VAT number `FR 50833085806`):\n\n```javascript\nSalesTax.getTaxExchangeStatus(\"FR\", null, \"FR50833085806\")\n  .then((exchangeStatus) =\u003e {\n    /* exchangeStatus ===\n      {\n        exchange : \"business\",\n        area     : \"worldwide\",\n        exempt   : true\n      }\n     */\n  });\n```\n\n:morocco: **Given a Morocco-based customer**:\n\n```javascript\nSalesTax.getTaxExchangeStatus(\"MA\")\n  .then((exchangeStatus) =\u003e {\n    /* exchangeStatus ===\n      {\n        exchange : \"consumer\",\n        area     : \"worldwide\",\n        exempt   : false\n      }\n     */\n  });\n```\n\n:us: **Given an United States \u003e Delaware-based customer**:\n\n```javascript\nSalesTax.getTaxExchangeStatus(\"US\", \"DE\")\n  .then((exchangeStatus) =\u003e {\n    /* exchangeStatus ===\n      {\n        exchange : \"consumer\",\n        area     : \"worldwide\",\n        exempt   : true\n      }\n     */\n  });\n```\n\n:hong_kong: **Given an Hong Kong-based customer**:\n\n```javascript\nSalesTax.getTaxExchangeStatus(\"HK\")\n  .then((exchangeStatus) =\u003e {\n    /* exchangeStatus ===\n      {\n        exchange : \"consumer\",\n        area     : \"worldwide\",\n        exempt   : true\n      }\n     */\n  });\n```\n\n### :white_check_mark: Disable / enable tax number validation\n\n**Prototype:** `SalesTax.toggleEnabledTaxNumberValidation(enabled\u003cboolean\u003e)\u003cundefined\u003e`\n\n:thumbsup: **Enable tax number validation** (enabled by default — use only if you disabled it previously):\n\n```javascript\nSalesTax.toggleEnabledTaxNumberValidation(true)\n```\n\n:thumbsdown: **Disable tax number validation** (do not check tax number syntax):\n\n```javascript\nSalesTax.toggleEnabledTaxNumberValidation(false)\n```\n\n### :white_check_mark: Disable / enable tax number fraud check\n\n**Prototype:** `SalesTax.toggleEnabledTaxNumberFraudCheck(enabled\u003cboolean\u003e)\u003cundefined\u003e`\n\n**Notice: fraud check requires tax number validation to be enabled.**\n\n:thumbsup: **Enable tax number fraud check** (enable hitting against external APIs to verify tax numbers against fraud):\n\n```javascript\nSalesTax.toggleEnabledTaxNumberFraudCheck(true)\n```\n\n:thumbsdown: **Disable tax number fraud check** (disabled by default — use only if you enabled it previously):\n\n```javascript\nSalesTax.toggleEnabledTaxNumberFraudCheck(false)\n```\n\n## Where is the offline tax data pulled from?\n\nThe offline data contained in the `sales-tax` library comes from different sources:\n\n- Tax data is pulled from [Value-added tax (VAT) rates — PwC](http://taxsummaries.pwc.com/ID/Value-added-tax-(VAT)-rates) (last updated: 27th June 2023).\n- Country currencies are pulled from: [Detailed Territory-Currency Information — Unicode](https://www.unicode.org/cldr/charts/42/supplemental/detailed_territory_currency_information.html) (last updated: 27th July 2023).\n\n**It is kept up-to-date year-by-year with tax changes worldwide.**\n\nSome countries have multiple sales tax, eg. Brazil. In those cases, the returned sales tax is the one on services. Indeed, I consider most users of this module use it for their SaaS business — _in other words, service businesses._\n\n## What happens if a country or state schedules a tax rate change?\n\nAs tax rate changes happen to some countries in the word on a yearly basis, `sales-tax` automatically uses the current tax rate relative to current date and time, ie. whenever you call the library functions.\n\nAt a technical level, tax rate changes for a country can be easily scheduled from the [tax rates JSON file](https://github.com/valeriansaliou/node-sales-tax/blob/master/res/sales_tax_rates.json) by moving the current tax rate in a `before` object, which then stores the country tax rate before enforcement date, and then the future tax rate is stored in the main object. Note that as a library user, you do not have to schedule tax rate changes, `sales-tax` handles it for you automatically.\n\nPlease make sure you always keep `sales-tax` up-to-date with the latest NPM version, as those tax rate changes are stored in an offline JSON file, which requires a manual library update.\n\n_For instance, Germany changed their VAT rate from 19% down to 16% as of 1st July 2020:_\n\n```json\n\"DE\": {\n  \"type\": \"vat\",\n  \"rate\": 0.16,\n  \"currency\": \"EUR\",\n\n  \"before\": {\n    \"2020-06-30T22:00:00.000Z\": {\n      \"type\": \"vat\",\n      \"rate\": 0.19,\n      \"currency\": \"EUR\"\n    }\n  }\n}\n```\n\n## I bill from the EU, but sales tax is still being returned for non-EU countries!\n\nAs international tax rules can be **very complex** depending on your business legal structure (eg. if you run a nexus in an US state, you may owe sales tax to this US state, even if you charge from the UK); `sales-tax` does not void returned tax rate for `worldwide` countries.\n\nThus, when the country is `worldwide` relative to your billing origin country, you need to handle things your own way.\n\nTo make things easier for you, `sales-tax` returns an `area` parameter in the `SalesTax.getSalesTax`, that is either `worldwide`, `regional` or `national` (this depends on your configured origin country). For `regional` and `national` areas, you can trust the returned rate. However, you may need to override all `worldwide` area rates and void them all to zero; for instance if you charge from France to the United States, and you know that you do not owe sales tax in the US as you do not run a nexus company in the US.\n\n⚠️ **Note that this would also apply to non-EU businesses charging customers outside of their jurisdiction.** For instance, an Australian business would not charge VAT for customers outside of the country, yet it would charge VAT for all Australian customers. Yet, VAT might be returned by `sales-tax` for such international charges (ie. `worldwide` area). Therefore, such a `worldwide` area VAT should be voided if you consider that this does not apply to you, while `national` or `regional` area VAT should be used as normal. Always check with your accountant when in doubt.\n\n## How are tax numbers validated?\n\n### :eu: Europe\n\nEuropean VAT numbers can be fraud-checked against the official `ec.europa.eu` VIES VAT API, which return whether a given VAT number exists or not. This helps you ensure a customer-provided VAT number really exists. This feature, as it may incur significant delays (while querying the VIES VAT API) is disabled by default. There's [a switch to enable it](#white_check_mark-disable--enable-tax-number-fraud-check).\n\nIn all cases, the syntax of the European VAT numbers get validated from offline rules. Although, it only checks number syntaxical correctness; thus it is not sufficient to tell if the number exists or not.\n\nYou can manually check a VAT number on [VIES VAT number validation](http://ec.europa.eu/taxation_customs/vies/vatRequest.html).\n\n### :us: United States\n\nUnited States EIN (U.S. Employer Identification Number) are validated against EIN format rules.\n\n### :canada: Canada\n\nCanada BN (Business Number) are validated against BN format rules.\n\n### :black_flag: Rest of the world\n\nIf a country or economic community is not listed here, provided tax identification numbers are ignored for those countries (considered as invalid — so do not rely on validation methods as a source of truth).\n\n_If you need tax number validation for a missing country, feel free to submit a Pull Request._\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvaleriansaliou%2Fnode-sales-tax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvaleriansaliou%2Fnode-sales-tax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvaleriansaliou%2Fnode-sales-tax/lists"}