Overview

The Avalara Tax service calculates the taxes on the items in an order. The service uses the shipping destination address to complete the calculation. Currently, you can only calculate taxes for Canada and the United States. Once the tax amount has been calculated, the value is passed to the Checkout service for when the order is processed.

Before you can use this service, you must create an Avalara account, enable the tax jurisdiction, and add the API configurations in the Site service.


API Reference

/{tenant}/tax/quote

/{tenant}/tax/quote

post

Calculate the taxes for the items in the cart. The response contains the tax amount based on the shipping address and the list of items.


Avalara Tax Calculation

Introduction

In this tutorial you will learn how to configure and use the Avalara Tax service to calculate the taxes on the items in a cart. It shows you how to get your system to use the Avalara Tax service along with the Avalara third-party provider, and how to complete tax calculations on the items in your cart.

Set up the Avalara Tax service

To use the Avalara AvaTax product, you must complete these steps:

  1. Create an Avalara account.
  2. Enable the tax jurisdiction.
  3. Add the Avalara configurations to the Site service.

Create an Avalara account

To create an Avalara account, go to the Avalara AvaTax page on the Avalara website. After you create an account, you will receive an email containing this information:

  • Admin Console URL (DEV): https://admin-development.avalara.net/
  • Username (DEV): Your email address
  • Temporary Password (DEV): A temporary password to sign in to Avalara
The Avalara Tax service supports the AvaTax 15 REST API.

Configure the tax jurisdiction

Next, you must sign in to Avalara and configure the tax jurisdiction for your company. After you complete that process, you will receive another email with the Avalara keys and values needed for the Site service. The email contains:

KeyDescription/Value
accountYour Avalara account ID
licenseYour Avalara license key
apiVersion1.0
urlhttps://development.avalara.net


Use this information to configure Avalara Tax service for your tenant (with a site already created) using the Site service POST/sites request. If you are using the value-added tax (VAT), you also need the following keys:

  • businessIdentificationNo - Your Avalara Unified Business Identifier (UBI)
  • taxIncluded - true/false (the default value is false)

When you file for your business license, you'll receive your UBI. For more information, see the File business license applications section of the Avalara page.

Refer to the Site service documentation to configure the tax provider for your site.

Add the Avalara configurations to the Site service

Once you have the keys from Avalara, you need to add them to your tenant configuration in the Site service. This part of the configuration sets up the services before configuring the Avalara Tax settings for a tenant's site.

Setup

Assertion

Define variable assert:

    assert = chai.assert;
Get access token

To perform any operations with a specific service, you always need an access token. For this purpose, create an API Client for the oAuth2 service:

    API.createClient('oAuth2Service',
    '/services/oauth2/v1/api.raml');

Now, get the token:

    tenant = projectIdPlaceholder;
    AccessToken = oAuth2Service.token.post({
      'client_id' : clientIdPlaceholder,
      'client_secret':clientSecretPlaceholder,
      'grant_type' : 'client_credentials',
      'token_type': 'Bearer',
      'scope': 'hybris.tenant='+tenant+ ' hybris.site_manage hybris.tax_manage'
    });

To make the calls simple and the code clean, assign the id of the returned object to a variable:

    access_token = AccessToken.body.access_token;
Create API client for Site service
    API.createClient('siteService',
    '/services/site/v1/api.raml');
Create API client for Avalara Tax service
    API.createClient('taxAvalaraService',
    '/services/avalaratax/v1/api.raml');
Cleanup

Before you create the site used for this tutorial, make sure that the site doesn't already exist.


       response = siteService.tenant(tenant).sites.get({}, {
        headers: {
          'Authorization': 'Bearer ' + access_token,
          'Content-Type' : 'application/json'
        }
      }
    );
    var i = 0;
    while(i < response.body.length){
            if(response.body[i].code == 'canada') {
                response = siteService.tenant(tenant).sites.code('canada').delete({}, {
                    headers: {
                        'Authorization': 'Bearer ' + access_token,
                    'Content-Type' : 'application/json'
                }
            });
            assert.equal(response.status, 404);
            break;
        } 
        i++;
    }
    response;
Create a site

Here, you are going to create a site with the code canada for tenant.

    response = siteService.tenant(tenant).sites.post({
            "code": "canada",
          "name": "Canadian Site",
          "active": false,
          "default": false,
          "defaultLanguage": "en",
          "languages": [
            "en",
            "fr"
          ],
          "currency": "CAD",
          "homeBase": {
            "address": {
              "street": "Maisonneuve",
              "streetNumber": "999",
              "zipCode": "H3A 3L4",
              "city": "Montreal",
              "state": "Quebec",
              "country": "CA"
            }
          }
        }, {
        headers: {
            'Authorization': 'Bearer ' + access_token,
            'Content-Type' : 'application/json'
        }
    });
    assert.equal(response.status, 201);
    siteId = response.body.id
    response;
Configure the Avalara tax settings

This part sets up the Avalara tax settings for the site (canada) you just created for your tenant.

    response = siteService.tenant(tenant).sites.code(siteId).tax.post({
        "id": "AVALARA",
        "name": "Avalara Tax Service",
        "serviceType": "urn:x-yaas:service:tax",
        "serviceUrl": "https://api.beta.yaas.io/hybris/tax-avalara/v1",
        "active": true,
        "configuration": {
            "restricted": {
            "license": "F9B594FA5D692DCC",
            "url": "https://development.avalara.net",
            "apiVersion": "1.0",
            "account": "2000157268",
            "businessIdentificationNo": "12345",
            "taxIncluded": true
          }
        }
       },{
        headers: {
            'Authorization': 'Bearer ' + access_token,
            'Content-Type' : 'application/json'
        }
    });
    assert.equal(response.status, 201);
    response.body;

Various tax calculations

The Quote API retrieves the tax calculation for a given request. There are different scenarios of how tax is calculated for an order. You can:

  • Estimate the taxes based on the ZIP Code.
  • Calculate tax for each line item in an order.
  • Calculate tax for some items in an order and not for others.
  • Calculate tax for an order after discounts are applied.

Tax is calculated based on the shipping destination address in the request. Currently, you can only calculate taxes for Canada and the United States.

The following examples show the different ways that tax is calculated on an order.

For more information, see the Avalara website.

Tax estimate by ZIP Code

If you need a tax estimate, then the request can only contain the ZIP Code and the country of the destination address.

Tax calculation by ZIP Code is not always accurate, because the ZIP Code jurisdiction is not the same as the tax jurisdiction. For example, it is possible for two streets within the same ZIP Code to have different tax rates.
    response = taxAvalaraService.tenant(tenant).tax.quote.post({
             "date": "2015-01-11T14:00:00.000Z",
          "currency": "CAD",
          "siteCode": "canada",
          "addresses": [
              {
                  "type": "SHIP_TO",
                  "addressLine1": "1741 Boulevard Alexis-Nihon",
                  "zipCode": "H4R3A2",
                  "city": "Saint-Laurent",
                  "state": "QC",
                  "country": "CA"
              }
          ],
          "lineItems": [
              {
                  "id": "id0",
                  "itemCode": "productA",
                  "quantity": 10,
                  "unitPrice": 15,
                  "productDescription": "8.5 x 11 hardcover notebook, 192 pages."
              },
              {
                  "id": "id1",
                  "itemCode": "productB",
                  "quantity": 2,
                  "unitPrice": 10,
                  "productDescription": "8.5 x 11 3-subject notebook, 300 pages."
              }
          ]
           },{
        headers: {
            'Authorization': 'Bearer ' + access_token,
            'Content-Type' : 'application/json'
        }
    });
    assert.equal(response.status, 200);
    response.body;

Tax calculation on an entire order

Tax is calculated based on the shipping destination information. When tax is applied to an entire order, the same rate is applied to each line item. In the request, you can provide the shipping to (SHIP_TO) and from (SHIP_FROM) addresses, or only the SHIP_TO address.

The type, zipCode, and country attributes are mandatory to calculate tax if the address is informed.

    response = taxAvalaraService.tenant(tenant).tax.quote.post({
             "date": "2015-01-11T14:00:00.000Z",
          "currency": "CAD",
          "siteCode": "canada",
          "addresses": [
              {
                  "type": "SHIP_FROM",
                  "addressLine1": "123 rue Des Passereaux",
                  "zipCode": "J0L1C0",
                  "city": "St-Clin",
                  "state": "QC",
                  "country": "CA"
              },
              {
                  "type": "SHIP_TO",
                  "addressLine1": "1741 Boulevard Alexis-Nihon",
                  "zipCode": "H4R3A2",
                  "city": "Saint-Laurent",
                  "state": "QC",
                  "country": "CA"
              }
          ],
          "lineItems": [
              {
                  "id": "id0",
                  "itemCode": "productA",
                  "quantity": 10,
                  "unitPrice": 15,
                  "productDescription": "8.5 x 11 hardcover notebook, 192 pages."
              },
              {
                  "id": "id1",
                  "itemCode": "productB",
                  "quantity": 2,
                  "unitPrice": 10,
                  "productDescription": "8.5 x 11 3-subject notebook, 300 pages."
              }
          ]
           },{
        headers: {
            'Authorization': 'Bearer ' + access_token,
            'Content-Type' : 'application/json'
        }
    });
    assert.equal(response.status, 200);
    response.body;

No tax calculation on specific items

In the tax request, you can choose to not apply taxes to some of the line items in an order. If you do not want to apply taxes to a certain item, the line item must contain the taxCode attribute with a value of NT (no tax).

In this example, taxes are not applied to hardcover notebooks.

    response = taxAvalaraService.tenant(tenant).tax.quote.post({
             "date": "2015-01-11T14:00:00.000Z",
          "currency": "CAD",
          "siteCode": "canada",
          "addresses": [
              {
                  "type": "SHIP_FROM",
                  "addressLine1": "123 rue Des Passereaux",
                  "zipCode": "J0L1C0",
                  "city": "St-Clin",
                  "state": "QC",
                  "country": "CA"
              },
              {
                  "type": "SHIP_TO",
                  "addressLine1": "1741 Boulevard Alexis-Nihon",
                  "zipCode": "H4R3A2",
                  "city": "Saint-Laurent",
                  "state": "QC",
                  "country": "CA"
              }
          ],
          "lineItems": [
              {
                  "id": "id0",
                  "itemCode": "productA",
                  "taxCode": "NT",
                  "quantity": 10,
                  "unitPrice": 15,
                  "productDescription": "8.5 x 11 hardcover notebook, 192 pages."
              },
              {
                  "id": "id1",
                  "itemCode": "productB",
                  "quantity": 2,
                  "unitPrice": 10,
                  "productDescription": "8.5 x 11 3-subject notebook, 300 pages."
              }
          ]
           },{
        headers: {
            'Authorization': 'Bearer ' + access_token,
            'Content-Type' : 'application/json'
        }
    });
    assert.equal(response.status, 200);
    response.body;

Tax calculation with discount

If a discount is applied to an order, the discount must be calculated before the taxes are applied. With Avalara, you can only use a decimal format value for discounts (in other words, a dollar amount). Percentage values cannot be used. The discount amount is applied proportionally across all the line items with a discounted attribute set to true. If none of the line items have a discounted attribute set to true, then the value in the discount attribute is ignored.

In this example, a discount of $10 is applied proportionally to the two items that have the discounted attribute set to true.

    response = taxAvalaraService.tenant(tenant).tax.quote.post({
      "date": "2015-01-11T14:00:00.000Z",
      "currency": "CAD",
      "siteCode": "canada",
      "discount": 10,
      "addresses": [
          {
              "type": "SHIP_FROM",
              "addressLine1": "123 rue Des Passereaux",
              "zipCode": "J0L1C0",
              "city": "St-Clin",
              "state": "QC",
              "country": "CA"
          },
          {
              "type": "SHIP_TO",
              "addressLine1": "1741 Boulevard Alexis-Nihon",
              "zipCode": "H4R3A2",
              "city": "Saint-Laurent",
              "state": "QC",
              "country": "CA"
          }
      ],
      "lineItems": [
          {
              "id": "id0",
              "itemCode": "productA",
              "taxCode": "FILE_A",
              "quantity": 10,
              "unitPrice": 10,
              "productDescription": "8.5 x 11 hardcover notebook, 192 pages.",
              "discounted": true
          },
          {
              "id": "id1",
              "itemCode": "productB",
              "taxCode": "FILE_A",
              "quantity": 1,
              "unitPrice": 20,
              "productDescription": "8.5 x 11 3-subject notebook, 300 pages.",
              "discounted": true
          },
          {
              "id": "id2",
              "itemCode": "productC",
              "taxCode": "FILE_B",
              "quantity": 2,
              "unitPrice": 10,
              "productDescription": "9 x 7 hardcover notebook, 150 pages."
          }
      ]
    },{
        headers: {
            'Authorization': 'Bearer ' + access_token,
            'Content-Type' : 'application/json'
        }
    });
    assert.equal(response.status, 200);
    response.body;

Cleanup

To avoid any conflicts, we delete the site created for this project.

    response = siteService.tenant(tenant).sites.code('canada').delete({}, {
        headers: {
            'Authorization': 'Bearer ' + access_token,
            'Content-Type' : 'application/json'
        }
        }
    );
    assert.equal(response.status, 204);
    response;


Error Codes

For more information about error codes, see the API Reference.


Glossary

TermDescription
AvalaraA company that provides services for sales tax management.
line itemA specific item in the cart.
shipping destinationThe address where the order is being shipped to.
tax jurisdictionA distinct tax regulation for an area, such as a municipality, city, or country.
VATA Value-Added Tax added to a product"s price. This tax is included in the product"s sale price.
ZIP CodeA group of numbers (and letters) that are added to an address to assist in the sorting of mail.


  • Send feedback

    If you find any information that is unclear or incorrect, please let us know so that we can improve the Dev Portal content.

  • Get Help

    Use our private help channel. Receive updates over email and contact our specialists directly.

  • hybris Experts

    If you need more information about this topic, visit hybris Experts to post your own question and interact with our community and experts.