External Tax Engine

Last updated

The custom tax engine plugin allows you to integrate external tax engine services of your choice that Centra does not support out of the box. It is intended to be used along with Checkout API or on the AMS side in case of manual order creation. The external custom tax calculator will be called in various order lifecycle points (e.g. pre-checkout, on checkout, on shipping, etc.) to receive proper tax rates and apply them to the selection or the order.

Setup#

Warehouse address#

To calculate taxes for some countries (e.g. US, Canada, etc.) there is a requirement to have a warehouse address filled in. You need to specify the full address of the warehouse to calculate the tax correctly. You can fill in this data on the specific warehouse page.

Warehouse setup example

Plugin#

Here is a sample of a custom tax engine plugin setup:

Plugin setup example

To set up the External tax engine (ETE) plugin, you need to provide all the basic information:

  • Plugin name - the name used for some info displayed across the AMS (e.g. selectors, history entries)
  • Tax engine type - should be Custom
  • API URL - the endpoint Centra will send requests for tax calculation to.

Please note that this endpoint should be able to handle multiple types of payloads depending on the request type (see Request type concept).

  • Signing secret - the string which will be used to construct the request signature header to make it possible to verify the validity of the request on your ETE side (see Request signature concept).

You may see the plain value for the signing secret field on the plugin form, but don’t worry - we encrypt the field value on DB and store it safely.

  • Connection to the tax engine - here you may check the connection to the API you specified above. See Test connection to learn more about how the connection check works.
  • Supported countries - there is a selector which defines the set of countries ETE should be called on. Order shipping address country selection triggers the check if ETE should be called, and calls it if the condition is fulfilled.
  • Same tax calculation on prices - select if all countries used in this tax engine have tax calculated similarly (included in prices or on top of prices).
  • Tax on prices - select if taxes are included in prices before the checkout or added on top of prices in the checkout.
  • Default tax code - general fallback tax code will be sent on the basket line if you do not specify a different one on the product store level.
  • Default shipping tax code - the shipping tax code will be sent on the basket line to calculate shipping costs' tax.
  • Default handling tax code - the handling tax code will be sent on the basket line to calculate handling costs' tax.
  • Default return costs tax code - the return costs tax code will be sent on the basket line to calculate return costs' tax.
  • Default no tax code - the tax code for non-taxed non-physical goods, used for refunding the absolute money values including tax.

There is no way to set non-default shipping, handling, return cost and non-taxed codes now.

  • Send taxes to external system - if selected, Centra will make requests to ETE not only for the tax calculation but for tax filing purposes. Those calls will have a separate request type, so you will know for sure when exactly the tax should be filed.

Tax code batch assignment#

There is a possibility to do a mass assignment of tax codes for products on the product catalog page. It has the Update tax codes batch action which allows the same tax code assignment for a batch of products on the store level.

Tax code batch assignment example

Customer exemption code assignment#

There is a possibility to assign the custom exemption code for customer (in Retail) and for account (in Wholesale) to provide more granular tax exemption experience for groups of customers. Entered exemption code will be sent in the payload so external tax service may define if customer/account is eligible for the exemption and apply it.

Customer exemption code assignment example

In case you need to apply personal tax exemptions for certain users, you may check the Customer code definition. However, a customer exemption code can also be used for such purposes.

Flow#

At some points in the order lifecycle, it is required by Centra to make calls to the tax engine to calculate the proper tax amount. It may happen either pre-checkout (by filling in the shipping address, changing the number of order items, etc.) or post-checkout (adding/removing items from the order, warehouse changing on allocation, etc.).

In this case, Centra issues the request to ETE with order data (data set may vary depending on the request type) and waits for the response in some format (which also may vary depending on the same request type) to process it and apply the correct tax rules to the order. The way of defining which request and response formats should be used for which action is described below.

Common request concepts#

Request type#

By design, the plugin will send all tax calculation requests to the same endpoint specified in the plugin settings. However, the request body itself may contain a different set of fields depending on the request type (e.g. order calculation will have the full set of lines, but return calculation may require only some lines from the whole order with partial amount and quantity).

It means that custom ETE must be able to process different payloads and respond in different formats depending on the action that should be done. To define input and output formats correctly, Centra operates with requestType field value which indicates action should be done and schema set should be used to process the request properly.

Request typeDescriptionRequest/response structure
calculateTaxNoCommitCalculate taxes for orders without the actual commit (it means no saving order data on the ETE side for further reporting to tax authorities). May be used on pre-checkout for the estimated tax calculation.Order
calculateDeliveryTaxNoCommitCalculate taxes for shipments without the actual commit (it means no saving shipment data on the ETE side for further reporting to tax authorities). Used on shipment creation for the estimated tax calculation.Delivery
calculateDeliveryTaxAndCommitCalculate taxes for shipments with the actual commit (with saving shipment data on the ETE side for further reporting to tax authorities). Used on shipment completion for the actual tax calculation.Delivery
calculateReturnTaxNoCommitCalculate taxes for returns without the actual commit (it means no saving return data on the ETE side for further reporting to tax authorities). Used on return creation for the estimated tax calculation.Return
calculateReturnTaxAndCommitCalculate taxes for returns with the actual commit (with saving return data on the ETE side for further reporting to tax authorities). Used on return completion for the actual tax calculation.Return
testTaxEngineConnectionTest the connection with the tax engine.Test connection

In case your external tax engine receives some unrecognizable payload (e.g. unknown request type, wrong data for required fields) or fails to calculate the tax for any reason - it should respond with a verbose error and non-2xx response code, so Centra will be able to execute a proper fallback to the internal tax engine calculation.

You may receive the transaction with the committing type and same entity ID a few times. In this case, your tax engine should handle it properly and update the transaction committed before instead of responding with an error.

Request signature#

The request token is a hash value calculated with the HMAC method and hashing algorithm sha512. It uses the signing secret string from the plugin settings and JSON-encoded request body to calculate the header value.

To verify the request integrity, you need to construct the hash value in the same way with the same signing secret and compare the calculation result with the income header value.

Here is the example for header calculation in PHP, but a lot of languages have similar functions (or libraries supported) to calculate the hash value:

1 2 3 4 private function calculateToken(array $payload, string $signingSecret): string { return hash_hmac('sha512', json_encode($payload), $signingSecret); }

If hashes are equal - it means that the request is valid and data is not corrupted, so it can be processed safely.

Discount handling#

Centra uses the approach of basket lines with negative values to handle discounts per line properly. It means that if you have a discount applied on selection, Centra will distribute it across the basket lines automatically and send you discount values per basket line with a negative amount for 2 reasons:

  • to keep proper selection total sum calculation;
  • to be able to calculate line discount tax value.

The discount line will have the same tax code as the item for which the discount is applied, and the line ID will be represented as the parent item ID + -discount postfix.

Here is the example, where line 1 is the main line, and line 2 is the discount applied to line 1:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 { "lines": [ { "id": "133", "quantity": 1, "amount": 100, "taxCode": "code123", "taxIncluded": false, "addresses": { "shipFrom": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 111" }, "shipTo": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 222" } }, "sku": "Product123Variant456Size789", "description": "TestProduct1", "productNumber": "Product123" }, { "id": "133-discount", "quantity": 1, "amount": -10, "taxCode": "code123", "taxIncluded": false, "addresses": { "shipFrom": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 111" }, "shipTo": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 222" } }, "sku": "Product123Variant456Size789", "description": "TestProduct1", "productNumber": "Product123" } ] }

For proper tax information processing, Centra expects back the same line ID for both the product line and discount line as it has been sent in the payload. It will help to correctly connect the discount line to its product line.

Additional costs handling#

Additional costs (like shipping cost, handling cost, return cost, and return compensation (refund) cost) are using the similar approach to how we handle discounts, but each cost line may appear once in the order/shipment/return lines list. Also, each cost type have its own tax code defined on the plugin level, and some of the cost lines may appear only on some specific entities (e.g. return cost and return compensation cost may be applied for return only).

Additional cost lines will be presented on the payload only in case you define all additional cost tax codes on the plugin. In case some additional cost code is empty, that additional cost line will not be sent in the lines array.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 { "lines": [ { "id": "shipping-delivery-{deliveryId}", "quantity": 1, "amount": 5, "taxCode": "shippingTaxCode", "taxIncluded": false, "addresses": { "shipTo": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 111" }, "shipFrom": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 222" } }, "sku": "shipping", "description": "Shipping costs" }, { "id": "handling-delivery-{deliveryId}", "quantity": 1, "amount": 3, "taxCode": "handlingTaxCode", "taxIncluded": false, "addresses": { "shipTo": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 111" }, "shipFrom": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 222" } }, "sku": "handling", "description": "Handling costs" } ] }

Additional cost line ID constructed by the following schema:

cost type-entity type-entity id

Possible cost types and entity types are explained in the tables below.

Entity typeDescription
orderThis can be met on order calculation
deliveryThis can be met on shipment calculation
returnThis can be met on return calculation
Additional cost typeDescription
shippingThis applies if there is a shipping cost to tax
handlingThis applies if there is a handling cost to tax
return-costsThis applies if there is a return cost to tax
return-compensationThis applies if there is a return compensation (refund) cost to tax
shipping-dThis can be met if there is a discount applied that affects shipping costs
handling-dThis can be met if there is a discount applied that affects handling costs

Some amounts on additional cost lines may be negative, so your tax engine should not consider it as the wrong input. It depends both on the additional cost type and entity type.

For proper tax information processing, Centra expects back the same line ID for each additional cost line as it has been sent in the payload. It will help to correctly connect the additional cost line to the entity.

Customer code definition#

The customer code is a string that may be used as a customer identifier for the definition of tax exemption on the external engine side. Centra transfers the customer’s code which you may associate with any kind of exemption in the process of tax calculation on your side, and return the exempted line(s) back to Centra to be processed.

Usually, Centra sends its customer ID as a string, e.g. '77', so you may check which ID the customer has in Centra and build a connection between the customer and his exemption stored on your ETE side.

However, in the case of anonymous checkout on Centra, there is no customer ID available until the payment stage (it's the moment when we are creating the user in Centra even if the checkout is anonymous). But there are some points in order lifecycle before payment when we want to calculate some taxes, despite the customer is not existing yet.

At that moment, the customer code field will contain Centra basket ID instead of Centra customer ID. Centra basket ID is quite a long and random string, so there are no chances it will match with some customer ID and trigger the exemption on the ETE side.

Company code definition#

In case your tax engine supports a multi-company setup, you may want to specify explicitly for which company you want to calculate the tax. For that purpose, Centra has a company code field on plugin level - a string that may be used as a company identifier for your external tax engine. According to the received code, your tax engine may book taxes on behalf of the legal entity you prefer.

Test connection#

There is a Test connection button that helps you to check if the connection with your service can be successfully established. For some out-of-the-box tax engine types (like Avatax) the button works straight away. However, for custom external tax engine it will require some coding to be done on your side to make the button work since you need to accept and verify the payload, check request integrity, and maybe do some additional actions on your side (e.g. send some requests to external tax service under the hood if you use one).

You can check the details of what we are sending to your custom ETE, and which format we expect back, here: Test connection request/response structure.

Request headers#

Here is the list of headers we send with the request, all of them may be used for logging purposes and reported to support for debugging purposes too.

HeaderTypeComment
X-Client-IdstringClient instance ID, e.g. boilerplate-dev
X-Request-IdstringCentra request ID, e.g. 1_1b4591cbd04624e5bce7b1d530adaabe
X-Correlation-IdstringCentra correlation ID, e.g. centra_1_1b4591cbd04624e5bce7b1d530adaabe
X-Request-SignaturestringContains the request signature string constructed with help of signing secret provided as a plugin setting. May be used to verify the origin of the request and the integrity of the request’s body. See more on Request signature
User-AgentstringContains information regarding the Centra version used on request. Example: Centra (https://centra.com), version: v3.33.1

Error response#

Error response structure is common for all entities, so it is listed only once here.

In case of an error, the response should have a non-2xx response code and a reasonable message for debugging purposes.

1 2 3 4 5 { "error": { "message": "Unable to calculate tax." } }
FieldTypeComment
messagestringA message which indicates the error

Order request/response structure#

Request#

Headers

See Request headers.

Body

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 { "data": { "requestType": "calculateTaxNoCommit", "taxEngine": "custom", "entityId": "12681d9bab682309c0fe60102d86d5d6", "customerCode": "50b9577bbe8f9", "transactionDate": "2023-04-07", "lines": [ { "id": "133", "quantity": 1, "amount": 100, "taxCode": "code123", "taxIncluded": false, "addresses": { "shipFrom": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 111" }, "shipTo": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 222" } }, "sku": "Product123Variant456Size789", "description": "TestProduct1", "productNumber": "Product123" }, { "id": "134", "quantity": 1, "amount": 200, "taxCode": "code456", "taxIncluded": false, "addresses": { "shipFrom": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 111" }, "shipTo": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 222" } }, "sku": "Product456Variant789Size012", "description": "TestProduct2", "productNumber": "Product456" } ] } }
Order structure
FieldTypeComment
requestTypestringThe request type indicates which type of calculation should be done on the ETE side, always equals to calculateTaxNoCommit for orders
taxEnginestringAlways equals custom
entityIdstringEntity ID, here represents Centra basket ID
customerCodestringCustomer code, required primarily for tax exempt identification. For value explanation, see more on Customer code definition
companyCode (optional)stringCompany code, used for transaction assigning to specific company in case of multi-company setup. See more on Company code definition
customerExemptionCode (optional)stringCustomer exemption code, used for tax exempt identification. See more on Customer exemption code assignment
transactionDatestring, in YYYY-MM-DD formatCalculation date (current date by default but also may take past values, e.g. order creation date)
linesarrayOrder lines for calculation
Line structure
FieldTypeComment
idstring or integerOrder line ID
quantityintegerQuantity of items ordered
amountfloatThe sum of items' prices. Amount value may be negative in some cases (see more on Discount handling or Additional costs handling)
taxCodestringTax identifier, used to define the proper tax rate
taxIncludedbooleanFlag to indicate if line amount includes the tax value
addressesobject of addressesShipping addresses information. The object may contain either shipFrom or shipTo address or both at the same time
sku (optional)stringFull item SKU (product + variant + size)
description (optional)stringItem description
productNumber (optional)stringa.k.a. Product SKU
Address structure
FieldTypeComment
countrystringCountry ISO code (2 symbols)
postalCode (optional)stringPostal code
state (optional)stringState ISO code (2 symbols)
city (optional)stringCity
line1 (optional)stringAddress line 1
line2 (optional)stringAddress line 2

Response#

Success

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 { "data": { "transactionId": "uniq-trans-id-123", "transactionType": "custom-operation-type-string", "totalTax": 19.18, "totalDiscount": null, "lines": [ { "id": "133", "quantity": 1, "amount": 100, "taxableAmount": 96.5, "tax": 6.39, "taxIncluded": false, "rules": [ { "taxId": "32b71e721c4fe0d80c922ed0e0badd3c", "taxName": "NJ STATE TAX", "taxableAmount": 96.5, "rate": 0.06625, "tax": 6.39 } ] }, { "id": "134", "quantity": 1, "amount": 200, "taxableAmount": 193, "tax": 12.79, "taxIncluded": false, "rules": [ { "taxId": "32b71e721c4fe0d80c922ed0e0badd3c", "taxName": "NJ STATE TAX", "taxableAmount": 193, "rate": 0.06625, "tax": 12.79 } ] } ] } }
Order structure
FieldTypeComment
transactionIdstringCalculation result ID assigned by external tax calculator
transactionTypestringType of calculated action assigned by external tax calculator. May be any string that will help you to indicate which operation has been done on your tax engine side (like order/delivery/return calculation, committed or not committed). You can either specify your own type or send back the type you received in the request
totalTaxfloatTotal tax value
totalDiscount (optional)float or nullTotal discount value
linesarrayTax info per order line
Line structure
FieldTypeComment
idstringOrder line ID
quantityintegerQuantity of items ordered
amountfloatThe sum of items' prices
taxableAmountfloatLine amount value that should be taxed (may not equal the full line amount)
taxfloatCalculated tax value for all line items
taxIncludedbooleanFlag to indicate if line amount includes tax value
rulesarrayAn array of tax rules applied to the current line
Rule structure
FieldTypeComment
taxIdstringTax rule identifier. Should be the same for equal rule types for proper grouping on the Centra side
taxNamestringName of the tax rule
taxableAmountfloatLine amount value that should be taxed by current rule (may not equal the full line amount)
ratefloatTax rate value, absolute (should be contained between 0 and 1)
taxfloatCalculated tax value for the current line and rule

Error

See Error response.

Delivery request/response structure#

Request#

Headers

See Request headers.

Body

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 { "data": { "requestType": "calculateDeliveryTaxNoCommit", "taxEngine": "custom", "entityId": "31-1", "customerCode": "100", "transactionDate": "2023-04-15", "lines": [ { "id": "1122", "quantity": 1, "amount": 100, "taxCode": "code123", "taxIncluded": false, "addresses": { "shipFrom": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 111" }, "shipTo": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 222" } }, "sku": "Product123Variant456Size789", "description": "TestProduct1", "productNumber": "Product123" }, { "id": "1123", "quantity": 1, "amount": 200, "taxCode": "code456", "taxIncluded": false, "addresses": { "shipFrom": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 111" }, "shipTo": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 222" } }, "sku": "Product456Variant789Size012", "description": "TestProduct2", "productNumber": "Product456" } ] } }
Delivery structure
FieldTypeComment
requestTypestring, one of: calculateDeliveryTaxNoCommit, calculateDeliveryTaxAndCommitThe request type indicates which type of calculation should be done on the ETE side
taxEnginestringAlways equals custom
entityIdstringEntity ID, here represents Centra shipment ID
customerCodestringCustomer code, required primarily for tax exempt identification. For value explanation, see more on Customer code definition
companyCode (optional)stringCompany code, used for transaction assigning to specific company in case of multi-company setup. See more on Company code definition
customerExemptionCode (optional)stringCustomer exemption code, used for tax exempt identification. See more on Customer exemption code assignment
transactionDatestring, in YYYY-MM-DD formatCalculation date (current date by default but also may take past values, e.g. shipment creation date or shipment completion date)
linesarrayShipment lines for calculation
Line structure
FieldTypeComment
idstring or integerShipment line ID
quantityintegerQuantity of items shipped
amountfloatThe sum of items' prices. Amount value may be negative in some cases (see more on Discount handling or Additional costs handling)
taxCodestringTax identifier, used to define the proper tax rate
taxIncludedbooleanFlag to indicate if line amount includes the tax value
addressesobject of addressesShipping addresses information. The object may contain either shipFrom or shipTo address or both at the same time
sku (optional)stringFull item SKU (product + variant + size)
description (optional)stringItem description
productNumber (optional)stringa.k.a. Product SKU
Address structure
FieldTypeComment
countrystringCountry ISO code (2 symbols)
postalCode (optional)stringPostal code
state (optional)stringState ISO code (2 symbols)
city (optional)stringCity
line1 (optional)stringAddress line 1
line2 (optional)stringAddress line 2

Response#

Success

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 { "data": { "transactionId": "uniq-trans-id-456", "transactionType": "delivery-custom-operation-type-string", "totalTax": 19.18, "totalDiscount": null, "lines": [ { "id": "1122", "quantity": 1, "amount": 100, "taxableAmount": 96.5, "tax": 6.39, "taxIncluded": false, "rules": [ { "taxId": "32b71e721c4fe0d80c922ed0e0badd3c", "taxName": "NJ STATE TAX", "taxableAmount": 96.5, "rate": 0.06625, "tax": 6.39 } ] }, { "id": "1123", "quantity": 1, "amount": 200, "taxableAmount": 193, "tax": 12.79, "taxIncluded": false, "rules": [ { "taxId": "32b71e721c4fe0d80c922ed0e0badd3c", "taxName": "NJ STATE TAX", "taxableAmount": 193, "rate": 0.06625, "tax": 12.79 } ] } ] } }
Delivery structure
FieldTypeComment
transactionIdstringCalculation result ID assigned by external tax calculator
transactionTypestringType of calculated action assigned by external tax calculator. May be any string that will help you to indicate which operation has been done on your tax engine side (like order/delivery/return calculation, committed or not committed). You can either specify your own type or send back the type you received in the request
totalTaxfloatTotal tax value
totalDiscount (optional)float or nullTotal discount value
linesarrayTax info per shipment line
Line structure
FieldTypeComment
idstringShipment line ID
quantityintegerQuantity of items shipped
amountfloatThe sum of items' prices
taxableAmountfloatLine amount value that should be taxed (may not equal the full line amount)
taxfloatCalculated tax value for all line items
taxIncludedbooleanFlag to indicate if line amount includes tax value
rulesarrayAn array of tax rules applied to the current line
Rule structure
FieldTypeComment
taxIdstringTax rule identifier. Should be the same for equal rule types for proper grouping on the Centra side
taxNamestringName of the tax rule
taxableAmountfloatLine amount value that should be taxed by current rule (may not equal the full line amount)
ratefloatTax rate value, absolute (should be contained between 0 and 1)
taxfloatCalculated tax value for the current line and rule

Error

See Error response.

Return request/response structure#

Request#

Headers

See Request headers.

Body

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 { "data": { "requestType": "calculateReturnTaxAndCommit", "taxEngine": "custom", "entityId": "31-1-2", "parentEntityId": "31-1", "customerCode": "100", "transactionDate": "2023-04-17", "taxationDate": "2023-04-15", "lines": [ { "id": "15", "quantity": 1, "amount": -100, "taxCode": "code123", "taxIncluded": false, "addresses": { "shipFrom": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 111" }, "shipTo": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 222" } }, "sku": "Product123Variant456Size789", "description": "TestProduct1", "productNumber": "Product123" }, { "id": "16", "quantity": 1, "amount": -200, "taxCode": "code456", "taxIncluded": false, "addresses": { "shipFrom": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 111" }, "shipTo": { "country": "US", "postalCode": "07936", "state": "NJ", "city": "East Hanover", "line1": "27 Merry Ln", "line2": "apt. 222" } }, "sku": "Product456Variant789Size012", "description": "TestProduct2", "productNumber": "Product456" } ] } }
Return structure
FieldTypeComment
requestTypestring, one of: calculateReturnTaxNoCommit, calculateReturnTaxAndCommitThe request type indicates which type of calculation should be done on the ETE side
taxEnginestringAlways equals custom
entityIdstringEntity ID, here represents Centra return ID
parentEntityIdstringParent entity ID, here represents Centra shipment ID
customerCodestringCustomer code, required primarily for tax exempt identification. For value explanation, see more on Customer code definition
companyCode (optional)stringCompany code, used for transaction assigning to specific company in case of multi-company setup. See more on Company code definition
customerExemptionCode (optional)stringCustomer exemption code, used for tax exempt identification. See more on Customer exemption code assignment
transactionDatestring, in YYYY-MM-DD formatCalculation date (current date by default but also may take past values, e.g. return creation date or return completion date)
taxationDatestring, in YYYY-MM-DD formatTaxation date (date when the shipment has been completed, required for proper tax value calculation for return)
linesarrayReturn lines for calculation

taxationDate should be used in tax calculation for items that are returned to make sure the same tax rules and rates are applied, and that refund value will not be undertaxed or overtaxed. transactionDate here serves as the actual date when the return has been initiated.

Line structure
FieldTypeComment
idstring or integerReturn line ID
quantityintegerQuantity of items returned
amountfloatThe sum of items' prices. Amount value may be positive, e.g. because of discount returns (see more on Discount handling) or additional cost application (see more on Additional costs handling)
taxCodestringTax identifier, used to define the proper tax rate
taxIncludedbooleanFlag to indicate if line amount includes the tax value
addressesobject of addressesShipping addresses information. The object may contain either shipFrom or shipTo address or both at the same time
sku (optional)stringFull item SKU (product + variant + size)
description (optional)stringItem description
productNumber (optional)stringa.k.a. Product SKU
Address structure
FieldTypeComment
countrystringCountry ISO code (2 symbols)
postalCode (optional)stringPostal code
state (optional)stringState ISO code (2 symbols)
city (optional)stringCity
line1 (optional)stringAddress line 1
line2 (optional)stringAddress line 2

Response#

Success

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 { "data": { "transactionId": "uniq-trans-id-789", "transactionType": "return-custom-operation-type-string", "totalTax": -19.18, "totalDiscount": null, "lines": [ { "id": "15", "quantity": 1, "amount": -100, "taxableAmount": -96.5, "tax": -6.39, "taxIncluded": false, "rules": [ { "taxId": "32b71e721c4fe0d80c922ed0e0badd3c", "taxName": "NJ STATE TAX", "taxableAmount": -96.5, "rate": 0.06625, "tax": -6.39 } ] }, { "id": "16", "quantity": 1, "amount": -200, "taxableAmount": -193, "tax": -12.79, "taxIncluded": false, "rules": [ { "taxId": "32b71e721c4fe0d80c922ed0e0badd3c", "taxName": "NJ STATE TAX", "taxableAmount": -193, "rate": 0.06625, "tax": -12.79 } ] } ] } }
Return structure
FieldTypeComment
transactionIdstringCalculation result ID assigned by external tax calculator
transactionTypestringType of calculated action assigned by external tax calculator. May be any string that will help you to indicate which operation has been done on your tax engine side (like order/delivery/return calculation, committed or not committed). You can either specify your own type or send back the type you received in the request
totalTaxfloatTotal tax value
totalDiscount (optional)float or nullTotal discount value
linesarrayTax info per return line
Line structure
FieldTypeComment
idstringReturn line ID
quantityintegerQuantity of items returned
amountfloatThe sum of items' prices
taxableAmountfloatLine amount value that should be taxed (may not equal the full line amount)
taxfloatCalculated tax value for all line items
taxIncludedbooleanFlag to indicate if line amount includes tax value
rulesarrayAn array of tax rules applied to the current line
Rule structure
FieldTypeComment
taxIdstringTax rule identifier. Should be the same for equal rule types for proper grouping on the Centra side
taxNamestringName of the tax rule
taxableAmountfloatLine amount value that should be taxed by current rule (may not equal the full line amount)
ratefloatTax rate value, absolute (should be contained between 0 and 1)
taxfloatCalculated tax value for the current line and rule

Error

See Error response.

Test connection request/response structure#

Request#

Headers

See Request headers.

Body

1 2 3 4 5 6 { "data": { "requestType": "testTaxEngineConnection", "taxEngine": "custom" } }
Test connection request structure
FieldTypeComment
requestTypestringAlways equals to testTaxEngineConnection
taxEnginestringAlways equals custom

Response#

Success

A successful request body will be ignored, so it's enough for your ETE to respond with a 2xx response code with no or empty body.

1 {}

Error

See Error response.