how to use JavaScript callout and httpClient to invoke the SOAP-based Avalara Tax Service (avatax) ?

I have a synchronous request to be made to another webservice before making the call to target endpoint and I’m using javascript to construct this request.

When I test the constructed request in SOAPUI , I get the expected response

However, when I use the below in javascript -

var myResult = httpClient.get(“https://development.avalara.net/Tax/TaxSvc.asmx/v2”,reqcont);

I get below as response . how to use httpClient in order to pass the request along with URL to get valid response ?

#content{ FONT-SIZE: 0.7em; PADDING-BOTTOM: 2em; MARGIN-LEFT: 30px}BODY{MARGIN-TOP: 0px; MARGIN-LEFT: 0px; COLOR: #000000; FONT-FAMILY: Verdana; BACKGROUND-COLOR: white}P{MARGIN-TOP: 0px; MARGIN-BOTTOM: 12px; COLOR: #000000; FONT-FAMILY: Verdana}PRE{BORDER-RIGHT: #f0f0e0 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #f0f0e0 1px solid; MARGIN-TOP: -5px; PADDING-LEFT: 5px; FONT-SIZE: 1.2em; PADDING-BOTTOM: 5px; BORDER-LEFT: #f0f0e0 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #f0f0e0 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e5e5cc}.heading1{MARGIN-TOP: 0px; PADDING-LEFT: 15px; FONT-WEIGHT: normal; FONT-SIZE: 26px; MARGIN-BOTTOM: 0px; PADDING-BOTTOM: 3px; MARGIN-LEFT: -30px; WIDTH: 100%; COLOR: #ffffff; PADDING-TOP: 10px; FONT-FAMILY: Tahoma; BACKGROUND-COLOR: #003366}.intro{MARGIN-LEFT: -15px}TaxSvc Service

TaxSvc Service


You have created a service.

To test this service, you will need to create a client and use it to call the service. You can do this using the svcutil.exe tool from the command line with the following syntax:


svcutil.exe http://development.avalara.net/Tax/TaxSvc.svc?wsdl

You can also access the service description as a single file:

http://development.avalara.net/Tax/TaxSvc.svc?singleWsdl

This will generate a configuration file and a code file that contains the client class. Add the two files to your client application and use the generated client class to call the Service. For example:

C#

class Test {  static void Main() { TaxSvcClient client = new TaxSvcClient();  // Use the 'client' variable to call operations on the service.  // Always close the client.  client.Close(); } } 

Visual Basic

Class Test  Shared Sub Main()  Dim client As TaxSvcClient = New TaxSvcClient()  ' Use the 'client' variable to call operations on the service.  ' Always close the client.  client.Close()  End Sub End Class
1 Like

This “https://development.avalara.net/Tax/TaxSvc.asmx/v2” looks like just a SOAP service information page, which via httpClient returning response as HTML page content.

Also is the WSDL publicly available as i tried and it ever loads? Also make you are passing correct input request.

Your question asked “how to use the httpClient from JavaScript?” But I think you really want to know, “how can I invoke the Avalara Tax Service from an Apigee Edge API Proxy?”

@Faij Ahmad is correct : the URL you mentioned is just a service description page. It gives information about the service (useful for humans) - it is not the endpoint for the service (useful for apps).

Searching on Google, I found the actual WSDL for the Avalara Tax service is here:

https://development.avalara.net/Tax/TaxSvc.wsdl

The WSDL is just a machine-readable service description (WSDL = Web Services Description Language). Again, it is not the app endpoint, but the WSDL tells me the app endpoint. It is https://development.avalara.net/Tax/TaxSvc.asmx?Ping

What I would do:

  • Figure out how to construct a request to the Avalara service you want.
  • Use ServiceCallout (not JS and httpClient) to invoke the service

By googling around and playing, and with no thanks to the avalara developer documentation which I found to be confusing, I was able to build a request to invoke the Ping operation on that TaxService, and get a real response.

My request was like this:

curl -i -X POST [https://development.avalara.net/Tax/TaxSvc.asmx?Ping](https://development.avalara.net/Tax/TaxSvc.asmx?Ping) \
  -H soapAction:http://avatax.avalara.com/services/Ping \
  -H Content-Type:text/xml \
    --data '
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:avalara="http://avatax.avalara.com/services">
  <soap:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                   soap:actor="http://schemas.xmlsoap.org/soap/actor/next">
      <wsse:UsernameToken>
        <wsse:Username>My-Account-Id</wsse:Username>
        <wsse:Password>My-License-Key</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
    <avalara:Profile>
      <avalara:Name>TEST</avalara:Name>
      <avalara:Client>ClientSOAP</avalara:Client>
      <avalara:Adapter>SOAP API</avalara:Adapter>
      <avalara:Machine>MBPRO</avalara:Machine>
    </avalara:Profile>
  </soap:Header>
  <soap:Body>
    <avalara:Ping/>
  </soap:Body>
</soap:Envelope>
'

and the response I got was a pretty standard SOAP fault:

<s:Envelope 
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring xml:lang="en-US">The user or account could not be authenticated.</faultstring>
    </s:Fault>
  </s:Body>
</s:Envelope> 

ok, so that says I got a good endpoint, but my security credentials were rejected. (I don’t know why - I registered for a free trial account, but it’s rejecting my creds). I’m assuming you have valid credentials for the Avalara service and you can insert them into place in the above.

How can you do the equivalent within an Apigee Proxy? Use ServiceCallout. The ServiceCallout also lets you template-ify the messaging being sent. Like this:

<ServiceCallout name='SC-AvalaraPing'>
  <Request>
    <Set>
     <Headers>
       <Header name='soapAction'>http://avatax.avalara.com/services/Ping</Header>
     </Headers>
     <Payload contentType='text/xml'>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://avatax.avalara.com/services">
  <soap:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                   soap:actor="http://schemas.xmlsoap.org/soap/actor/next">
      <wsse:UsernameToken>
        <wsse:Username>{avalara_accountid}</wsse:Username>
        <wsse:Password>{avalara_licensekey}</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
    <ser:Profile>
      <ser:Name>Apigee TEST</ser:Name>
      <ser:Client>Apigee Edge Client</ser:Client>
      <ser:Adapter>SOAP API</ser:Adapter>
      <ser:Machine>MBPRO</ser:Machine>
    </ser:Profile>
  </soap:Header>
  <soap:Body>
    <ser:Ping/>
  </soap:Body>
</soap:Envelope>
     </Payload>
     <Verb>POST</Verb>
    </Set>
  </Request>
  <Response>avalaraResponse</Response>
  <HTTPTargetConnection>
    <SSLInfo>
        <Enabled>true</Enabled>
        <IgnoreValidationErrors>true</IgnoreValidationErrors>
    </SSLInfo>
    <Properties>
      <Property name='success.codes'>2xx, 3xx, 4xx, 5xx</Property>
    </Properties>
    <URL>https://development.avalara.net/Tax/TaxSvc.asmx?Ping</URL>
  </HTTPTargetConnection>
</ServiceCallout>

Augment that policy with some XSL and an XMLToJSON policy and you can get a JSON response out.

Find attached a working API Proxy. avalara-sc-apiproxy-20180306-1145.zip

Deploy it to your org/env, and then Invoke it like this:

curl -i -u ${ACCOUNTID}:${LICENSEKEY} \
    [https://${ORG}-${ENV}.apigee.net/avalara-sc/ping](https://${ORG}-${ENV}.apigee.net/avalara-sc/ping) 

My response looks like this:

{
    "Fault": {
        "faultcode": "s:Client",
        "faultstring": {
            "lang": "en-US",
            "$": "The user or account could not be authenticated."
        }
    }
}

1 Like

If you still want to do in Javascript you should first note that you need to use httpClient.send() instead of httpClient.get()

var myResult = httpClient.get("https://development.avalara.net/Tax/TaxSvc.asmx/v2",reqcont);

Sample usage explained here: https://docs.apigee.com/api-services/reference/javascript-object-model

Or even better let APIGEE do some heavy lifting for you, you can directly create a SOAP to REST service.

I recommend that you use the wizard to generate the proxy. Steps:

  1. Select “+ API Proxy”

  2. Select SOAP Service

  3. Click on “Example URL”, select the your WSDL.

  4. Click on “Validate” and Click “Next”

  5. API Proxy Type => Select “Pass- Through SOAP”

  6. Accept defaults for the remaining screen and deploy it.

You will be able to easily consume a SOAP Service with this approach and tweak it to suit your needs.

Thanks.

@Dino

Thanks a lot for your time and response!

I had tried out even service callout and even then was getting same HTML response and then you and @Faij Ahmad pointed out it correctly, I did not have the correct endpoint.

I previously was using the enpoint - https://development.avalara.net/Tax/TaxSvc.asmx/v2, which surprisingly works in SOAP UI ( I still don’t know how) . However, when I corrected the endpoint to https://development.avalara.net/Tax/TaxSvc.asmx?GetTaxHistory , seeing what you gave in the example of ping operation, I got the expected valid SOAP response.

Thanks again!

@Faij Ahmad, thanks for your response! I’m now able to make a request and get successful response