Code Monkey home page Code Monkey logo

taxjar-node's Introduction

TaxJar Sales Tax API for Node NPM Module Build Status Known Vulnerabilities

Official Node client for Sales Tax API v2. For the API documentation, please visit https://developers.taxjar.com/api/reference/.


Requirements
Installation
Authentication
Usage
Custom Options
Sandbox Environment
Error Handling
Testing


Requirements

  • Node.js v10.0 and later.

Installation

npm install taxjar

Authentication

// CommonJS Import
const Taxjar = require('taxjar');

// ES6 Import
// Using TypeScript? Pass `esModuleInterop` in tsconfig.json
// https://www.typescriptlang.org/docs/handbook/compiler-options.html
import Taxjar from 'taxjar';

const client = new Taxjar({
  apiKey: process.env.TAXJAR_API_KEY
});

Warning: Never expose your API token in client-side JavaScript. This is insecure and could put your TaxJar account at risk.

You're now ready to use TaxJar! Check out our quickstart guide to get up and running quickly.

Usage

categories - List all tax categories
taxForOrder - Calculate sales tax for an order
listOrders - List order transactions
showOrder - Show order transaction
createOrder - Create order transaction
updateOrder - Update order transaction
deleteOrder - Delete order transaction
listRefunds - List refund transactions
showRefund - Show refund transaction
createRefund - Create refund transaction
updateRefund - Update refund transaction
deleteRefund - Delete refund transaction
listCustomers - List customers
showCustomer - Show customer
createCustomer - Create customer
updateCustomer - Update customer
deleteCustomer - Delete customer
ratesForLocation - List tax rates for a location (by zip/postal code)
nexusRegions - List nexus regions
validateAddress - Validate an address
validate - Validate a VAT number
summaryRates - Summarize tax rates for all regions


List all tax categories (API docs)

The TaxJar API provides product-level tax rules for a subset of product categories. These categories are to be used for products that are either exempt from sales tax in some jurisdictions or are taxed at reduced rates. You need not pass in a product tax code for sales tax calculations on product that is fully taxable. Simply leave that parameter out.

client.categories().then(res => {
  res.categories; // Array of categories
});

Calculate sales tax for an order (API docs)

Shows the sales tax that should be collected for a given order.

client.taxForOrder({
  from_country: 'US',
  from_zip: '07001',
  from_state: 'NJ',
  from_city: 'Avenel',
  from_street: '305 W Village Dr',
  to_country: 'US',
  to_zip: '07446',
  to_state: 'NJ',
  to_city: 'Ramsey',
  to_street: '63 W Main St',
  amount: 16.50,
  shipping: 1.5,
  line_items: [
    {
      id: '1',
      quantity: 1,
      product_tax_code: '31000',
      unit_price: 15.0,
      discount: 0
    }
  ]
}).then(res => {
  res.tax; // Tax object
  res.tax.amount_to_collect; // Amount to collect
});

List order transactions (API docs)

Lists existing order transactions created through the API.

client.listOrders({
  from_transaction_date: '2015/05/01',
  to_transaction_date: '2015/05/31'
}).then(res => {
  res.orders; // Orders object
});

Show order transaction (API docs)

Shows an existing order transaction created through the API.

client.showOrder('123').then(res => {
  res.order; // Order object
});

Create order transaction (API docs)

Creates a new order transaction.

client.createOrder({
  transaction_id: '123',
  transaction_date: '2015/05/14',
  from_country: 'US',
  from_zip: '92093',
  from_state: 'CA',
  from_city: 'La Jolla',
  from_street: '9500 Gilman Drive',
  to_country: 'US',
  to_zip: '90002',
  to_state: 'CA',
  to_city: 'Los Angeles',
  to_street: '123 Palm Grove Ln',
  amount: 17.45,
  shipping: 1.5,
  sales_tax: 0.95,
  line_items: [
    {
      id: '1',
      quantity: 1,
      product_identifier: '12-34243-9',
      description: 'Fuzzy Widget',
      unit_price: 15.0,
      discount: 0,
      sales_tax: 0.95
    }
  ]
}).then(res => {
  res.order; // Order object
});

Update order transaction (API docs)

Updates an existing order transaction created through the API.

client.updateOrder({
  transaction_id: '123',
  amount: 17.45,
  shipping: 1.5,
  line_items: [
    {
      quantity: 1,
      product_identifier: '12-34243-0',
      description: 'Heavy Widget',
      unit_price: 15.0,
      discount: 0.0,
      sales_tax: 0.95
    }
  ]
}).then(res => {
  res.order; // Order object
});

Delete order transaction (API docs)

Deletes an existing order transaction created through the API.

client.deleteOrder('123').then(res => {
  res.order; // Order object
});

List refund transactions (API docs)

Lists existing refund transactions created through the API.

client.listRefunds({
  from_transaction_date: '2015/05/01',
  to_transaction_date: '2015/05/31'
}).then(res => {
  res.refunds; // Refunds object
});

Show refund transaction (API docs)

Shows an existing refund transaction created through the API.

client.showRefund('123-refund').then(res => {
  res.refund; // Refund object
});

Create refund transaction (API docs)

Creates a new refund transaction.

client.createRefund({
  transaction_id: '123-refund',
  transaction_reference_id: '123',
  transaction_date: '2015/05/14',
  from_country: 'US',
  from_zip: '92093',
  from_state: 'CA',
  from_city: 'La Jolla',
  from_street: '9500 Gilman Drive',
  to_country: 'US',
  to_zip: '90002',
  to_state: 'CA',
  to_city: 'Los Angeles',
  to_street: '123 Palm Grove Ln',
  amount: -17.45,
  shipping: -1.5,
  sales_tax: -0.95,
  line_items: [
    {
      id: '1',
      quantity: 1,
      product_identifier: '12-34243-9',
      description: 'Fuzzy Widget',
      unit_price: -15.0,
      discount: -0,
      sales_tax: -0.95
    }
  ]
}).then(res => {
  res.refund; // Refund object
});

Update refund transaction (API docs)

Updates an existing refund transaction created through the API.

client.updateRefund({
  transaction_id: '123-refund',
  transaction_reference_id: '123',
  amount: -17.95,
  shipping: -2.0,
  line_items: [
    {
      id: '1',
      quantity: 1,
      product_identifier: '12-34243-0',
      description: 'Heavy Widget',
      unit_price: -15.0,
      discount: -0,
      sales_tax: -0.95
    }
  ]
}).then(res => {
  res.refund; // Refund object
});

Delete refund transaction (API docs)

Deletes an existing refund transaction created through the API.

client.deleteRefund('123-refund').then(res => {
  res.refund; // Refund object
});

List customers (API docs)

Lists existing customers created through the API.

client.listCustomers().then(res => {
  res.customers; // Customers object
});

Show customer (API docs)

Shows an existing customer created through the API.

client.showCustomer('123').then(res => {
  res.customer; // Customer object
});

Create customer (API docs)

Creates a new customer.

client.createCustomer({
  customer_id: '123',
  exemption_type: 'wholesale',
  name: 'Dunder Mifflin Paper Company',
  exempt_regions: [
    {
      country: 'US',
      state: 'FL'
    },
    {
      country: 'US',
      state: 'PA'
    }
  ],
  country: 'US',
  state: 'PA',
  zip: '18504',
  city: 'Scranton',
  street: '1725 Slough Avenue'
}).then(res => {
  res.customer; // Customer object
});

Update customer (API docs)

Updates an existing customer created through the API.

client.updateCustomer({
  customer_id: '123',
  exemption_type: 'wholesale',
  name: 'Sterling Cooper',
  exempt_regions: [
    {
      country: 'US',
      state: 'NY'
    }
  ],
  country: 'US',
  state: 'NY',
  zip: '10010',
  city: 'New York',
  street: '405 Madison Ave'
}).then(res => {
  res.customer; // Customer object
});

Delete customer (API docs)

Deletes an existing customer created through the API.

client.deleteCustomer('123').then(res => {
  res.customer; // Customer object
});

List tax rates for a location (by zip/postal code) (API docs)

Shows the sales tax rates for a given location.

Please note this method only returns the full combined rate for a given location. It does not support nexus determination, sourcing based on a ship from and ship to address, shipping taxability, product exemptions, customer exemptions, or sales tax holidays. We recommend using taxForOrder to accurately calculate sales tax for an order.

client.ratesForLocation('90002').then(res => {
  res.rate; // Rate object
});

List nexus regions (API docs)

Lists existing nexus locations for a TaxJar account.

client.nexusRegions().then(res => {
  res.regions; // Array of nexus regions
});

Validate an address (API docs)

Validates a customer address and returns back a collection of address matches. Address validation requires a TaxJar Plus subscription.

client.validateAddress({
  country: 'US',
  state: 'AZ',
  zip: '85297',
  city: 'Gilbert',
  street: '3301 South Greenfield Rd'
}).then(res => {
  res.addresses; // Array of address matches
});

Validate a VAT number (API docs)

Validates an existing VAT identification number against VIES.

client.validate({
  vat: 'FR40303265045'
}).then(res => {
  res.validation; // Validation object
});

Summarize tax rates for all regions (API docs)

Retrieve minimum and average sales tax rates by region as a backup.

This method is useful for periodically pulling down rates to use if the TaxJar API is unavailable. However, it does not support nexus determination, sourcing based on a ship from and ship to address, shipping taxability, product exemptions, customer exemptions, or sales tax holidays. We recommend using taxForOrder to accurately calculate sales tax for an order.

client.summaryRates().then(res => {
  res.summary_rates; // Array of summarized rates
});

Custom Options

API Version

By default, TaxJar's API will respond to requests with the latest API version when a version header is not present on the request.

To request a specific API version, include the x-api-version header with the desired version string.

client.setApiConfig('headers', {
  'x-api-version': '2020-08-07'
});

Sandbox Environment

You can easily configure the client to use the TaxJar Sandbox:

// CommonJS Import
const Taxjar = require('taxjar');

// ES6 Import
import Taxjar from 'taxjar';

const client = new Taxjar({
  apiKey: process.env.TAXJAR_SANDBOX_API_KEY,
  apiUrl: Taxjar.SANDBOX_API_URL
});

For testing specific error response codes, pass the custom X-TJ-Expected-Response header:

client.setApiConfig('headers', {
  'X-TJ-Expected-Response': '422'
});

Error Handling

client.taxForOrder({
  from_country: 'US',
  from_zip: '07001',
  from_state: 'NJ',
  from_city: 'Avenel',
  from_street: '305 W Village Dr',
  to_country: 'US',
  to_zip: '07446',
  to_state: 'NJ',
  to_city: 'Ramsey',
  to_street: '63 W Main St',
  amount: 16.50,
  shipping: 1.5,
  line_items: [
    {
      id: '1',
      quantity: 1,
      product_tax_code: '31000',
      unit_price: 15.0,
      discount: 0,
      sales_tax: 0.95
    }
  ]
}).then(res => {
  res.tax; // Tax object
  res.tax.amount_to_collect; // Amount to collect
}).catch(err => {
  err.detail; // Error detail
  err.status; // Error status code
});

In TypeScript, you may want to first check the error's type before handling:

client.taxForOrder(/* ... */)
  .catch(err => {
    if (err instanceof Taxjar.Error) {
      err.detail; // Error detail
      err.status; // Error status code
    } else {
      // handle non-taxjar error
    }
  });

Testing

npm test

To validate API methods in the TaxJar sandbox environment, pass the following environment variables:

TAXJAR_API_URL="https://api.sandbox.taxjar.com" \
TAXJAR_API_KEY="9e0cd62a22f451701f29c3bde214" \
npm test

taxjar-node's People

Contributors

dallendalton avatar dependabot[bot] avatar dkulchenko avatar eboswort avatar fastdivision avatar jordan-k-johnson avatar saiichihashimoto avatar scottrudiger avatar sethobey avatar smolentzov-stripe avatar squirly avatar strmer15 avatar tizol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

taxjar-node's Issues

Incorrect type for TaxForOrderRes.tax.jurisdictions

According to the Taxjar API docs, the POST /v2/taxes endpoint returns a tax object with jurisdictions property which contains an object with key, value pairs.

Screen Shot 2021-01-25 at 2 26 22 PM

Screen Shot 2021-01-25 at 2 26 28 PM

However, the TaxForOrderRes.tax.jurisdictions type definition in this module contradicts the API docs (and the live results in my experience) by declaring this value contains an array of jurisdiction objects.

Screen Shot 2021-01-25 at 2 30 52 PM

Is this type definition wrong? Should the [] at the end of the type deceleration by omitted?

Still getting "shipping is missing" using PHP taxjar

shipping is a decimal and is set in the passed object.
result from taxForOrder() is '406 Not Acceptable – shipping is missing'
Json data:
{"from_country":"US", "from_zip":"02125", "from_state":"MA", "from_city":"Boston", "from_street":"Boston street", "to_country":"US", "to_zip":"97221", "to_state":"MA", "to_city":"Boston", "to_street":"44 Main street", "amount":30.5, "shipping":2, "line_items":[{"id":"12", "quantity":1, "product_tax_code":"", "unit_price":24, "discount":0}, {"id":"247", "quantity":1, "product_tax_code":"", "unit_price":1.5, "discount":0}]}

Saw note about Mar 22 issue and response was to update to newer version. Composer is using:
{ "require": { "taxjar/taxjar-php": "^1.7" } }

Sorry, new to taxjar so not sure how to handle a parameter that is set but response says it's not.

No Changelog/History

I can't find a changelog or release notes for any versions of this library so it's difficult to verify additions/changes to the library when updating my deps. The only thing I can find at all are API notes on the TaxJar website but those are labelled by date and don't correspond to this library's version scheme.

I'm guessing there are no compatibility changes but it's nice to be able to have a version history available.

Consider exposing TaxJar Types definitions.

I'm using Typescript (4.0.5) and since I don't want to import them directly from the dist directory like proposed in this issue.
I really don't feel comfortable with this approach since the dist folder is typically used for the transpiled files and importing from there could lead to some reliability issues.

It would be nice to have those Types definitions exposed for us to use when importing the package.

Thanks!

How to access TaxjarTypes?

I can see from the source code that there are plenty of useful types available in TaxjarTypes. Alas, I cannot seem to access them...

I am using TypeScript 3.9.5, NodeJS 10, and I have the recommended import:

import Taxjar from "taxjar";

How can I access things like TaxParams and LineItem?

(Not Urgent) Improve Performance of CI

This is not urgent but something to keep in mind when there's time. Feel free to skip this for now.

There's a few ways we could improve performance for running builds in Travis CI.

  1. Currently, npm's prepublish script is being used to build before publishing. However, this causes CI to build dist/ twice for each node version: once on npm install and again on npm test.

Screen Shot 2019-04-27 at 3 00 06 PM
Screen Shot 2019-04-27 at 3 00 38 PM
(Note that tsc runs twice.)

This is because of the behavior of prepublish. It triggers whenever npm install is run within the project and on npm publish.

  • If we change it to prepublishOnly, then CI will only build once (before running tests) and the behavior of building before npm publish will be unchanged. (Note: the maintainer who publishes will need at least [email protected] for prepublishOnly to work.)

You can see the behavior by checking out this commit:

git fetch https://github.com/ScottRudiger/taxjar-node.git 02d0051c00d7323cd81907e33ab05f3eef539e4b:ci/improve-perf
git checkout ci/improve-perf
rm -r node_modules
npm install # no longer builds 'dist/'
npm test # still builds 'dist/'
npm publish --dry-run # still builds 'dist/'
  • Or, we could go even further and make it so CI still performs tests on dist/ but for a slightly better DX make it so dist/ is never built locally for common development tasks such as testing.

Here's a proof of concept. Mocha uses ts-node/register to compile for tests without building dist/ locally. But Travis CI sets the env var CI=true so the script

"test": "if [ $CI ]; then tsc && mocha; else mocha -r ts-node/register; fi"

should cause Travis to still build and test against dist/. (If we go ahead with this change, we can make this cleaner by instead defining that behavior in .travis.yml.)

Check it out locally with:

git checkout master
git branch -D ci/improve-perf
git fetch https://github.com/ScottRudiger/taxjar-node.git 91903275241833b887b0b0e06704b734dc4ed0c8:ci/improve-perf
git checkout ci/improve-perf
rm -r dist
npm install # no longer builds 'dist/'
npm test # no longer builds 'dist/'
CI=true npm test # builds 'dist/'
npm publish --dry-run # still builds 'dist/'
  1. Skip non-LTS versions of Node.

Instead of 4 through 10 we could skip the non-LTS Node versions for testing, except the latest. I think it’d be 6, 8, 10, 11 and maybe 12 since it was released a few days ago. Of course, we could keep 4 even though it’s out of LTS. The main idea is to skip 5, 7, and 9 to speed up the build.

  1. Also, look into having Travis cache node_modules or use npm cit on versions where it’s available.

  2. Other than that, I thought it might be useful to run eslint in the latest Node version and exit early if there are any linting errors. That should speed up CI significantly in those cases.

Consider passing `detail` as the error message

A lot of Node tooling (e.g. logging services, verror etc.) expect a message on an error object however this lib just instantiates an Error without a message here: https://github.com/taxjar/taxjar-node/blob/master/lib/util/request.ts#L30

It would be useful if detail was the message, e.g. new Error(`TaxJar: ${result.error.detail}`)

Additionally does TaxJar's API return error codes as, at least this package appears to just return dynamic error messaging:

{
  stack: '...',
  error: 'Bad Request',
  detail: 'to_zip 90210 is not used within to_state CALIFORNIA',
  status: 400
}

I'd like to see something like code: 'invalid_zip' so we can present localised error messaging on our frontend as it wouldn't be feasible to do so with detail because it's dynamic?

Promise.defer is deprecated warning

Defer is deprecated in Bluebird. I get the following warning:

Warning: Promise.defer is deprecated and will be removed in a future version. Use new Promise instead.

TaxjarError: undefined - undefined

We just started to use TaxJar trial.

On a local machine, all went fine, it’s working. But when we deployed it to GCP k8s, taxjar started throwing a strange error

No details at all.

{
detail: undefined, 
error: undefined, 
message: undefined - undefined, 
name: TaxjarError, 
stack: 
TaxjarError: undefined - undefined
    at proxyError (/home/node/app/node_modules/taxjar/dist/util/request.js:6:11)
, 
status: undefined
}

We use only .taxForOrder method.

package version "taxjar": "3.1.0"

Return types

Currently all methods return any, meaning we have to define your backend's responses on our end (with our own checks to make sure our documentation-based assumptions are actually correct) to have type-safety. Any plans to support this?

Unhandled rejection Error

i have problems with the new update. i get an anonymous error on node_modules/taxjar/lib/util/request.js:25:30. This problem only happens with the new version on taxjar, if i used a previous version works fine.

Unhandled rejection Error at Request.<anonymous> (/home/vagrant/vcoplayer/node_modules/taxjar/lib/util/request.js:25:30) at emitTwo (events.js:100:13) at Request.emit (events.js:185:7) at Request.mixin._fireSuccess (/home/vagrant/vcoplayer/node_modules/restler/lib/restler.js:229:10) at /home/vagrant/vcoplayer/node_modules/restler/lib/restler.js:161:20 at IncomingMessage.parsers.json (/home/vagrant/vcoplayer/node_modules/restler/lib/restler.js:415:9) at IncomingMessage.parsers.auto (/home/vagrant/vcoplayer/node_modules/restler/lib/restler.js:400:21) at Request.mixin._encode (/home/vagrant/vcoplayer/node_modules/restler/lib/restler.js:198:29) at /home/vagrant/vcoplayer/node_modules/restler/lib/restler.js:157:16 at Request.mixin._decode (/home/vagrant/vcoplayer/node_modules/restler/lib/restler.js:173:7) at IncomingMessage.<anonymous> (/home/vagrant/vcoplayer/node_modules/restler/lib/restler.js:150:14) at emitNone (events.js:85:20) at IncomingMessage.emit (events.js:179:7) at endReadableNT (_stream_readable.js:913:12) at _combinedTickCallback (internal/process/next_tick.js:74:11) From previous event: at Object.Request.api (/home/vagrant/vcoplayer/node_modules/taxjar/lib/util/request.js:14:12) at Object.Taxjar.taxForOrder (/home/vagrant/vcoplayer/node_modules/taxjar/lib/taxjar.js:47:25) at next (/home/vagrant/vcoplayer/server/lib/checkout/index.js:135:10) at /home/vagrant/vcoplayer/server/controllers/checkout/calculateTaxes.js:18:4 at /home/vagrant/vcoplayer/server/models/user.js:214:11 at Query.<anonymous> (/home/vagrant/vcoplayer/node_modules/mongoose/lib/model.js:3407:16) at /home/vagrant/vcoplayer/node_modules/kareem/index.js:259:21 at /home/vagrant/vcoplayer/node_modules/kareem/index.js:127:16 at _combinedTickCallback (internal/process/next_tick.js:67:7) at process._tickCallback (internal/process/next_tick.js:98:9)

406 (Not Acceptable) shipping is missing

Hi, I'm trying an example from the doc and get the error (406 (Not Acceptable) shipping is missing)...

const Taxjar = require('taxjar');

const client = new Taxjar({
  apiKey: '9e0cd62a22f451701f29c3bde214'
});

client.taxForOrder({
  from_country: 'US',
  from_zip: '92093',
  from_state: 'CA',
  from_city: 'La Jolla',
  from_street: '9500 Gilman Drive',
  to_country: 'US',
  to_zip: '90002',
  to_state: 'CA',
  to_city: 'Los Angeles',
  to_street: '1335 E 103rd St',
  amount: 15,
  shipping: 1.5,
  nexus_addresses: [
    {
      id: 'Main Location',
      country: 'US',
      zip: '92093',
      state: 'CA',
      city: 'La Jolla',
      street: '9500 Gilman Drive'
    }
  ],
  line_items: [
    {
      id: '1',
      quantity: 1,
      product_tax_code: '20010',
      unit_price: 15,
      discount: 0
    }
  ]
}).then(res => {
  res.tax; // Tax object
  res.tax.amount_to_collect; // Amount to collect
});

Access blocked by CORS Policy

Trying to use the sales tax api and my requests are failing due to No 'Access-Control-Allow-Origin' header is present on the requested resource.

Screen Shot 2019-06-04 at 10 35 59 AM

Screen Shot 2019-06-04 at 10 34 19 AM

Warning: a promise was rejected with a non-error: [object String]

Warning raised when API key is wrong

screen shot 2016-12-01 at 3 53 59 pm
....

API Needs better error handling

Expanded image with full warning 1

Expanded image with full warning 2

Suggestions

https://github.com/danwrong/restler

rest.get('http://google.com').on('complete', function(result) {
  if (result instanceof Error) {
    console.log('Error:', result.message);
    this.retry(5000); // try again after 5 sec
  } else {
    console.log(result);
  }
});

petkaantonov/bluebird#990

if (result.error) {
  const proxiedError = new Error();
  proxiedError.error = result.error.error;
  proxiedError.detail = result.error.detail;
  proxiedError.status = result.error.status;
  reject(proxiedError);
} else {
  resolve(result);
}

https://github.com/danwrong/restler

complete: function(result, response){
  ... 
}

Consider adding setApiConfig header documentation to readme

Received an email saying I had to add x-api-version to the header... in the readme I couldn't see anything about / where or how to set this... but figured it out in the end.

client.setApiConfig('headers', {
	'x-api-version': '2020-08-07'
 });

Not Acceptable Shipment is missing .NET API

Similar to issue #14 , I am trying the example from the documentation, but I keep getting the Not Acceptable Shipment is missing error. I am using the .Net api and I am passing a JSON with the specified values. I also saw in issue #18 that it was mentioned that the user needed to pass a different object type. Does the .net API expect a JSON or some other object type? Based on the samples I was assuming it was a JSON.

Any help would be greatly appreciated.

Incorrect typescript return types

The methods in this library were recently updated to have return types.

I believe that the added types are incorrect. As they signify that the promise will resolve to one of two types but in practice only resolves to one of these two types. The other is the expected value of the rejection.

Due to the nature of javascript promises capturing any error, Typescript does not permit narrowing of the error type on a promise. This is because the error could be thrown by other code in the async code or node js itself.

Digging into the code, it seems that the error creation code is not very standard:

const proxiedError = new (<any>Error)(
`TaxJar: ${result.error.error} - ${result.error.detail}`
);
proxiedError.error = result.error.error;
proxiedError.detail = result.error.detail;
proxiedError.status = result.statusCode;
throw proxiedError;

Typically, in Typescript, I would expect:

export class TaxJarError extends Error {
  constructor(
    public error: string,
    public detail: string,
    public status: number
  ) {
    super(detail);
    Object.setPrototypeOf(this, TaxjarError.prototype);
  }
}

Allowing for correct instanceof TaxjarError semantics.

Exclude unnecessary files in npm package

When viewing the published npm package, it seems there are extra files included that may not be necessary:

Screen Shot 2019-04-23 at 1 31 18 PM

What do you think of adding the following to .npmignore?

  • .editorconfig
  • .eslintrc
  • .travis.yml
  • tsconfig.json

Alternatively, we could switch from excluding files to including files with the package.json files field like so:

{
  "files": ["dist/**"]
}

This would include only:

  • all the contents of dist/
  • package.json
  • LICENSE
  • README

That way, publishing will be a little more future proof if/when more configuration files are added that shouldn't be included in the npm package.

Let me know what you think; I'm happy to send up a quick PR. 🚀

Cannot import Taxjar using TypeScript

This used to work on v1, now it throws an error on v2.

import * as taxjar from 'taxjar';
Module '"/node_modules/taxjar/dist/taxjar"' resolves to a non-module entity and cannot be imported using this construct.

Attempting to import as documented throws a different error.

import Taxjar from 'taxjar';
Module '"/node_modules/taxjar/dist/taxjar"' has no default export.

Here's my tsconfig.json file.

{
  "compilerOptions": {
    "lib": ["es2017"],
    "module": "commonjs",
    "noImplicitReturns": true,
    "outDir": "lib",
    "sourceMap": true,
    "target": "es6"
  },
  "compileOnSave": true,
  "include": [
    "src"
  ],
  "strictNullChecks": true
}

Moderate severity vulnerability in request package

Surprised this has not even an issue opened, so here it is.

request has been deprecated for three years now, and has a moderate vulnerability published on march.

taxjar-node even has an opened pull request (#72) with a possible solution since January.

# npm audit report

request  *
Severity: moderate
Server-Side Request Forgery in Request - https://github.com/advisories/GHSA-p8p7-x288-28g6

Any idea of who could work on this?

validateAddress doesn't work. Endpoint 404 error is thrown.

validateAddress fails permanently.

 const client = new Taxjar({
    apiUrl: process.env.TAXJAR_API_URL,
    apiKey: process.env.TAXJAR_TOKEN
});

 client.validateAddress({
        country: 'US',
        state: 'AZ',
        zip: '85297',
        city: 'Gilbert',
        street: '3301 South Greenfield Rd'
    }).then(res => {
        console.log("RES",res)
        res.addresses; // Addresses object
    }).catch(e => {
        console.error(e)
    });

Throws and error:

    TaxjarError: Not Found - No such route 'POST /v2/addresses/validate'
    at proxyError (/test/node_modules/taxjar/dist/util/request.js:9:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  error: 'Not Found',
  detail: "No such route 'POST /v2/addresses/validate'",
  status: 404
}

TaxJar error

TaxJar errors come back as JSON.
ex: {
error: "BadRequest",
detail: "...",
status: 400
}
These do not get rejected in /lib/util/request.js.
line 23-27:
if (result instanceof Error) {
defer.reject(result);
} else {
defer.resolve(result);
}
Does not work since the JSON is not an instance of Error.

Differences between node api and rest api

I have an issue when I try to use the Node API and the Rest API because they give me different tax calculations.
With Node
This is my request:

_this.provider.taxForOrder({
                from_country: ‘US’,
                from_zip: “80120”,
                from_state: “CO”,
                to_country: “US”,
                to_zip: “80001",
                to_state: “CO”,
                amount: 454.97000000000014,
                shipping: “0",
                line_items: [{
                        id: 0,
                        quantity: 1,
                        unit_price: 454.97000000000014
                }],
 }).

And this is my response:

{  
   "tax":{  
      "order_total_amount":454.97,
      "shipping":0,
      "taxable_amount":454.97,
      "amount_to_collect":18.2,
      "rate":0.04,
      "has_nexus":true,
      "freight_taxable":true,
      "tax_source":"modified-origin",
      "breakdown":{  
         "taxable_amount":454.97,
         "tax_collectable":18.2,
         "combined_tax_rate":0.04,
         "state_taxable_amount":454.97,
         "state_tax_rate":0.029,
         "state_tax_collectable":13.19,
         "county_taxable_amount":0,
         "county_tax_rate":0,
         "county_tax_collectable":0,
         "city_taxable_amount":0,
         "city_tax_rate":0,
         "city_tax_collectable":0,
         "special_district_taxable_amount":454.97,
         "special_tax_rate":0.011,
         "special_district_tax_collectable":5,
         "shipping":{  
            "taxable_amount":0,
            "tax_collectable":0,
            "combined_tax_rate":0.04,
            "state_taxable_amount":0,
            "state_sales_tax_rate":0.029,
            "state_amount":0,
            "county_taxable_amount":0,
            "county_tax_rate":0,
            "county_amount":0,
            "city_taxable_amount":0,
            "city_tax_rate":0,
            "city_amount":0,
            "special_taxable_amount":0,
            "special_tax_rate":0.011,
            "special_district_amount":0
         },
         "line_items":[  
            {  
               "id":"0",
               "taxable_amount":454.97,
               "tax_collectable":18.2,
               "combined_tax_rate":0.04,
               "state_taxable_amount":454.97,
               "state_sales_tax_rate":0.029,
               "state_amount":13.19,
               "county_taxable_amount":0,
               "county_tax_rate":0,
               "county_amount":0,
               "city_taxable_amount":0,
               "city_tax_rate":0,
               "city_amount":0,
               "special_district_taxable_amount":454.97,
               "special_tax_rate":0.011,
               "special_district_amount":5
            }
         ]
      }
   }
}

With Rest

This is my Post Request to https://api.taxjar.com/v2/taxes

{
    “to_city”: “Louisville”,
    “to_state”: “CO”,
    “to_zip”: “80001",
    “to_country”: “US”,
    “from_city”: “Littleton”,
    “from_state”: “CO”,
    “from_zip”: “80120",
    “from_country”: “US”,
    “amount”: 454.97000000000014,
    “shipping”: 0,
    “line_items”: [
      {
        “id”: “0”,
        “quantity”: 1,
        “unit_price”: 454.97000000000014
      }
    ]
  }

And this is my response:

{
  “tax”: {
    “order_total_amount”: 454.97,
    “shipping”: 0,
    “taxable_amount”: 454.97,
    “amount_to_collect”: 13.19,
    “rate”: 0.029,
    “has_nexus”: true,
    “freight_taxable”: true,
    “tax_source”: “modified-origin”,
    “breakdown”: {
      “taxable_amount”: 454.97,
      “tax_collectable”: 13.19,
      “combined_tax_rate”: 0.029,
      “state_taxable_amount”: 454.97,
      “state_tax_rate”: 0.029,
      “state_tax_collectable”: 13.19,
      “county_taxable_amount”: 0,
      “county_tax_rate”: 0,
      “county_tax_collectable”: 0,
      “city_taxable_amount”: 0,
      “city_tax_rate”: 0,
      “city_tax_collectable”: 0,
      “special_district_taxable_amount”: 0,
      “special_tax_rate”: 0,
      “special_district_tax_collectable”: 0,
      “shipping”: {
        “taxable_amount”: 0,
        “tax_collectable”: 0,
        “combined_tax_rate”: 0.029,
        “state_taxable_amount”: 0,
        “state_sales_tax_rate”: 0.029,
        “state_amount”: 0,
        “county_taxable_amount”: 0,
        “county_tax_rate”: 0,
        “county_amount”: 0,
        “city_taxable_amount”: 0,
        “city_tax_rate”: 0,
        “city_amount”: 0,
        “special_taxable_amount”: 0,
        “special_tax_rate”: 0,
        “special_district_amount”: 0
      },
      “line_items”: [
        {
          “id”: “0”,
          “taxable_amount”: 454.97,
          “tax_collectable”: 13.19,
          “combined_tax_rate”: 0.029,
          “state_taxable_amount”: 454.97,
          “state_sales_tax_rate”: 0.029,
          “state_amount”: 13.19,
          “county_taxable_amount”: 0,
          “county_tax_rate”: 0,
          “county_amount”: 0,
          “city_taxable_amount”: 0,
          “city_tax_rate”: 0,
          “city_amount”: 0,
          “special_district_taxable_amount”: 0,
          “special_tax_rate”: 0,
          “special_district_amount”: 0
        }
      ]
    }
  }
}

The difference between both responses is:

  • With Node my tax calculation is 18.2

  • With Rest my tax calculation is 13.19

Why this is happening?

Thanks in advance

Parameters passing doesn't work for GET-based requests

Since GET requests don't have a body, providing options such as from_transaction_date to methods like listOrders doesn't work, as they're being provided to restler as (ignored) body params instead of querystring params.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.