Code Monkey home page Code Monkey logo

taxjar.net's Introduction

TaxJar Sales Tax API for .NET / C# Nuget

Official .NET / C# client for the TaxJar API. For the API documentation, please visit https://developers.taxjar.com/api.


Getting Started
Package Dependencies
Authentication
Usage
Custom Options
Sandbox Environment
Error Handling
Tests
More Information
License
Support
Contributing


Getting Started

We recommend installing TaxJar.net via NuGet. Before authenticating, get your API key from TaxJar.

Use the NuGet package manager inside Visual Studio, Xamarin Studio, or run the following command in the Package Manager Console:

PM> Install-Package TaxJar

Package Dependencies

TaxJar.net comes with assemblies for .NET Standard 2.0. It requires the following dependencies:

These packages are automatically included when installing via NuGet.

Authentication

To authenticate with our API, add a new AppSetting with your TaxJar API key to your project's Web.config / App.config file or directly supply the API key when instantiating the client:

Method A

<!-- Web.config / App.config -->
<appSettings>
...
  <add key="TaxjarApiKey" value="[Your TaxJar API Key]" />
...
</appSettings>
var client = new TaxjarApi(ConfigurationManager.AppSettings["TaxjarApiKey"]);

Note: This method requires System.Configuration.ConfigurationManager on .NET Framework 4.x. If you'd like to use this method on .NET Standard or Core, reference the NuGet package in your project.

Method B

var client = new TaxjarApi("[Your TaxJar API Key]");

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
ValidateVat - 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.

var categories = client.Categories();

// Async Method
var categories = await client.CategoriesAsync();

Calculate sales tax for an order (API docs)

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

var tax = client.TaxForOrder(new {
  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.50,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_tax_code = "31000",
      unit_price = 15,
      discount = 0
    }
  }
});

// Async Method
var tax = await client.TaxForOrderAsync(new {
  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.50,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_tax_code = "31000",
      unit_price = 15,
      discount = 0
    }
  }
});

// Request Entity
var taxEntity = new Tax {
  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.50,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_tax_code = "31000",
      unit_price = 15,
      discount = 0
    }
  }
};

var tax = client.TaxForOrder(taxEntity);

List order transactions (API docs)

Lists existing order transactions created through the API.

var orders = client.ListOrders(new {
  from_transaction_date = "2015/05/01",
  to_transaction_date = "2015/05/31"
});

// Async Method
var orders = await client.ListOrdersAsync(new {
  from_transaction_date = "2015/05/01",
  to_transaction_date = "2015/05/31"
});

// Request Entity
var orderFilter = new OrderFilter {
  FromTransactionDate = "2015/05/01",
  ToTransactionDate = "2015/05/31"
};

var orders = client.ListOrders(orderFilter);

Show order transaction (API docs)

Shows an existing order transaction created through the API.

var order = client.ShowOrder("123");

// Async Method
var order = await client.ShowOrderAsync("123");

Create order transaction (API docs)

Creates a new order transaction.

var order = client.CreateOrder(new {
  transaction_id = "123",
  transaction_date = "2015/05/04",
  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,
  shipping = 2,
  sales_tax = 0.95,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_identifier = "12-34243-0",
      description = "Heavy Widget",
      unit_price = 15,
      discount = 0,
      sales_tax = 0.95
    }
  }
});

// Async Method
var order = await client.CreateOrderAsync(new {
  transaction_id = "123",
  transaction_date = "2015/05/04",
  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,
  shipping = 2,
  sales_tax = 0.95,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_identifier = "12-34243-0",
      description = "Heavy Widget",
      unit_price = 15,
      discount = 0,
      sales_tax = 0.95
    }
  }
});

// Request Entity
var orderEntity = new Order {
  transaction_id = "123",
  transaction_date = "2015/05/04",
  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,
  shipping = 2,
  sales_tax = 0.95,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_identifier = "12-34243-0",
      description = "Heavy Widget",
      unit_price = 15,
      discount = 0,
      sales_tax = 0.95
    }
  }
};

var order = client.CreateOrder(orderEntity);

Update order transaction (API docs)

Updates an existing order transaction created through the API.

var order = client.UpdateOrder(new {
  transaction_id = "123",
  amount = 17,
  shipping = 2,
  line_items = new[] {
    new {
      quantity = 1,
      product_identifier = "12-34243-0",
      description = "Heavy Widget",
      unit_price = 15,
      discount = 0,
      sales_tax = 0.95
    }
  }
});

// Async Method
var order = await client.UpdateOrderAsync(new {
  transaction_id = "123",
  amount = 17,
  shipping = 2,
  line_items = new[] {
    new {
      quantity = 1,
      product_identifier = "12-34243-0",
      description = "Heavy Widget",
      unit_price = 15,
      discount = 0,
      sales_tax = 0.95
    }
  }
});

// Request Entity
var orderEntity = new Order {
  TransactionId = "123",
  Amount = 17,
  Shipping = 2,
  LineItems = new List<LineItem> {
    new LineItem {
      Quantity = 1,
      ProductIdentifier = "12-34243-0",
      Description = "Heavy Widget",
      UnitPrice = 15,
      Discount = 0,
      SalesTax = 0.95
    }
  }
};

var order = client.UpdateOrder(orderEntity);

Delete order transaction (API docs)

Deletes an existing order transaction created through the API.

var order = client.DeleteOrder("123");

// Async Method
var order = await client.DeleteOrderAsync("123");

List refund transactions (API docs)

Lists existing refund transactions created through the API.

var refunds = client.ListRefunds(new {
  from_transaction_date = "2015/05/01",
  to_transaction_date = "2015/05/31"
});

// Async Method
var refunds = await client.ListRefundsAsync(new {
  from_transaction_date = "2015/05/01",
  to_transaction_date = "2015/05/31"
});

// Request Entity
var refundFilter = new RefundFilter {
  FromTransactionDate = "2015/05/01",
  ToTransactionDate = "2015/05/31"
};

var refunds = client.ListRefunds(refundFilter);

Show refund transaction (API docs)

Shows an existing refund transaction created through the API.

var refund = client.ShowRefund("123-refund");

// Async Method
var refund = await client.ShowRefundAsync("123-refund");

Create refund transaction (API docs)

Creates a new refund transaction.

var refund = client.CreateRefund(new {
  transaction_id = "123-refund",
  transaction_reference_id = "123",
  transaction_date = "2015/05/04",
  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,
  shipping = -2,
  sales_tax = -0.95,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_identifier = "12-34243-0",
      description = "Heavy Widget",
      unit_price = -15,
      discount = -0,
      sales_tax = -0.95
    }
  }
});

// Async Method
var refund = await client.CreateRefundAsync(new {
  transaction_id = "123-refund",
  transaction_reference_id = "123",
  transaction_date = "2015/05/04",
  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,
  shipping = -2,
  sales_tax = -0.95,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_identifier = "12-34243-0",
      description = "Heavy Widget",
      unit_price = -15,
      discount = -0,
      sales_tax = -0.95
    }
  }
});

// Request Entity
var refundEntity = new Refund {
  transaction_id = "123-refund",
  transaction_reference_id = "123",
  transaction_date = "2015/05/04",
  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,
  shipping = -2,
  sales_tax = -0.95,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_identifier = "12-34243-0",
      description = "Heavy Widget",
      unit_price = -15,
      discount = -0,
      sales_tax = -0.95
    }
  }
};

var refund = client.CreateRefund(refundEntity);

Update refund transaction (API docs)

Updates an existing refund transaction created through the API.

var refund = client.UpdateRefund(new {
  transaction_id = "123-refund",
  transaction_reference_id = "123",
  amount = -17,
  shipping = -2,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_identifier = "12-34243-0",
      description = "Heavy Widget",
      unit_price = -15,
      discount = -0,
      sales_tax = -0.95
    }
  }
});

// Async Method
var refund = await client.UpdateRefundAsync(new {
  transaction_id = "123-refund",
  transaction_reference_id = "123",
  amount = -17,
  shipping = -2,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_identifier = "12-34243-0",
      description = "Heavy Widget",
      unit_price = -15,
      discount = -0,
      sales_tax = -0.95
    }
  }
});

// Request Entity
var refundEntity = new Refund {
  transaction_id = "123-refund",
  transaction_reference_id = "123",
  amount = -17,
  shipping = -2,
  line_items = new[] {
    new {
      id = "1",
      quantity = 1,
      product_identifier = "12-34243-0",
      description = "Heavy Widget",
      unit_price = -15,
      discount = -0,
      sales_tax = -0.95
    }
  }
};

var refund = client.UpdateRefund(refundEntity);

Delete refund transaction (API docs)

Deletes an existing refund transaction created through the API.

var refund = client.DeleteRefund("123-refund");

// Async Method
var refund = await client.DeleteRefundAsync("123-refund");

List customers (API docs)

Lists existing customers created through the API.

var customers = client.ListCustomers();

// Async Method
var customers = await client.ListCustomersAsync();

Show customer (API docs)

Shows an existing customer created through the API.

var customer = client.ShowCustomer("123");

// Async Method
var customer = await client.ShowCustomerAsync("123");

Create customer (API docs)

Creates a new customer.

var customer = client.CreateCustomer(new {
  customer_id = "123",
  exemption_type = "wholesale",
  name = "Dunder Mifflin Paper Company",
  exempt_regions = new[] {
    new {
      country = "US",
      state = "FL"
    },
    new {
      country = "US",
      state = "PA"
    }
  },
  country = "US",
  state = "PA",
  zip = "18504",
  city = "Scranton",
  street = "1725 Slough Avenue"
});

// Async Method
var customer = await client.CreateCustomerAsync(new {
  customer_id = "123",
  exemption_type = "wholesale",
  name = "Dunder Mifflin Paper Company",
  exempt_regions = new[] {
    new {
      country = "US",
      state = "FL"
    },
    new {
      country = "US",
      state = "PA"
    }
  },
  country = "US",
  state = "PA",
  zip = "18504",
  city = "Scranton",
  street = "1725 Slough Avenue"
});

// Request Entity
var customerEntity = new Customer {
  CustomerId = "123",
  ExemptionType = "wholesale",
  Name = "Dunder Mifflin Paper Company",
  ExemptRegions = new List<ExemptRegion> {
    new ExemptRegion {
      Country = "US",
      State = "FL"
    },
    new ExemptRegion {
      Country = "US",
      State = "PA"
    }
  },
  Country = "US",
  State = "PA",
  Zip = "18504",
  City = "Scranton",
  Street = "1725 Slough Avenue"
};

var customer = client.CreateCustomer(customerEntity);

Update customer (API docs)

Updates an existing customer created through the API.

var customer = client.UpdateCustomer(new {
  customer_id = "123",
  exemption_type = "wholesale",
  name = "Sterling Cooper",
  exempt_regions = new[] {
    new {
      country = "US",
      state = "NY"
    }
  },
  country = "US",
  state = "NY",
  zip = "10010",
  city = "New York",
  street = "405 Madison Ave"
});

// Async Method
var customer = await client.UpdateCustomerAsync(new {
  customer_id = "123",
  exemption_type = "wholesale",
  name = "Sterling Cooper",
  exempt_regions = new[] {
    new {
      country = "US",
      state = "NY"
    }
  },
  country = "US",
  state = "NY",
  zip = "10010",
  city = "New York",
  street = "405 Madison Ave"
});

// Request Entity
var customerEntity = new Customer {
  CustomerId = "123",
  ExemptionType = "wholesale",
  Name = "Sterling Cooper",
  ExemptRegions = new List<ExemptRegion> {
    new ExemptRegion {
      Country = "US",
      State = "NY"
    }
  },
  Country = "US",
  State = "NY",
  Zip = "10010",
  City = "New York",
  Street = "405 Madison Ave"
};

var customer = client.UpdateCustomer(customerEntity);

Delete customer (API docs)

Deletes an existing customer created through the API.

var customer = client.DeleteCustomer("123");

// Async Method
var customer = await client.DeleteCustomerAsync("123");

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.

var rates = client.RatesForLocation("90002", new {
  city = "LOS ANGELES",
  country = "US"
});

// Async Method
var rates = await client.RatesForLocationAsync("90002", new {
  city = "LOS ANGELES",
  country = "US"
});

// Request Entity
var rateEntity = new Rate {
  City = "LOS ANGELES",
  Country = "US"
};

var rates = client.RatesForLocation("90002", rateEntity);

List nexus regions (API docs)

Lists existing nexus locations for a TaxJar account.

var nexusRegions = client.NexusRegions();

// Async Method
var nexusRegions = await client.NexusRegionsAsync();

Validate an address (API docs)

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

var addresses = client.ValidateAddress(new {
  country = "US",
  state = "AZ",
  zip = "85297",
  city = "Gilbert",
  street = "3301 South Greenfield Rd"
});

// Async Method
var addresses = client.ValidateAddressAsync(new {
  country = "US",
  state = "AZ",
  zip = "85297",
  city = "Gilbert",
  street = "3301 South Greenfield Rd"
});

Validate a VAT number (API docs)

Validates an existing VAT identification number against VIES.

var validation = client.ValidateVat(new {
  vat = "FR40303265045"
});

// Async Method
var validation = await client.ValidateVatAsync(new {
  vat = "FR40303265045"
});

// Request Entity
var vatEntity = new Validation {
  Vat = "FR40303265045"
};

var validation = client.ValidateVat(vatEntity);

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.

var summaryRates = client.SummaryRates();

// Async Method
var summaryRates = await client.SummaryRatesAsync();

Custom Options

You can pass additional options using SetApiConfig or when instantiating the client for the following:

Timeouts

// Custom timeout when instantiating the client
var client = new TaxjarApi("[Your TaxJar API Key]", new { apiUrl = "https://api.taxjar.com", timeout = 30 * 1000 });

// Custom timeout via `SetApiConfig`
client.SetApiConfig("timeout", 30 * 1000);

API Version

// Custom API version when instantiating the client
var client = new TaxjarApi("[Your TaxJar API Key]", new { apiUrl = "https://api.taxjar.com", headers = new Dictionary<string, string> {
  { "x-api-version", "2020-08-07" }
}});

// Custom API version via `SetApiConfig`
client.SetApiConfig("headers", new Dictionary<string, string> {
  { "x-api-version", "2020-08-07" }
});

Sandbox Environment

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

var client = new TaxjarApi("[Your TaxJar Sandbox API Key]", new { apiUrl = "https://api.sandbox.taxjar.com" });

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

client.SetApiConfig("headers", new Dictionary<string, string> {
  { "X-TJ-Expected-Response", "422" }
});

Error Handling

When invalid data is sent to TaxJar or we encounter an error, we’ll throw a TaxjarException with the HTTP status code and error message. To catch these exceptions, refer to the example below. Click here for a list of common error response classes.

using Taxjar;
var client = new TaxjarApi();

try
{
  // Invalid request
  var order = client.CreateOrder(new {
    transaction_date = "2015/05/04",
    from_country = "US",
    from_zip = "07001",
    from_state = "NJ",
    from_city = "Avenel",
    from_street = "305 W Village Dr",
    to_country = "US",
    to_zip = "90002",
    to_state = "CA",
    to_city = "Ramsey",
    to_street = "63 W Main St",
    amount = 17.45,
    shipping = 1.5,
    sales_tax = 0.95
    line_items = new[] {
      new {
        id = "1",
        quantity = 1,
        product_tax_code = "31000",
        unit_price = 15,
        discount = 0,
        sales_tax = 0.95
      }
    }
  });
}
catch(TaxjarException e)
{
  // 406 Not Acceptable – transaction_id is missing
  e.TaxjarError.Error;
  e.TaxjarError.Detail;
  e.TaxjarError.StatusCode;
}

Tests

We use NUnit and WireMock.Net for testing. Before running the specs, create a secrets.json file inside the Taxjar.Tests directory with your sandbox API Token:

{
  "ApiToken": "YOUR_SANDBOX_KEY"
}

More Information

More information can be found at TaxJar Developers.

License

TaxJar.net is released under the MIT License.

Support

Bug reports and feature requests should be filed on the GitHub issue tracking page.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new pull request

taxjar.net's People

Contributors

ajaffie avatar codymullins avatar fastdivision avatar martinmccaulley avatar scottrudiger avatar sethobey avatar smolentzov-stripe avatar tissaxinnit 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

Watchers

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

taxjar.net's Issues

TaxJar not loading

We have a .net core 2 project that we are having issues with TaxJar running on our servers but not our local developer machines. We are getting "could not load TaxJar" because file can't be found. The file is clearly on the server along with all other dependencies. We have uninstalled/re-installed the package. We have insured we have the latest version (3.0.2). The server only has .net core installed. Are there any other dependencies or requirements for deployment?

No extensibility points (such as retry policies)

Hey thanks for the SDK its useful, however we are finding several gaps that we'd like to be able to include ourselves such as retry policies and things of that nature.

Any plans for this, or would you be willing to look at a PR contribution to open up some extensibility points?

@kdcllc has a PR out that appears to be a very good start but we'd like to open up access to be able to hook in Polly retry policies maybe as an optional parameter to the TaxJarApi or some such.

Polly in the .NET world is somewhat ubiquitous nowadays for people to implement really effective retry policies and most projects that require resiliency are very likely to already have some set of Polly policy builders and such so we believe this would be a great addition to the TaxJar .NET SDK.

Taxjar API Version

Am I correct in thinking I can pass the x-api-version HTTP request header:

HEADER: "x-api-version: 2022-01-24"

via the following line of code:

client.headers.Add("x-api-version", "2022-01-24");

Or is this already hard-coded somewhen in the library?

RestSharp dependency

Requesting validation of RestSharp latest, 108.0.1, and update of package references.

Shouldn't some properties be nullable?

Hi,
I was comparing this Tax class to the API for Calculating sales tax for an order and noticed shouldn't certain fields be nullable? For example, Tax.Amount and Tax.Shipping should be of type decimal?, right? Shouldn't any parameter that is considered optional in the API docs be nullable? When serializing any classes before sending them to the API (

request.AddParameter("application/json", JsonConvert.SerializeObject(body), ParameterType.RequestBody);
), the default values for certain types are being set and sent instead of null (or nothing if NullValueHandling = NullValueHandling.Ignore is being set).

This should be changed in all classes that have optional API parameters not just the Tax class referenced above.

Thanks!

Cannot run with Newtonsoft.Json version 13

TaxJar version 3.3.2 in NuGet requires Newtonsoft.Json minimum version 12.0.3 (if I'm reading the NPM description properly). I have Newtonsoft.Json v 13.0.1 already installed and I'm getting "Could not load file or assembly 'Newtonsoft.Json, Version=12.0.0.0....The located assembly's manifest definition does not match the assembly reference" when I call a TaxJar method at runtime.

I've tried downgrading Newtonsoft to v12, which works for this problem but causes others which depend on v13.

Can TaxJar be updated to accept Newtonsoft.Json 13?

Thanks, Dave

Request entity examples

Our README examples mainly use anonymous types to pass data for API requests. Let's add new examples using request entities so the data is easier to manage prior to passing it to a client method.

RestSharp failures swallowed silently

While using the API, I came across an issue where I was getting an "object reference not set to an instance of an object" error. Debugging led me to the TaxForOrder method, but there was no further information about the error.

Eventually I was able to determine the issue was that I was missing the System.ValueTuple reference, which was causing RestSharp to fail (the request never went out). RestSharp in turn handled this error internally and returned a response object (without throwing any errors). the response object contains an error message which is how I was able to figure out I was missing a reference. This information, however, was not available as a consumer of the client. I had to use the source code to figure out what was going on.

The SendRequest method is not handling error conditions from RestSharp and simply returns a response with null content, which causes the null reference error mentioned above in TaxForOrder when attempting to deserialize the response.

Use Inheritance for some models

The Breakdown object has Shipping and LineBreadowns. All 3 of these objects have very similar properties. The common properties be put into a BaseBreakdown and individual breakdowns (Shipping, Line) could inherit. Any reason this couldn't be done?

Cannot specify decimal timeouts

The client's timeout property is of type int. It gets multiplied internally by 1000 to convert to milliseconds.

This is a limitation as it does not allow me to set a timeout of 1.5 seconds (1500 milliseconds).

The property should be more flexible (e.g. TimeSpan).

.Net Standard DLLs not Updated in NuGet

The binaries for 3.2.0 on NuGet for .Net Standard are Assembly version 3.1.1 and are referencing RestSharp 106.6.9, but the package installs RestSharp 106.10.1. In the absence of proper Assembly Redirection in .Net Core, this is a large issue. 3.2.0 is not working in .Net Core.

image

Not compatible with co-existing package relying on RestSharpSigned

This package requires the unsigned version of RestSharp package. If there is a need for a co-existing package in the same project that relies on the signed version of RestSharp - RestSharpSigned, then the two cannot work in the same project.

Would it be possible to provide a second option for a signed version of taxjar.net? In the meantime I'll have to maintain my own version.

RatesForLocation chokes on EU countries

Using the example provided here: https://developers.taxjar.com/api/reference/#get-show-tax-rates-for-a-location

Throws the following:

InvalidCastException: Null object cannot be converted to a value type.
System.Convert.ChangeType(object value, Type conversionType, IFormatProvider provider)

JsonSerializationException: Error converting value {null} to type 'System.Decimal'. Path 'rate.super_reduced_rate', line 1, position 34.
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, object value, CultureInfo culture, JsonContract contract, Type targetType) in JsonSerializerInternalReader.cs, line 989

props maybe need to be marked as nullable?

Example code

Can you post example code where multiple line items are added to a TaxForOrder call but the line items are stored in an array which needs to be looped through using foreach?

RestSharp Method Not Found - RestSharp

Issue

After installing version 4.0.0 of TaxJar and attempting to instantiate a new instance of TaxjarApi. When calling a new instance, the program is throwing a Method Not Found error.

Error

System.MissingMethodException: 'Method not found: 'Void RestSharp.RestClient..ctor(RestSharp.RestClientOptions, System.Action`1<System.Net.Http.Headers.HttpRequestHeaders>)'.'

Code Causing Error

public TaxJarInterface(ITaxJarSecurity taxJarSecurity, int timeout = 0)
{
    if (string.IsNullOrEmpty(taxJarSecurity.ApiKey))
        throw new ArgumentNullException("apiToken", "Please provide an API token");

    ApiInterface = new TaxjarApi(taxJarSecurity.ApiKey)
    {
        apiUrl = $"https://{(!taxJarSecurity.DemoMode ? TaxJarConstants.DefaultApiUrl : TaxJarConstants.SandboxApiUrl)}",
        timeout = timeout
    };
}

Serialization issue - RestSharp does not use Newtonsoft JsonNetSerializer by default

All of the API entities rely on the Newtonsoft JsonProperty attribute to serialize correctly. By default RestSharp does not use Newtonsoft JsonNetSerializer which means the request body does not get serialized with the correct property names

For example nexus_addresses should look like this:

"nexus_addresses": [{
    "id": null,
    "country": "US",
    "zip": null,
    "state": "AZ",
    "city": null,
    "street": null
}],

instead it gets serialized (When using the NexusAddress class instead of just a dynamic) as:

"nexus_addresses": [{
    "Id": null,
    "Country": "US",
    "Zip": null,
    "State": "AZ",
    "City": null,
    "Street": null
}],

Notice the casing.

This caused the API to return incorrect tax information as I'm assuming the nexus addresses do not get deserialized properly and are required for my use case.

To fix this we could set the Serializer when building the RestRequest Note: you will need to reference the package RestSharp.Serializers.NewtonsoftJson

var request = new RestRequest(action, method)
{
      RequestFormat = DataFormat.Json, JsonSerializer = new JsonNetSerializer()
};

Need help with generic error troubleshooting

Taxjar.TaxjarException: 'Unprocessable Entity - Something could not be processed'

I'm getting this generic error when creating an error.

Is there any way to get more info to help with troubleshooting?

Is there a way to expose the raw request and raw response so I could paste that into PostMan and troubleshoot?

Running off V3 now.

Thanks for your help!

Async methods are ignoring 'TransactionId' property.

I noticed in the source code that async versions of 'UpdateOrder' and 'UpdateRefund' (there might be others) are ignoring the 'TransactionId' property from the dotnet entities.

this is from the async method:
var transactionId = parameters.GetType().GetProperty("transaction_id").GetValue(parameters).ToString();

this was leading to a NullReferenceException when using the Taxjar.Order object.
Problem was solved when after switching to the synchronous version of UpdateOrder.

this is from the synchronous method:
var transactionIdProp = parameters.GetType().GetProperty("transaction_id") ?? parameters.GetType().GetProperty("TransactionId");

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.