Integrate Avalara
Edit on GitHubTo enable the Avalara partner integration, use the spryker-eco/avalara-tax module.
Install feature core
Follow the steps below to install the feature core.
Prerequisites
- To start the feature integration, overview and install the necessary features:
NAME | VERSION | INTEGRATION GUIDE |
---|---|---|
Spryker Core | master | Spryker Core feature integration |
Cart | master | Cart feature integration |
Product | master | Product feature integration |
Tax | master | |
Inventory Management | master | Install the Inventory Management feature |
Glue API: Checkout | master | Install the Checkout Glue API |
- To register an application with the Avalara platform and get configuration options, follow Set up AvaTax.
1) Install the required modules using Composer
Install the required modules:
composer require spryker-eco/avalara-tax:"^0.1.0" --update-with-dependencies
Ensure that the following modules have been installed:
MODULE | EXPECTED DIRECTORY |
---|---|
AvalaraTax | vendor/spryker-eco/avalara-tax |
2) Set up the configuration
Add the US
ISO country code to the global store configuration:
config/Shared/stores.php
<?php
$stores = [];
$stores['DE'] = [
...
'countries' => [..., 'US'],
...
];
Configure the Avalara credentials:
- Add the following template to configuration:
config/Shared/config_default.php
<?php
use SprykerEco\Shared\AvalaraTax\AvalaraTaxConstants;
// >>> Avalara Tax
$config[AvalaraTaxConstants::AVALARA_TAX_APPLICATION_NAME] = 'YOUR_APPLICATION_NAME';
$config[AvalaraTaxConstants::AVALARA_TAX_APPLICATION_VERSION] = 'YOUR_APPLICATION_VERSION';
$config[AvalaraTaxConstants::AVALARA_TAX_MACHINE_NAME] = 'YOUR_MACHINE_NAME';
$config[AvalaraTaxConstants::AVALARA_TAX_ENVIRONMENT_NAME] = 'AVALARA_ENVIRONMENT_NAME';
$config[AvalaraTaxConstants::AVALARA_TAX_ACCOUNT_ID] = 'YOUR_ACCAUNT_ID';
$config[AvalaraTaxConstants::AVALARA_TAX_LICENSE_KEY] = 'YOUR_LICENSE_KEY';
$config[AvalaraTaxConstants::AVALARA_TAX_COMPANY_CODE] = 'YOUR_COMPANY_CODE';
- Based on the data from your Avalara account, replace the placeholders in the template as described below.
PLACEHOLDER | DESCRIPTION |
---|---|
YOUR_APPLICATION_NAME | Application name. |
YOUR_APPLICATION_VERSION | Application version. |
YOUR_MACHINE_NAME | Name of the machine specific to your project. |
AVALARA_ENVIRONMENT_NAME | Environment name. Acceptable values are sandbox , production or the full URL of your AvaTax instance. |
YOUR_ACCAUNT_ID | Client identifier. |
YOUR_LICENSE_KEY | Client secret. |
YOUR_COMPANY_CODE | Company code. |
3) Add translations
- Append glossary according to your configuration:
data/import/glossary.csv
>countries.iso.US,United States of America,en_US
countries.iso.US,vereinigte Staaten von Amerika,de_DE
- Import data:
console data:import glossary
Make sure that in the database, the configured data has been added to the spy_glossary
table.
4) Set up database schema and transfer objects
Apply database changes, generate entity and transfer changes:
console propel:install
console transfer:generate
Make sure that the following changes have been applied by checking your database:
DATABASE ENTITY | TYPE | EVENT |
---|---|---|
spy_tax_avalara_api_log | table | created |
spy_tax_avalara_sales_order | table | created |
spy_tax_avalara_sales_order_item | table | created |
spy_tax_avalara_sales_detail | table | created |
spy_product_abstract.avalara_tax_code | column | created |
spy_product.avalara_tax_code | column | created |
Make sure that the following changes have been applied in the transfer objects:
TRANSFER | TYPE | EVENT | PATH |
---|---|---|---|
AvalaraApiLogTransfer | class | created | src/Generated/Shared/Transfer/AvalaraApiLogTransfer |
AvalaraAddressTransfer | class | created | src/Generated/Shared/Transfer/AvalaraAddressTransfer |
AvalaraLineItemTransfer | class | created | src/Generated/Shared/Transfer/AvalaraLineItemTransfer |
AvalaraCreateTransactionTransfer | class | created | src/Generated/Shared/Transfer/AvalaraCreateTransactionTransfer |
AvalaraCreateTransactionRequestTransfer | class | created | src/Generated/Shared/Transfer/AvalaraCreateTransactionRequestTransfer |
AvalaraTransactionLineTransfer | class | created | src/Generated/Shared/Transfer/AvalaraTransactionLineTransfer |
AvalaraTransactionTransfer | class | created | src/Generated/Shared/Transfer/AvalaraTransactionTransfer |
AvalaraCreateTransactionResponseTransfer | class | created | src/Generated/Shared/Transfer/AvalaraCreateTransactionResponseTransfer |
AvalaraAddressValidationInfoTransfer | class | created | src/Generated/Shared/Transfer/AvalaraAddressValidationInfoTransfer |
AvalaraResolveAddressRequestTransfer | class | created | src/Generated/Shared/Transfer/AvalaraResolveAddressRequestTransfer |
AvalaraResolveAddressResponseTransfer | class | created | src/Generated/Shared/Transfer/AvalaraResolveAddressResponseTransfer |
QuoteTransfer.avalaraCreateTransactionResponse | property | created | src/Generated/Shared/Transfer/QuoteTransfer |
ProductConcreteTransfer.avalaraTaxCode | property | created | src/Generated/Shared/Transfer/ProductConcreteTransfer |
ProductAbstractTransfer.avalaraTaxCode | property | created | src/Generated/Shared/Transfer/ProductAbstractTransfer |
ItemTransfer.avalaraTaxCode | property | created | src/Generated/Shared/Transfer/ItemTransfer |
ItemTransfer.warehouse | property | created | src/Generated/Shared/Transfer/ItemTransfer |
5) Set up behavior
- Activate the following plugins:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
AvalaraItemTaxRateCalculatorPlugin | Calculates taxes based on the response data received from the Avalara Tax API. Use it instead of ProductItemTaxRateCalculatorPlugin , ProductOptionTaxRateCalculatorPlugin , and ShipmentTaxRateCalculatorPlugin . |
None | SprykerEco\Zed\AvalaraTax\Communication\Plugin\Calculation |
AvalaraTaxCodeItemExpanderPlugin | Expands CartChangeTransfer.items with an Avalara tax code. |
None | SprykerEco\Zed\AvalaraTax\Communication\Plugin\Cart |
AvalaraTaxCodeProductConcreteBeforeCreatePlugin | Expands product concrete with an Avalara tax code. | None | SprykerEco\Zed\AvalaraTax\Communication\Plugin\Product |
AvalaraTaxCheckoutPreConditionPlugin | Checks if a request to Avalara was successful. | None | SprykerEco\Zed\AvalaraTax\Communication\Plugin\Checkout |
ItemWarehouseCartOperationPostSavePlugin | Expands QuoteTransfer.items with a warehouse property. |
None | SprykerEco\Zed\AvalaraTax\Communication\Plugin\Cart |
AvalaraReadCheckoutDataValidatorPlugin | Validates the shipping address data. | None | SprykerEco\Zed\AvalaraTax\Communication\Plugin\CheckoutRestApi |
src/Pyz/Zed/Calculation/CalculationDependencyProvider.php
<?php
namespace Pyz\Zed\Calculation;
use Spryker\Zed\Calculation\CalculationDependencyProvider as SprykerCalculationDependencyProvider;
use Spryker\Zed\Kernel\Container;
use SprykerEco\Zed\AvalaraTax\Communication\Plugin\Calculation\AvalaraItemTaxRateCalculatorPlugin;
class CalculationDependencyProvider extends SprykerCalculationDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\CalculationExtension\Dependency\Plugin\CalculationPluginInterface[]
*/
protected function getQuoteCalculatorPluginStack(Container $container)
{
return [
new AvalaraItemTaxRateCalculatorPlugin(),
];
}
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\CalculationExtension\Dependency\Plugin\CalculationPluginInterface[]
*/
protected function getOrderCalculatorPluginStack(Container $container)
{
return [
new AvalaraItemTaxRateCalculatorPlugin(),
];
}
}
Make sure you’ve enabled the plugins:
- Adding items to a cart and proceed to checkout.
- On the summary page, you should see the calculated taxes for your order.
src/Pyz/Zed/Cart/CartDependencyProvider.php
<?php
namespace Pyz\Zed\Cart;
use Spryker\Zed\Cart\CartDependencyProvider as SprykerCartDependencyProvider;
use Spryker\Zed\Kernel\Container;
use SprykerEco\Zed\AvalaraTax\Communication\Plugin\Cart\AvalaraTaxCodeItemExpanderPlugin;
use SprykerEco\Zed\AvalaraTax\Communication\Plugin\Cart\ItemWarehouseCartOperationPostSavePlugin;
class CartDependencyProvider extends SprykerCartDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\CartExtension\Dependency\Plugin\ItemExpanderPluginInterface[]
*/
protected function getExpanderPlugins(Container $container): array
{
return [
new AvalaraTaxCodeItemExpanderPlugin(),
];
}
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\CartExtension\Dependency\Plugin\CartOperationPostSavePluginInterface[]
*/
protected function getPostSavePlugins(Container $container): array
{
return [
new ItemWarehouseCartOperationPostSavePlugin(),
];
}
}
- Add an address to a warehouse
- Increase the product stock of an item.
- Add the item to a cart.
- Proceed to the summary page of checkout.
- In the
spy_tax_avalara_api_log
table, check that theShipFrom
property is specified in the request data.
src/Pyz/Zed/Product/ProductDependencyProvider.php
<?php
namespace Pyz\Zed\Product;
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\Product\ProductDependencyProvider as SprykerProductDependencyProvider;
use SprykerEco\Zed\AvalaraTax\Communication\Plugin\Product\AvalaraTaxCodeProductConcreteBeforeCreatePlugin;
class ProductDependencyProvider extends SprykerProductDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\ProductExtension\Dependency\Plugin\ProductConcreteCreatePluginInterface[]
*/
protected function getProductConcreteBeforeCreatePlugins(Container $container)
{
return [
new AvalaraTaxCodeProductConcreteBeforeCreatePlugin(),
];
}
}
- Create an abstract product with the Avalara tax code specified.
- Create a variant of this product.
- Check that the concrete product inherits the Avalara tax code.
src/Pyz/Zed/Checkout/CheckoutDependencyProvider.php
<?php
namespace Pyz\Zed\Checkout;
use Spryker\Zed\Checkout\CheckoutDependencyProvider as SprykerCheckoutDependencyProvider;
use Spryker\Zed\Kernel\Container;
use SprykerEco\Zed\AvalaraTax\Communication\Plugin\Checkout\AvalaraTaxCheckoutPreConditionPlugin;
class CheckoutDependencyProvider extends SprykerCheckoutDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\CheckoutExtension\Dependency\Plugin\CheckoutPreConditionPluginInterface[]
*/
protected function getCheckoutPreConditions(Container $container)
{
return [
new AvalaraTaxCheckoutPreConditionPlugin(),
];
}
}
- Create a warehouse with a non-US address.
- Specify product stock for a product.
- Add the product to a cart.
- On the summary page of checkout, check that you can’t place the order because of a failed request to the Avalara API.
src/Pyz/Zed/CheckoutRestApi/CheckoutRestApiDependencyProvider.php
<?php
namespace Pyz\Zed\CheckoutRestApi;
use Spryker\Zed\CheckoutRestApi\CheckoutRestApiDependencyProvider as SprykerCheckoutRestApiDependencyProvider;
use SprykerEco\Zed\AvalaraTax\Communication\Plugin\CheckoutRestApi\AvalaraReadCheckoutDataValidatorPlugin;
class CheckoutRestApiDependencyProvider extends SprykerCheckoutRestApiDependencyProvider
{
/**
* @return \Spryker\Zed\CheckoutRestApiExtension\Dependency\Plugin\ReadCheckoutDataValidatorPluginInterface[]
*/
protected function getReadCheckoutDataValidatorPlugins(): array
{
return [
new AvalaraReadCheckoutDataValidatorPlugin(),
];
}
}
Make sure that you’ve activated AvalaraReadCheckoutDataValidatorPlugin
:
- Send an incorrect address to the
/checkout-data
endpoint. - Make sure that request with the incorrect shipping address does not pass the validation check:
Request:
Request:
{
"data": {
"type": "checkout-data",
"attributes": {
"idCart": "1ce91011-8d60-59ef-9fe0-4493ef3628b2",
"shippingAddress": {
"salutation": "Mr",
"email": "spencor.hopkin@spryker.com",
"firstName": "spencor",
"lastName": "hopkin",
"address1": "West road",
"address2": "212",
"address3": "",
"zipCode": "11111",
"city": "Test",
"iso2Code": "US",
"company": "Spryker",
"phone": "+380663344123",
"isDefaultShipping": true,
"isDefaultBilling": true
}
}
}
}
Response:
{
"errors": [
{
"code": "1101",
"status": 422,
"detail": "Address not geocoded."
},
{
"code": "1101",
"status": 422,
"detail": "The city could not be determined."
}
]
}
- Update the following data import .csv files:
FILE NAME | COLUMN TO ADD | LOCATION |
---|---|---|
product_abstract.csv | avalara_tax_code | data/import/common/common/product_abstract.csv |
product_concrete.csv | avalara_tax_code | data/import/common/common/product_concrete.csv |
- To handle the new field, adjust
ProductAbstract
andProductConcrete
data importers using the following example:data/import/common/common/product_abstract.csv
data/import/common/common/product_concrete.csv
data/import/common/common/product_abstract.csv
>category_key,category_product_order,abstract_sku,name.en_US,name.de_DE,url.en_US,url.de_DE,attribute_key_1,value_1,attribute_key_1.en_US,value_1.en_US,attribute_key_1.de_DE,value_1.de_DE,attribute_key_2,value_2,attribute_key_2.en_US,value_2.en_US,attribute_key_2.de_DE,value_2.de_DE,attribute_key_3,value_3,attribute_key_3.en_US,value_3.en_US,attribute_key_3.de_DE,value_3.de_DE,attribute_key_4,value_4,attribute_key_4.en_US,value_4.en_US,attribute_key_4.de_DE,value_4.de_DE,attribute_key_5,value_5,attribute_key_6,value_6,attribute_key_6.en_US,value_6.en_US,attribute_key_6.de_DE,value_6.de_DE,color_code,description.en_US,description.de_DE,tax_set_name,meta_title.en_US,meta_title.de_DE,meta_keywords.en_US,meta_keywords.de_DE,meta_description.en_US,meta_description.de_DE,new_from,new_to,avalaraTaxCode
digital-cameras,16,001,Canon IXUS 160,Canon IXUS 160,/en/canon-ixus-160-1,/de/canon-ixus-160-1,megapixel,20 MP,,,,,flash_range_tele,1.3-1.5 m,flash_range_tele,4.2-4.9 ft,,,memory_slots,1,,,,,usb_version,2,,,,,brand,Canon,,,color,Red,color,Weinrot,#DC2E09,"Add a personal touch Make shots your own with quick and easy control over picture settings such as brightness and colour intensity. Preview the results while framing using Live View Control and enjoy sharing them with friends using the 6.8 cm (2.7”) LCD screen. Combine with a Canon Connect Station and you can easily share your photos and movies with the world on social media sites and online albums like irista, plus enjoy watching them with family and friends on an HD TV. Effortlessly enjoy great shots of friends thanks to Face Detection technology. It detects multiple faces in a single frame making sure they remain in focus and with optimum brightness. Face Detection also ensures natural skin tones even in unusual lighting conditions.","Beeindruckende Aufnahmen, ganz einfach Smart Auto ermöglicht die mühelose Aufnahme von fantastischen Fotos und Movies – die Kamera wählt in diesem Modus automatisch die idealen Einstellungen für die jeweilige Aufnahmesituation. Sie müssen nur noch das Motiv anvisieren und auslösen. Ein Druck auf die Hilfe-Taste führt zu leicht verständlichen Erklärungen der Kamerafunktionen. Zahlreiche Kreativfilter laden zum Experimentieren ein und bieten echten Fotospaß. So lässt sich neben vielen anderen Optionen der Verzeichnungseffekt eines Fisheye-Objektivs nachempfinden oder in Fotos und Movies werden die Dinge wie Miniaturmodelle dargestellt.",Entertainment Electronics,Canon IXUS 160,Canon IXUS 160,"Canon,Entertainment Electronics","Canon,Entertainment Electronics",Add a personal touch Make shots your own with quick and easy control over picture settings such as brightness and colour intensity. Preview the results whi,"Beeindruckende Aufnahmen, ganz einfach Smart Auto ermöglicht die mühelose Aufnahme von fantastischen Fotos und Movies – die Kamera wählt in diesem Modus au","",2020-01-01 00:00:00.000000,PC040111
- Import data:
console data:import product-abstract
console data:import product-concrete
Open spy_product_abstract
, and spy_product
and make sure that all data has been imported.
Related features
FEATURE | REQUIRED FOR THE CURRENT FEATURE | INTEGRATION GUIDE |
---|---|---|
Avalara Tax + Product Option | ✓ | Avalara Tax + Product Options feature integration |
Avalara Tax + Shipment | ✓ | Avalara Tax + Shipment feature integration |
Thank you!
For submitting the form