TaxEngineAdapter Interface

Retrieves information from the tax engine and evaluates the information to define tax details.

Namespace

CommerceTax

TaxEngineAdapter Methods

Learn more about the available methods with the TaxEngineAdapter class.

The TaxEngineAdapter class includes these methods.

processRequest(requestType)

The processRequest method takes an instance of TaxEngineContext class and returns a response with the calculated tax details through the TaxDetailsResponse class or an error response through the ErrorResponse class.

Signature

global commercetax.TaxEngineResponse processRequest(commercetax.TaxEngineContext var1)

Parameters

var1
Type: TaxEngineContext
Wrapper class that stores information about the type of a tax calculation request.

Return Value

Type: TaxEngineResponse

Generic interface representing a response from a tax engine.

TaxEngineAdapter Example Implementation

Refer to the example implementation of the TaxEngineAdapter interface to accept information from a tax engine and evaluate the information to define tax details.

Namespace

commercetax

Usage

The TaxEngineAdapter interface accepts information from the tax engine through the TaxEngineContext class. The interface evaluates the information to define tax in the response with details, such as tax amount and addresses. The response is used to update and create entities in the Salesforce org.

Use these steps to build a sample tax adapter implementation. Each tax adapter implementation varies based on your implementation requirements. Customize this example to suit your business requirements.

Example

  • The custom adapter class implements the TaxEngineAdapter interface. The processRequest method takes an instance of TaxEngineContext class and returns a response with the calculated tax details through the TaxDetailsResponse class or an error response through the ErrorResponse class.

    1global virtual class AvalaraAdapter implements commercetax.TaxEngineAdapter {
    2    global commercetax.TaxEngineResponse processRequest(commercetax.TaxEngineContext taxEngineContext) {
    3        commercetax.RequestType requestType = taxEngineContext.getRequestType();
    4        if(requestType == commercetax.RequestType.CalculateTax){
    5            return CalculateTaxService.getTax(taxEngineContext);
    6        }
    7        else 
    8            return null;
    9    }
    10}
  • This example shows the CalculateTaxService class.

    1global class CalculateTaxService {
    2    // ============================================================================
    3    // CONSTANT 
    4    // ============================================================================
    5    private static final String AVALARA_ENDPOINT_URL_SANDBOX = 'https://sandbox-rest.avatax.com/api/v2';
    6    // Avalara Endpoint URL Production
    7    private static final String AVALARA_ENDPOINT_URL_PRODUCTION = 'https://rest.avatax.com/api/v2';
    8    private static final String TEST_REQUEST_BODY = '{  "id": -1,  "code": "00000131",  "companyId": -1,  "date": "2017-02-03T00:00:00",  "taxDate": "2017-02-03T00:00:00",  "status": "Temporary",  "type": "SalesOrder",  "reconciled": false,  "totalAmount": 4000,  "totalExempt": 0,  "totalTax": 290,  "totalTaxable": 4000,  "totalTaxCalculated": 290,  "adjustmentReason": "NotAdjusted",  "locked": false,  "version": 1,  "modifiedDate": "2017-02-03T12:18:18.7347388Z",  "modifiedUserId": 53894,  "lines": [    {      "id": -1,      "transactionId": -1,      "lineNumber": "80241000000jNDCAA2",      "discountAmount": 0,      "exemptAmount": 0,      "exemptCertId": 0,      "isItemTaxable": true,      "lineAmount": 1000,      "reportingDate": "2017-02-03T00:00:00",      "tax": 72.5,      "taxableAmount": 1000,      "taxCalculated": 72.5,      "taxCode": "P0000000",      "taxDate": "2017-02-03T00:00:00",      "taxIncluded": false,      "details": [        {          "id": -1,          "transactionLineId": -1,          "transactionId": -1,          "country": "US",          "region": "CA",          "exemptAmount": 0,          "jurisCode": "06",          "jurisName": "CALIFORNIA",          "stateAssignedNo": "",          "jurisType": "STA",          "nonTaxableAmount": 0,          "rate": 0.06,          "tax": 60,          "taxableAmount": 1000,          "taxType": "Sales",          "taxName": "CA STATE TAX",          "taxAuthorityTypeId": 45,          "taxCalculated": 60,          "rateType": "General"        },        {          "id": -1,          "transactionLineId": -1,          "transactionId": -1,          "country": "US",          "region": "CA",          "exemptAmount": 0,          "jurisCode": "075",          "jurisName": "SAN FRANCISCO",          "stateAssignedNo": "",          "jurisType": "CTY",          "nonTaxableAmount": 0,          "rate": 0.0025,          "tax": 2.5,          "taxableAmount": 1000,          "taxType": "Sales",          "taxName": "CA COUNTY TAX",          "taxAuthorityTypeId": 45,          "taxCalculated": 2.5,          "rateType": "General"        },        {          "id": -1,          "transactionLineId": -1,          "transactionId": -1,          "country": "US",          "region": "CA",          "exemptAmount": 0,          "jurisCode": "EMTV0",          "jurisName": "SAN FRANCISCO CO LOCAL TAX SL",          "stateAssignedNo": "38",          "jurisType": "STJ",          "nonTaxableAmount": 0,          "rate": 0.01,          "tax": 10,          "taxableAmount": 1000,          "taxType": "Sales",          "taxName": "CA SPECIAL TAX",          "taxAuthorityTypeId": 45,          "taxCalculated": 10,          "rateType": "General"        }      ]    }  ]}';
    9    
    10    private static String getTestResponseString(){
    11    
    12     List<String> jsonResponse = new List<String> {
    13                                    '"id": 0',
    14                                    '"code": "testDocCode1231245984"',
    15                                    '"companyId": 468039',
    16                                    '"date": "2020-07-15"',
    17                                    '"paymentDate": "2020-07-15"',
    18                                    '"status": "Temporary"',
    19                                    '"type": "SalesOrder"',
    20                                    '"customerVendorCode": "testDocCode1234"',
    21                                    '"customerCode": "testDocCode1234"',
    22                                    '"reconciled": false',
    23                                    '"totalAmount": 232',
    24                                    '"totalExempt": 0',
    25                                    '"totalDiscount": 0',
    26                                    '"totalTax": 23.43',
    27                                    '"totalTaxable": 232',
    28                                    '"totalTaxCalculated": 23.43',
    29                                    '"adjustmentReason": "NotAdjusted"',
    30                                    '"locked": false',
    31                                    '"version": 1',
    32                                    '"exchangeRateEffectiveDate": "2020-07-15"',
    33                                    '"exchangeRate": 1',
    34                                    '"modifiedDate": "2020-08-13T11:19:20.4836636Z"',
    35                                    '"modifiedUserId": 53894',
    36                                    '"taxDate": "2020-07-15T00:00:00"',
    37                                    '"lines": [{"id": 0,"transactionId": 0,"lineNumber": "1","discountAmount": 0,"exemptAmount": 0,"exemptCertId": 0,"isItemTaxable": true,"itemCode": "","lineAmount": 232,"quantity": 1,"reportingDate": "2020-07-15","tax": 23.43,"taxableAmount": 232,"taxCalculated": 23.43,"taxCode": "P0000000","taxCodeId": 8087,"taxDate": "2020-07-15","taxOverrideType": "None","taxOverrideAmount": 0,"taxIncluded": false,"details": [{"id": 0,"transactionLineId": 0,"transactionId": 0,"country": "US","region": "WA","exemptAmount": 0,"jurisCode": "53","jurisName": "WASHINGTON","stateAssignedNo": "","jurisType": "STA","jurisdictionType": "State","nonTaxableAmount": 0,"rate": 0.065,"tax": 15.08,"taxableAmount": 232,"taxType": "Sales","taxSubTypeId": "S","taxName": "WA STATE TAX","taxAuthorityTypeId": 45,"taxCalculated": 15.08,"rateType": "General","rateTypeCode": "G","unitOfBasis": "PerCurrencyUnit","isNonPassThru": false,"isFee": false},{"id": 0,"transactionLineId": 0,"transactionId": 0,"country": "US","region": "WA","exemptAmount": 0,"jurisCode": "033","jurisName": "KING","stateAssignedNo": "1700","jurisType": "CTY","jurisdictionType": "County","nonTaxableAmount": 0,"rate": 0,"tax": 0,"taxableAmount": 232,"taxType": "Sales","taxSubTypeId": "S","taxName": "WA COUNTY TAX","taxAuthorityTypeId": 45,"taxCalculated": 0,"rateType": "General","rateTypeCode": "G","unitOfBasis": "PerCurrencyUnit","isNonPassThru": false,"isFee": false}],"nonPassthroughDetails": [],"hsCode": "","costInsuranceFreight": 0,"vatCode": "","vatNumberTypeId": 0}]',
    38                                    '"addresses": [{"id": 0,"transactionId": 0,"boundaryLevel": "Address","line1": "255 S. King Street","line2": "","line3": "","city": "Seattle","region": "WA","postalCode": "98104","country": "US","taxRegionId": 2109700,"latitude": "47.59821","longitude": "-122.33108"}]',
    39                                    '"summary": [{"country": "US","region": "WA","jurisType": "State","jurisCode": "53","jurisName": "WASHINGTON","taxAuthorityType": 45,"stateAssignedNo": "","taxType": "Sales","taxSubType": "S","taxName": "WA STATE TAX","rateType": "General","taxable": 232,"rate": 0.065,"tax": 15.08,"taxCalculated": 15.08,"nonTaxable": 0,"exemption": 0},{"country": "US","region": "WA","jurisType": "County","jurisCode": "033","jurisName": "KING","taxAuthorityType": 45,"stateAssignedNo": "1700","taxType": "Sales","taxSubType": "S","taxName": "WA COUNTY TAX","rateType": "General","taxable": 232,"rate": 0,"tax": 0,"taxCalculated": 0,"nonTaxable": 0,"exemption": 0}]'
    40                                };
    41            return '{' + String.join(jsonResponse, ',') + '}';
    42        }
    43    
    44    public static commercetax.TaxEngineResponse getTax(commercetax.TaxEngineContext taxEngineContext) 
    45    { 
    46        commercetax.CalculateTaxRequest request = (commercetax.CalculateTaxRequest)taxEngineContext.getRequest();
    47        commercetax.calculatetaxtype requestType = request.taxtype;
    48        string referenceEntity = request.ReferenceEntityId;
    49        try{
    50            List<commercetax.TaxLineItemRequest> listOfLines = request.lineItems;
    51            if(!listOfLines.isEmpty()){
    52                HttpService sendHttpRequest = new HttpService();
    53                sendHttpRequest.addHeader('Content-type', 'application/json');
    54                String requestBody = AvalaraJSONBuilder.getInstance().frameJsonForGetTaxOrderItem(request);
    55                sendHttpRequest.post('/transactions/create',requestBody);
    56                //system.debug('Request '+requestBody);
    57                String responseString = '';
    58                if(Test.isRunningTest()){
    59                    responseString = getTestResponseString();
    60                } else{
    61                    responseString = sendHttpRequest.getResponse().getBody();
    62                }
    63                //system.debug(sendHttpRequest.getResponse());
    64                //system.debug('response'+responseString);
    65                //responseString = TEST_REQUEST_BODY;
    66                system.debug('Heap size used ' +Limits.getHeapSize());
    67                
    68                if(!responseString.contains('error'))
    69                {
    70                    commercetax.CalculateTaxResponse response = new commercetax.CalculateTaxResponse();
    71                    JsonSuccessParser jsonSuccessParserClass = JsonSuccessParser.parse(responseString);
    72                    response.setTaxTransactionType(request.taxTransactionType);
    73                    response.setDocumentCode(jsonSuccessParserClass.code);
    74                    response.setReferenceDocumentCode(jsonSuccessParserClass.referenceCode);
    75                    if(jsonSuccessParserClass.status == 'Temporary')  {
    76                        response.setStatus(commercetax.TaxTransactionStatus.Uncommitted);
    77                    }
    78                    if(jsonSuccessParserClass.status == 'Committed') {
    79                        response.setStatus(commercetax.TaxTransactionStatus.Committed);
    80                    }
    81                    response.setTaxType(requestType);
    82                    commercetax.AmountDetailsResponse headerAmountResponse = new commercetax.AmountDetailsResponse();
    83                    headerAmountResponse.setTotalAmountWithTax(jsonSuccessParserClass.totalAmount + jsonSuccessParserClass.totaltax);
    84                    headerAmountResponse.setExemptAmount(jsonSuccessParserClass.totalExempt);
    85                    headerAmountResponse.setTotalAmount(jsonSuccessParserClass.totalAmount);
    86                    headerAmountResponse.setTaxAmount(jsonSuccessParserClass.totalTax);
    87                    response.setAmountDetails(headerAmountResponse);
    88                    response.setStatusDescription(jsonSuccessParserClass.adjustmentReason);
    89                    response.setEffectiveDate(date.valueof(jsonSuccessParserClass.taxDate));
    90                    response.setTransactionDate(date.valueof(jsonSuccessParserClass.transactionDate));
    91                    response.setReferenceEntityId(referenceEntity);
    92                    response.setTaxTransactionId(jsonSuccessParserClass.id);
    93                    response.setCurrencyIsoCode(request.currencyIsoCode);
    94                    List<commercetax.LineItemResponse> lineItemResponses = new List<commercetax.LineItemResponse>();
    95                    for(JsonSuccessParser.Lines linesToProcess: jsonSuccessParserClass.lines)
    96                    {
    97                        commercetax.LineItemResponse lineItemResponse = new commercetax.LineItemResponse();
    98                        Double rateCalculated = 0.0;
    99                        List<commercetax.TaxDetailsResponse> taxDetailsResponses = new List<commercetax.TaxDetailsResponse>();
    100                        for(JsonSuccessParser.details linesDetails : linesToProcess.details)
    101                        {
    102                            commercetax.TaxDetailsResponse taxDetailsResponse = new commercetax.TaxDetailsResponse();
    103                            if(linesDetails.exemptAmount != 0){
    104                                taxDetailsResponse.setExemptAmount(linesDetails.exemptAmount);
    105                                taxDetailsResponse.setExemptReason('Some reason we dont know');
    106                            }
    107                                commercetax.ImpositionResponse imposition = new commercetax.ImpositionResponse();
    108                                    imposition.setSubType(linesDetails.taxName);
    109                                    imposition.setType(linesDetails.ratetype);
    110                                    imposition.setSubType(linesDetails.taxName);
    111                                    taxDetailsResponse.setImposition(imposition);
    112                                commercetax.JurisdictionResponse jurisdiction = new commercetax.JurisdictionResponse();
    113                                    jurisdiction.setCountry(linesDetails.country);
    114                                    jurisdiction.setRegion(linesDetails.region);
    115                                    jurisdiction.setName(linesDetails.jurisName);
    116                                    jurisdiction.setStateAssignedNumber(linesDetails.stateAssignedNo);
    117                                    jurisdiction.setId(linesDetails.jurisCode);
    118                                    jurisdiction.setLevel(linesDetails.jurisType);
    119                                    taxDetailsResponse.setJurisdiction(jurisdiction);
    120                                    rateCalculated += linesDetails.rate; 
    121                                taxDetailsResponse.setRate(rateCalculated);
    122                                taxDetailsResponse.setTax(linesDetails.taxCalculated);
    123                                taxDetailsResponse.setTaxableAmount(linesDetails.taxableAmount);
    124                                taxDetailsResponse.setTaxAuthorityTypeId(String.valueOf(linesDetails.taxAuthorityTypeId));
    125                                taxDetailsResponse.setTaxId(linesDetails.id);
    126                                taxDetailsResponse.setTaxRegionId(linesDetails.region);
    127                                taxDetailsResponses.add(taxDetailsResponse);    
    128                            
    129                        }
    130                            lineItemResponse.setTaxes(taxDetailsResponses);
    131                            lineItemResponse.setEffectiveDate(date.valueof(linesToProcess.taxDate));
    132                            lineItemResponse.setIsTaxable(true);
    133                                commercetax.AmountDetailsResponse amountResponse = new commercetax.AmountDetailsResponse();
    134                                amountResponse.setTaxAmount(linesToProcess.taxCalculated);
    135                                amountResponse.setTotalAmount(linesToProcess.lineAmount);
    136                                amountResponse.setTotalAmountWithTax(linesToProcess.lineAmount+linesToProcess.taxCalculated);
    137                                amountResponse.setExemptAmount(linesToProcess.exemptAmount);
    138                                lineItemResponse.setAmountDetails(amountResponse);
    139                            lineItemResponse.setIsTaxable(linesToProcess.isItemTaxable);
    140                            lineItemResponse.setProductCode(linesToProcess.itemCode);
    141                            lineItemResponse.setTaxCode(linesToProcess.taxCode);
    142                            lineItemResponse.setLineNumber(linesToProcess.lineNumber);
    143                            lineItemResponse.setQuantity(linesToProcess.quantity);
    144                            lineItemResponses.add(lineItemResponse);
    145                    }
    146                    response.setLineItems(lineItemResponses);
    147                    return response;
    148                }
    149                else
    150                {
    151                    JsonErrorParser jsonErrorParserClass = JsonErrorParser.parse(responseString);
    152                    String message = null;
    153                    if(String.isNotBlank(jsonErrorParserClass.error.message))
    154                    {
    155                       message=jsonErrorParserClass.error.message;
    156                    }else{
    157                           String errorMessage = '';
    158                            for(JsonErrorParser.cls_details messageString : jsonErrorParserClass.error.details)
    159                            {
    160                                if(String.isNotBlank(messageString.message) )
    161                                {
    162                                    errorMessage = messageString.message;
    163                                }
    164                            }
    165                            message = errorMessage; 
    166                        }
    167                     return new commercetax.ErrorResponse(commercetax.resultcode.TaxEngineError, '501', message);
    168
    169                }
    170            }else return null;
    171        }
    172        catch (Exception e) 
    173        {
    174            throw e; 
    175        }
    176    }
    177}
  • In the HttpService class, replace the test value in the endpoint variable with the name of the TaxTypedNamedCredential record. This class contains the credentials that are required to access your Avalara account through Salesforce.

    1public with sharing class HttpService 
    2{   
    3    // Attribute to implement singleton pattern for Order Product Service class
    4    private static HttpService httpServiceInstance;
    5    
    6    // VARIABLES
    7    
    8    private HttpResponse httpResponse;
    9    private Map<String,String> mapOfHeaderParameter = new Map<String,String>();
    10    private enum Method {GET, POST}
    11    
    12    /**
    13    * @name getInstance
    14    * @description get an Instance of Service class
    15    * @params NA
    16    * @return Http Service Class Instance
    17    */ 
    18    public static HttpService getInstance() 
    19    {
    20        if (NULL == httpServiceInstance) 
    21        {
    22            httpServiceInstance =  new HttpService();  
    23        }
    24        return httpServiceInstance;
    25    }
    26    
    27    /**
    28    * @name get
    29    * @description Get Method to get a HTTP request
    30    */    
    31    public void get(String endPoint) 
    32    {
    33        send(newRequest(Method.GET, endPoint));
    34    }
    35    
    36    /**
    37    * @name post
    38    * @description Post Method to Post a HTTP request
    39    */ 
    40    public void post(String path, String requestBody)
    41    {
    42       String endPoint = 'callout:commerce.tax.TaxTypedNamedCredential:test'+path;
    43        send(newRequest(Method.POST, endPoint, requestBody));
    44    }
    45    
    46    /**
    47    * @name addHeader
    48    * @description addHeader Methods to add all the defualt Header's required fo rthe request
    49    */
    50    public void addHeader(String name, String value)
    51    {
    52        mapOfHeaderParameter.put(name, value);
    53    }
    54    
    55    /**
    56    * @name setHeader
    57    * @description setHeader Methods to set setHeader for the request
    58    */
    59    private void setHeader(HttpRequest request) 
    60    {
    61        for(String headerValue : mapOfHeaderParameter.keySet())
    62        {
    63            request.setHeader(headerValue, mapOfHeaderParameter.get(headerValue));
    64        }
    65    }
    66    /**
    67    * @name newRequest
    68    * @description newRequest Methods to make a new request
    69    */
    70    private HttpRequest newRequest(Method method, String endPoint)
    71    {
    72        return newRequest(method, endPoint, NULL);
    73    }
    74    
    75    /**
    76    * @name newRequest
    77    * @description newRequest Methods to make a new request
    78    */
    79    private HttpRequest newRequest(Method method, String endPoint, String requestBody) 
    80    {
    81        HttpRequest request = new HttpRequest();
    82        request.setMethod(Method.name());
    83        setHeader(request);
    84        request.setEndpoint(endPoint);
    85        if (String.isNotBlank(requestBody)) 
    86        {
    87            request.setBody(requestBody);
    88        }   
    89        request.setTimeout(120000);
    90        return request;
    91    }
    92    
    93    /**
    94    * @name send
    95    * @description send Methods to send a request
    96    */
    97    private void send(HttpRequest request) 
    98    {
    99        try 
    100        {
    101            Http http = new Http();
    102            httpResponse = http.send(request);
    103        }
    104        catch(System.CalloutException e) 
    105        {
    106            system.debug('callout exception happened' + e.getMessage());
    107        }
    108        catch(Exception e) 
    109        {
    110            system.debug('callout did not happen' + e.getMessage());
    111        }
    112    }
    113    
    114    /**
    115    * @name getResponse
    116    * @description getResponse Method to get the Response
    117    */
    118    public HttpResponse getResponse()
    119    {
    120        return httpResponse;
    121    }
    122    
    123    /**
    124    * @name getResponseToString
    125    * @description getResponse Method to get the Responses
    126    */
    127    public String getResponseToString()
    128    {
    129        return getResponse().toString();
    130    }
    131}
  • Parse the JsonSuccessParser response object by using the AvalaraJSONBuilder class to build the response for your adapter.

    This example shows the JsonSuccessParser class.

    1global with sharing class JsonSuccessParser
    2{
    3  public static void consumeObject(JSONParser parser)
    4  {
    5    Integer depth = 0;
    6    do {
    7      JSONToken curr = parser.getCurrentToken();
    8      if (curr == JSONToken.START_OBJECT ||
    9        curr == JSONToken.START_ARRAY) {
    10        depth++;
    11      } else if (curr == JSONToken.END_OBJECT ||
    12        curr == JSONToken.END_ARRAY) {
    13        depth--;
    14      }
    15    } while (depth > 0 && parser.nextToken() != null);
    16  }
    17
    18    public class Addresses {
    19        public String id {get;set;}
    20        public String transactionId {get;set;}
    21        public String boundaryLevel {get;set;}
    22        public String line1 {get;set;}
    23        public String city {get;set;}
    24        public String region {get;set;}
    25        public String postalCode {get;set;}
    26        public String country {get;set;}
    27        public Integer taxRegionId {get;set;}
    28
    29        public Addresses(JSONParser parser) {
    30            while (parser.nextToken() != JSONToken.END_OBJECT) {
    31                if (parser.getCurrentToken() == JSONToken.FIELD_NAME) {
    32                    String text = parser.getText();
    33                    if (parser.nextToken() != JSONToken.VALUE_NULL) {
    34                        if (text == 'id') {
    35                            id = parser.getText();
    36                        } else if (text == 'transactionId') {
    37                            transactionId = parser.getText();
    38                        } else if (text == 'boundaryLevel') {
    39                            boundaryLevel = parser.getText();
    40                        } else if (text == 'line1') {
    41                            line1 = parser.getText();
    42                        } else if (text == 'city') {
    43                            city = parser.getText();
    44                        } else if (text == 'region') {
    45                            region = parser.getText();
    46                        } else if (text == 'postalCode') {
    47                            postalCode = parser.getText();
    48                        } else if (text == 'country') {
    49                            country = parser.getText();
    50                        } else if (text == 'taxRegionId') {
    51                            taxRegionId = parser.getIntegerValue();
    52                        } else {
    53                            consumeObject(parser);
    54                        }
    55                    }
    56                }
    57            }
    58        }
    59    }
    60
    61    public class Details {
    62        public String id {get;set;}
    63        public String transactionLineId {get;set;}
    64        public String transactionId {get;set;}
    65        public String country {get;set;}
    66        public String region {get;set;}
    67        public Integer exemptAmount {get;set;}
    68        public String jurisCode {get;set;}
    69        public String jurisName {get;set;}
    70        public String stateAssignedNo {get;set;}
    71        public String jurisType {get;set;}
    72        public Integer nonTaxableAmount {get;set;}
    73        public Double rate {get;set;}
    74        public Double tax {get;set;}
    75        public Integer taxableAmount {get;set;}
    76        public String taxType {get;set;}
    77        public String taxName {get;set;}
    78        public Integer taxAuthorityTypeId {get;set;}
    79        public Double taxCalculated {get;set;}
    80        public String rateType {get;set;}
    81
    82        public Details(JSONParser parser) {
    83            while (parser.nextToken() != JSONToken.END_OBJECT) {
    84                if (parser.getCurrentToken() == JSONToken.FIELD_NAME) {
    85                    String text = parser.getText();
    86                    if (parser.nextToken() != JSONToken.VALUE_NULL) {
    87                        if (text == 'id') {
    88                            id = parser.getText();
    89                        } else if (text == 'transactionLineId') {
    90                            transactionLineId = parser.getText();
    91                        } else if (text == 'transactionId') {
    92                            transactionId = parser.getText();
    93                        } else if (text == 'country') {
    94                            country = parser.getText();
    95                        } else if (text == 'region') {
    96                            region = parser.getText();
    97                        } else if (text == 'exemptAmount') {
    98                            exemptAmount = parser.getIntegerValue();
    99                        } else if (text == 'jurisCode') {
    100                            jurisCode = parser.getText();
    101                        } else if (text == 'jurisName') {
    102                            jurisName = parser.getText();
    103                        } else if (text == 'stateAssignedNo') {
    104                            stateAssignedNo = parser.getText();
    105                        } else if (text == 'jurisType') {
    106                            jurisType = parser.getText();
    107                        } else if (text == 'nonTaxableAmount') {
    108                            nonTaxableAmount = parser.getIntegerValue();
    109                        } else if (text == 'rate') {
    110                            rate = parser.getDoubleValue();
    111                        } else if (text == 'tax') {
    112                            tax = parser.getDoubleValue();
    113                        } else if (text == 'taxableAmount') {
    114                            taxableAmount = parser.getIntegerValue();
    115                        } else if (text == 'taxType') {
    116                            taxType = parser.getText();
    117                        } else if (text == 'taxName') {
    118                            taxName = parser.getText();
    119                        } else if (text == 'taxAuthorityTypeId') {
    120                            taxAuthorityTypeId = parser.getIntegerValue();
    121                        } else if (text == 'taxCalculated') {
    122                            taxCalculated = parser.getDoubleValue();
    123                        } else if (text == 'rateType') {
    124                            rateType = parser.getText();
    125                        } else {
    126                            consumeObject(parser);
    127                        }
    128                    }
    129                }
    130            }
    131        }
    132    }
    133
    134    public class Messages {
    135        public String summary {get;set;}
    136        public String details {get;set;}
    137        public String refersTo {get;set;}
    138        public String severity {get;set;}
    139        public String source {get;set;}
    140
    141        public Messages(JSONParser parser) {
    142            while (parser.nextToken() != JSONToken.END_OBJECT) {
    143                if (parser.getCurrentToken() == JSONToken.FIELD_NAME) {
    144                    String text = parser.getText();
    145                    if (parser.nextToken() != JSONToken.VALUE_NULL) {
    146                        if (text == 'summary') {
    147                            summary = parser.getText();
    148                        } else if (text == 'details') {
    149                            details = parser.getText();
    150                        } else if (text == 'refersTo') {
    151                            refersTo = parser.getText();
    152                        } else if (text == 'severity') {
    153                            severity = parser.getText();
    154                        } else if (text == 'source') {
    155                            source = parser.getText();
    156                        } else {
    157                            consumeObject(parser);
    158                        }
    159                    }
    160                }
    161            }
    162        }
    163    }
    164
    165    public String id {get;set;}
    166    public String code {get;set;}
    167    public String referenceCode {get;set;}
    168    public Integer companyId {get;set;}
    169    public String taxDate {get;set;}
    170    public String transactionDate {get;set;}
    171    public String status {get;set;}
    172    public String type_Z {get;set;} // in json: type
    173    public Boolean reconciled {get;set;}
    174    public Integer totalAmount {get;set;}
    175    public Integer totalExempt {get;set;}
    176    public Double totalTax {get;set;}
    177    public Integer totalTaxable {get;set;}
    178    public Double totalTaxCalculated {get;set;}
    179    public String adjustmentReason {get;set;}
    180    public Boolean locked {get;set;}
    181    public Integer version {get;set;}
    182    public String modifiedDate {get;set;}
    183    public Integer modifiedUserId {get;set;}
    184    public List<Lines> lines {get;set;}
    185    public List<Addresses> addresses {get;set;}
    186    public List<Summary> summary {get;set;}
    187    public List<Messages> messages {get;set;}
    188
    189    public JsonSuccessParser(JSONParser parser) {
    190        while (parser.nextToken() != JSONToken.END_OBJECT) {
    191            if (parser.getCurrentToken() == JSONToken.FIELD_NAME) {
    192                String text = parser.getText();
    193                if (parser.nextToken() != JSONToken.VALUE_NULL) {
    194                    if (text == 'id') {
    195                        id = parser.getText();
    196                    } else if (text == 'code') {
    197                        code = parser.getText();
    198                    } else if (text == 'referenceCode'){
    199                        referenceCode = parser.getText();
    200                    } else if (text == 'companyId') {
    201                        companyId = parser.getIntegerValue();
    202                    } else if (text == 'taxDate') {
    203                        taxDate = parser.getText();
    204                    } else if (text == 'date') {
    205                        transactionDate = parser.getText();
    206                    } else if (text == 'status') {
    207                        status = parser.getText();
    208                    } else if (text == 'type') {
    209                        type_Z = parser.getText();
    210                    } else if (text == 'reconciled') {
    211                        reconciled = parser.getBooleanValue();
    212                    } else if (text == 'totalAmount') {
    213                        totalAmount = parser.getIntegerValue();
    214                    } else if (text == 'totalExempt') {
    215                        totalExempt = parser.getIntegerValue();
    216                    } else if (text == 'totalTax') {
    217                        totalTax = parser.getDoubleValue();
    218                    } else if (text == 'totalTaxable') {
    219                        totalTaxable = parser.getIntegerValue();
    220                    } else if (text == 'totalTaxCalculated') {
    221                        totalTaxCalculated = parser.getDoubleValue();
    222                    } else if (text == 'adjustmentReason') {
    223                        adjustmentReason = parser.getText();
    224                    } else if (text == 'locked') {
    225                        locked = parser.getBooleanValue();
    226                    } else if (text == 'version') {
    227                        version = parser.getIntegerValue();
    228                    } else if (text == 'modifiedDate') {
    229                        modifiedDate = parser.getText();
    230                    } else if (text == 'modifiedUserId') {
    231                        modifiedUserId = parser.getIntegerValue();
    232                    } else if (text == 'lines') {
    233                        lines = new List<Lines>();
    234                        while (parser.nextToken() != JSONToken.END_ARRAY) {
    235                            lines.add(new Lines(parser));
    236                        }
    237                    } else if (text == 'addresses') {
    238                        addresses = new List<Addresses>();
    239                        while (parser.nextToken() != JSONToken.END_ARRAY) {
    240                            addresses.add(new Addresses(parser));
    241                        }
    242                    } else if (text == 'summary') {
    243                        summary = new List<Summary>();
    244                        while (parser.nextToken() != JSONToken.END_ARRAY) {
    245                            summary.add(new Summary(parser));
    246                        }
    247                    } else if (text == 'messages') {
    248                        messages = new List<Messages>();
    249                        while (parser.nextToken() != JSONToken.END_ARRAY) {
    250                            messages.add(new Messages(parser));
    251                        }
    252                    } else {
    253                        consumeObject(parser);
    254                    }
    255                }
    256            }
    257        }
    258    }
    259
    260    public class Summary {
    261        public String country {get;set;}
    262        public String region {get;set;}
    263        public String jurisType {get;set;}
    264        public String jurisCode {get;set;}
    265        public String jurisName {get;set;}
    266        public Integer taxAuthorityType {get;set;}
    267        public String stateAssignedNo {get;set;}
    268        public String taxType {get;set;}
    269        public String taxName {get;set;}
    270        public String taxGroup {get;set;}
    271        public String rateType {get;set;}
    272        public Integer taxable {get;set;}
    273        public Double rate {get;set;}
    274        public Double tax {get;set;}
    275        public Double taxCalculated {get;set;}
    276        public Integer nonTaxable {get;set;}
    277        public Integer exemption {get;set;}
    278
    279        public Summary(JSONParser parser) {
    280            while (parser.nextToken() != JSONToken.END_OBJECT) {
    281                if (parser.getCurrentToken() == JSONToken.FIELD_NAME) {
    282                    String text = parser.getText();
    283                    if (parser.nextToken() != JSONToken.VALUE_NULL) {
    284                        if (text == 'country') {
    285                            country = parser.getText();
    286                        } else if (text == 'region') {
    287                            region = parser.getText();
    288                        } else if (text == 'jurisType') {
    289                            jurisType = parser.getText();
    290                        } else if (text == 'jurisCode') {
    291                            jurisCode = parser.getText();
    292                        } else if (text == 'jurisName') {
    293                            jurisName = parser.getText();
    294                        } else if (text == 'taxAuthorityType') {
    295                            taxAuthorityType = parser.getIntegerValue();
    296                        } else if (text == 'stateAssignedNo') {
    297                            stateAssignedNo = parser.getText();
    298                        } else if (text == 'taxType') {
    299                            taxType = parser.getText();
    300                        } else if (text == 'taxName') {
    301                            taxName = parser.getText();
    302                        } else if (text == 'taxGroup') {
    303                            taxGroup = parser.getText();
    304                        } else if (text == 'rateType') {
    305                            rateType = parser.getText();
    306                        } else if (text == 'taxable') {
    307                            taxable = parser.getIntegerValue();
    308                        } else if (text == 'rate') {
    309                            rate = parser.getDoubleValue();
    310                        } else if (text == 'tax') {
    311                            tax = parser.getDoubleValue();
    312                        } else if (text == 'taxCalculated') {
    313                            taxCalculated = parser.getDoubleValue();
    314                        } else if (text == 'nonTaxable') {
    315                            nonTaxable = parser.getIntegerValue();
    316                        } else if (text == 'exemption') {
    317                            exemption = parser.getIntegerValue();
    318                        } else {
    319                            consumeObject(parser);
    320                        }
    321                    }
    322                }
    323            }
    324        }
    325    }
    326
    327    public class Lines {
    328        public String id {get;set;}
    329        public String transactionId {get;set;}
    330        public String lineNumber {get;set;}
    331        public Integer discountAmount {get;set;}
    332        public Integer exemptAmount {get;set;}
    333        public Integer exemptCertId {get;set;}
    334        public Boolean isItemTaxable {get;set;}
    335        public Integer lineAmount {get;set;}
    336        public Double quantity {get;set;}
    337        public String reportingDate {get;set;}
    338        public Double tax {get;set;}
    339        public Integer taxableAmount {get;set;}
    340        public Double taxCalculated {get;set;}
    341        public String taxCode {get;set;}
    342        public String taxDate {get;set;}
    343        public Boolean taxIncluded {get;set;}
    344        public List<Details> details {get;set;}
    345        public String itemCode {get;set;}
    346        public Lines(JSONParser parser) {
    347            while (parser.nextToken() != JSONToken.END_OBJECT) {
    348                if (parser.getCurrentToken() == JSONToken.FIELD_NAME) {
    349                    String text = parser.getText();
    350                    if (parser.nextToken() != JSONToken.VALUE_NULL) {
    351                        if (text == 'id') {
    352                            id = parser.getText();
    353                        } else if (text == 'transactionId') {
    354                            transactionId = parser.getText();
    355                        }else if (text == 'itemCode') {
    356                            itemCode = parser.getText();
    357                        }else if (text == 'lineNumber') {
    358                            lineNumber = parser.getText();
    359                        } else if (text == 'discountAmount') {
    360                            discountAmount = parser.getIntegerValue();
    361                        } else if (text == 'exemptAmount') {
    362                            exemptAmount = parser.getIntegerValue();
    363                        } else if (text == 'exemptCertId') {
    364                            exemptCertId = parser.getIntegerValue();
    365                        } else if (text == 'isItemTaxable') {
    366                            isItemTaxable = parser.getBooleanValue();
    367                        } else if (text == 'lineAmount') {
    368                            lineAmount = parser.getIntegerValue();
    369                        } else if (text == 'quantity') {
    370                            quantity = parser.getDoubleValue();
    371                        } else if (text == 'reportingDate') {
    372                            reportingDate = parser.getText();
    373                        } else if (text == 'tax') {
    374                            tax = parser.getDoubleValue();
    375                        } else if (text == 'taxableAmount') {
    376                            taxableAmount = parser.getIntegerValue();
    377                        } else if (text == 'taxCalculated') {
    378                            taxCalculated = parser.getDoubleValue();
    379                        } else if (text == 'taxCode') {
    380                            taxCode = parser.getText();
    381                        } else if (text == 'taxDate') {
    382                            taxDate = parser.getText();
    383                        } else if (text == 'taxIncluded') {
    384                            taxIncluded = parser.getBooleanValue();
    385                        } else if (text == 'details') {
    386                            details = new List<Details>();
    387                            while (parser.nextToken() != JSONToken.END_ARRAY) {
    388                                details.add(new Details(parser));
    389                            }
    390                        } else {
    391                            consumeObject(parser);
    392                        }
    393                    }
    394                }
    395            }
    396        }
    397    }
    398
    399
    400    public static JsonSuccessParser parse(String json)
    401    {
    402        return new JsonSuccessParser(System.JSON.createParser(json));
    403    }
    404}

    Prepare your JSON request to call the Avalara endpoint by using the AvalaraJSONBuilder class.

    1public with sharing class AvalaraJSONBuilder 
    2{
    3    private static AvalaraJSONBuilder avalaraJSONBuilderInstance;
    4    
    5    public static AvalaraJSONBuilder getInstance() 
    6    {
    7        if (NULL == avalaraJSONBuilderInstance) 
    8        {
    9            avalaraJSONBuilderInstance = new AvalaraJSONBuilder();
    10        }
    11        return avalaraJSONBuilderInstance;
    12    }
    13    
    14    public String frameJsonForGetTaxOrderItem(commercetax.CalculateTaxRequest calculateTaxRequest) 
    15    {
    16        try
    17        {
    18            Id accountid  = null;
    19            if(calculateTaxRequest.CustomerDetails.AccountId != null &&  calculateTaxRequest.CustomerDetails.AccountId != '')
    20               accountid = Id.valueof(calculateTaxRequest.CustomerDetails.AccountId);
    21            JSONGenerator jsonGeneratorInstance = JSON.createGenerator(true);
    22            jsonGeneratorInstance.writeStartObject();
    23            String type = null;
    24            if(calculateTaxRequest.taxtype == commercetax.CalculateTaxType.Actual)
    25                type ='SalesInvoice';
    26                else type = 'SalesOrder';
    27            jsonGeneratorInstance.writeStringField('type', type);
    28            if(calculateTaxRequest.SellerDetails != null)
    29                jsonGeneratorInstance.writeStringField('companyCode', calculateTaxRequest.SellerDetails.code);
    30            else 
    31                jsonGeneratorInstance.writeStringField('companyCode', 'billing2');
    32            if(calculateTaxRequest.isCommit != null) {
    33                jsonGeneratorInstance.writeBooleanField('commit', calculateTaxRequest.isCommit);
    34            }
    35            if(calculateTaxRequest.documentcode != null){
    36                jsonGeneratorInstance.writeStringField('code', calculateTaxRequest.documentcode);
    37            }else if(calculateTaxRequest.referenceEntityId != null) {
    38                jsonGeneratorInstance.writeStringField('code', calculateTaxRequest.referenceEntityId);
    39            }
    40            if(calculateTaxRequest.CustomerDetails.code == null && accountid !=null) {
    41                Account acc = [select id, name from account where id=:accountid];
    42                jsonGeneratorInstance.writeStringField('customerCode', acc.name);
    43            } else {
    44                jsonGeneratorInstance.writeStringField('customerCode', calculateTaxRequest.CustomerDetails.code);
    45            }
    46            if(calculateTaxRequest.EffectiveDate == null)
    47                jsonGeneratorInstance.writeDateField('date', system.today());
    48            else         
    49                jsonGeneratorInstance.writeDateTimeField('date', calculateTaxRequest.EffectiveDate);
    50            
    51            jsonGeneratorInstance.writeFieldName('lines');
    52            jsonGeneratorInstance.writeStartArray();
    53            for(integer i=0;i<1;i++){
    54                for(Commercetax.TaxLineItemRequest lineItem : calculateTaxRequest.LineItems)
    55                {
    56                    jsonGeneratorInstance.writeStartObject();
    57                    if(lineItem.linenumber != null){
    58                        jsonGeneratorInstance.writeStringField('number', lineItem.linenumber);
    59                    }
    60                    jsonGeneratorInstance.writeNumberField('quantity', lineItem.Quantity);
    61                    jsonGeneratorInstance.writeNumberField('amount', (lineItem.Amount));
    62                    jsonGeneratorInstance.writeStringField('taxCode',lineItem.taxCode);
    63                    
    64                    jsonGeneratorInstance.writeFieldName('addresses');
    65                    jsonGeneratorInstance.writeStartObject();  
    66                    jsonGeneratorInstance.writeFieldName('ShipFrom');
    67                    jsonGeneratorInstance.writeStartObject();
    68                    jsonGeneratorInstance.writeStringField('line1', lineItem.addresses.shipfrom.street);
    69                    jsonGeneratorInstance.writeStringField('line2', lineItem.addresses.shipfrom.street);
    70                    jsonGeneratorInstance.writeStringField('city', lineItem.addresses.shipfrom.city);
    71                    jsonGeneratorInstance.writeStringField('region', lineItem.addresses.shipfrom.state);
    72                    jsonGeneratorInstance.writeStringField('country', lineItem.addresses.shipfrom.country);
    73                    jsonGeneratorInstance.writeStringField('postalCode',lineItem.addresses.shipfrom.postalcode);              
    74                    jsonGeneratorInstance.writeEndObject();               
    75
    76                    jsonGeneratorInstance.writeFieldName('ShipTo');
    77                    jsonGeneratorInstance.writeStartObject();
    78                    jsonGeneratorInstance.writeStringField('line1', lineItem.addresses.shipto.street);
    79                    jsonGeneratorInstance.writeStringField('line2', lineItem.addresses.shipto.street);
    80                    jsonGeneratorInstance.writeStringField('city', lineItem.addresses.shipto.city);
    81                    jsonGeneratorInstance.writeStringField('region', lineItem.addresses.shipto.state);
    82                    jsonGeneratorInstance.writeStringField('country', lineItem.addresses.shipto.country);
    83                    jsonGeneratorInstance.writeStringField('postalCode',lineItem.addresses.shipto.postalcode); 
    84                    jsonGeneratorInstance.writeEndObject();               
    85
    86                    jsonGeneratorInstance.writeFieldName('pointOfOrderOrigin');
    87                    jsonGeneratorInstance.writeStartObject();
    88                    jsonGeneratorInstance.writeStringField('line1', lineItem.addresses.soldto.street);
    89                    jsonGeneratorInstance.writeStringField('line2', lineItem.addresses.soldto.street);
    90                    jsonGeneratorInstance.writeStringField('city', lineItem.addresses.soldto.city);
    91                    jsonGeneratorInstance.writeStringField('region', lineItem.addresses.soldto.state);
    92                    jsonGeneratorInstance.writeStringField('country', lineItem.addresses.soldto.country);
    93                    jsonGeneratorInstance.writeStringField('postalCode',lineItem.addresses.soldto.postalcode); 
    94                    jsonGeneratorInstance.writeEndObject(); 
    95
    96
    97                    if(lineItem.effectiveDate != null)    
    98                    {
    99                        jsonGeneratorInstance.writeFieldName('taxOverride');
    100                        jsonGeneratorInstance.writeStartObject();
    101                        jsonGeneratorInstance.writeDateTimeField('taxDate', lineItem.effectiveDate);             
    102                        jsonGeneratorInstance.writeEndObject();               
    103                    }
    104                    jsonGeneratorInstance.writeEndObject(); 
    105                    jsonGeneratorInstance.writeEndObject(); 
    106                }
    107            }
    108                jsonGeneratorInstance.writeEndArray();             
    109            jsonGeneratorInstance.writeEndObject();
    110            return jsonGeneratorInstance.getAsString();
    111        }
    112        catch (Exception e) 
    113        { 
    114             throw e;
    115        } 
    116    }
    117}
  • Use the JsonErrorParser class to extract the error details, if any.

    1global with sharing class JsonErrorParser
    2{
    3    public cls_error error;
    4    
    5    public class cls_error
    6    {
    7        public String code; 
    8        public String message;
    9        public String target;
    10        public cls_details[] details;
    11    }
    12    
    13    public class cls_details
    14    {
    15        public String code;
    16        public String message;
    17        public String description;
    18        public String faultCode;
    19        public String helpLink;
    20        public String severity;
    21    }
    22    public static JsonErrorParser parse(String json)
    23    {
    24        return (JsonErrorParser) System.JSON.deserialize(json, JsonErrorParser.class);
    25    }
    26}

Tax Mappings for Quotes and Orders

You can extend and customize the tax interface for quotes and orders by using custom metadata types and tax mappings. These customizations help you with unique business requirements such as the inclusion of specific data for accurate calculations and audits.

Tax callout extensions are supported for the Quote, QuoteLineItem, Order, and OrderItem objects to include additional fields to tax requests. You must manually write back tax response extensions to the objects. See custom metadata types to specify all your tax mapping definitions.

Request Mappings for Header Attributes

This table defines the request mappings between the header attributes of a tax callout and fields of applicable quote and order objects.

Header Attributes Quote Mapping Order Mapping
currencyIsoCode If multi-currency is enabled, then this value is Quote.CurrencyISOCode. Otherwise, this value is NULL. If multi-currency is enabled, then this value is Order.CurrencyISOCode. Otherwise, this value is NULL.
isCommit False False
referenceEntityId Quote.ID Order.ID
taxEngineId TaxTreatment.TaxEngine.ID TaxTreatment.TaxEngine.ID
transactionDate Current System Date System Date
sellerDetails NULL
code TaxEngine.SellerCode
customerDetails
accountId Quote.AccountId Order.AccountId
code NULL NULL
exemptionNo NULL NULL
exemptionReason NULL NULL
taxType Estimated Estimated
taxTransactionType NULL NULL
effectiveDate NULL NULL
addresses
billTo NULL NULL
shipTo NULL NULL
shipFrom NULL NULL
soldTo NULL NULL
taxEngineAddress TaxEngine.Address TaxEngine.Address
referenceDocumentCode NULL NULL
description NULL NULL
documentCode Quote.ID-TaxEngineId Order.ID-TaxEngineId
shouldVoid FALSE FALSE
lineItems Refer to the next line attributes section. Refer to the next line attributes section.

Request Mappings for Line Attributes

This table defines the request mappings between the line attributes of a tax callout and fields of applicable quote line items and order products.

Line Attributes Quote Line Item Mapping Order Product Mapping
taxCode TaxTreatment.TaxCode TaxTreatment.TaxCode
productCode TaxTreatment.ProductCode TaxTreatment.ProductCode
productId QuoteLineItem.Product2.Id OrderItem.Product2.Id
amount QuoteLineItem.TotalPrice OrderItem.TotalPrice
effectiveDate Current System Date Current System Date
lineNumber QuoteLineItem.Id OrderItem.Id
description NULL NULL
quantity QuoteLineItem.Quantity OrderItem.Quantity
addresses
billTo Quote.BillingAddress. If Quote.BillingAddress is null, then this value is Quote.Account.BillingAddress. Order.BillingAddress
shipTo Quote.ShippingAddress. If Quote.ShippingAddress is null, then this value is Quote.Account.ShippingAddress. Order.ShippingAddress
shipFrom NULL NULL
soldTo NULL NULL
productsku QuoteLineItem.Product2.ProductCode OrderItem.Product2.ProductCode
referenceDocumentCode NULL NULL

Response Mappings for Header Attributes

This table defines the response mappings between the header attributes of a tax callout and fields of applicable objects. Most response data is used for tax calculation and isn’t persisted on quote or order records.

Header Attributes Quote Mapping Order Mapping
currencyIsoCode Quote.CurrencyISOCode Order.CurrencyISOCode
isCommit Not returned. Not returned.
referenceEntityId Quote.ID Order.ID
taxEngineId TaxTreatment.TaxEngine.ID TaxTreatment.TaxEngine.ID
transactionDate System Date System Date
sellerDetails Not returned. Not returned.
code Not returned. Not returned.
customerDetails Not returned. Not returned.
accountId Not returned. Not returned.
code Not returned. Not returned.
exemptionNo Not returned. Not returned.
exemptionReason Not returned. Not returned.
taxType Estimated Estimated
taxTransactionType Not returned. Not returned.
effectiveDate System Date System Date
addresses
billTo Not returned. Not returned.
shipTo locationCode -> locationCode locationCode -> locationCode
shipFrom Not returned. Not returned.
soldTo Not returned. Not returned.
taxEngineAddress Not returned. Not returned.
referenceDocumentCode Not returned. Not returned.
description Not returned. Not returned.
documentCode Quote.ID-TaxEngineId Order.ID-TaxEngineId
status Uncommitted Uncommitted
taxEngineLogs Not returned. Not returned.
resultCode Not returned. Not returned.
transactionDate System Date System Date
amountDetails
exemptAmount Actual exemptAmount from response. Actual exemptAmount from response.
taxAmount Actual taxAmount from response. Actual taxAmount from response.
totalAmount Quote.Subtotal Order.Subtotal
totalAmountWithTax TaxAmount + TotalAmount TaxAmount + TotalAmount
lineItems Refer to the next line attributes section. Refer to the next line attributes section.

Response Mappings for Line Attributes

This table defines the response mappings between the line attributes of a tax callout and fields of applicable objects.

Line Attributes Quote Line Item Mapping Order Product Mapping
taxCode TaxTreatment.TaxCode TaxTreatment.TaxCode
productCode TaxTreatment.ProductCode TaxTreatment.ProductCode
productId Not returned. Not returned.
amountDetails
exemptAmount Actual exemptAmount from response Actual exemptAmount from response
taxAmount Actual taxAmount from response Actual taxAmount from response
totalAmount QuoteLineItem.Subtotal OrderItem.Subtotal
totalAmountWithTax TaxAmount + TotalAmount TaxAmount + TotalAmount
effectiveDate System Date System Date
lineNumber QuoteLineItem.Id OrderItem.Id
description Not returned. Not returned.
quantity Not returned. Not returned.
addresses
billTo Not persisted. Not persisted.
shipTo locationCode -> locationCode locationCode -> locationCode
shipFrom Not returned. Not returned.
soldTo Not returned. Not returned.
productsku Not returned. Not returned.
referenceDocumentCode Not returned. Not returned.
taxes Refer to the next tax attributes section. Refer to the next tax attributes section.

Response Mappings for Tax Attributes

This table defines the response mappings between the tax attributes of a tax callout and fields of applicable objects.

Tax Attributes Quote Mapping Order Mapping
exemptAmount Not returned. Not returned.
exemptReason Not returned. Not returned.
imposition
type Not returned. Not returned.
Name Not returned. Not returned.
jurisdiction
country Not returned. Not returned.
id Not returned. Not returned.
level Not returned. Not returned.
name Not returned. Not returned.
region Not returned. Not returned.
stateAssignedNo Not returned. Not returned.
rate QuoteItemTaxItem.Rate OrderItemTaxItem.Rate
tax QuoteItemTaxItem.amount OrderItemTaxItem.amount
taxId Not returned. Not returned.
taxableAmount Not returned. Not returned.