Page tree
Skip to end of metadata
Go to start of metadata

Introduction


DOTS FastTax (referred to as FastTax or FT) is a publicly available XML web service that provides sales tax rate information for all US areas based on several different inputs. The service provides zip, city, county, county fips codes, state, tax rates and exemptions. 
FastTax can provide instant sales tax rates for any address, zip code, city or county in the United States.

Integration

Integrating DOTS FastTax into your application should be easy and straightforward. If you are using a common platform, Service Objects may already have sample code built that you can use:
https://www.serviceobjects.com/developers/sample-code/fasttax

However, if you are using a common platform that does not already have sample code, you can ask Service Objects to build you an example. Email support@serviceobjects.com for more details.

Web Service Structure

Web services are methods that integrate with other applications via the web, and encapsulate tricky business logic. Web services are too large of a topic to cover in this document, but Service Objects has developed its web services to be as easy to integrate and as accessible as possible. 
FastTax is a public XML web service that supports SOAP, POST and GET operations. Note that SOAP is done via POST, only with special XML markup in the post-body.

The host path, or physical location of the web service is here:
https://trial.serviceobjects.com/ft/

The location of the WSDL, or Web Service Definition Language document, is here (This is also accessible via the "Service Definition" link.):
https://trial.serviceobjects.com/ft/soap.svc?wsdl

NOTE: For rates in Minnesota, please use GetBestMatch.  Minnesota tracks tax rates differently from the rest of the states (they have zip code level rates).  Getting rates based on zip or city and county lookup operations will not necessarily return accurate results.

This WSDL is the definition of the web service, meaning its inputs, outputs, operations, and the like. Most likely, you will have another tool read this WSDL and make the operations available to you in your application. Whenever your utilities or IDE asks for a WSDL path to FastTax, you can provide this one.

Every web service has operations that it offers to subscribers – methods that do different work and return different output. Examining the link above, you will notice several of these operations available, which are described in detail later on.

Code Snippets




Fast Tax C# Code Snippet
try
{
    DOTSFastTaxSoapClient ws = new DOTSFastTaxSoapClient();
    BestMatchResponse response = new BestMatchResponse();
    response = ws.GetBestMatch(Address.Text, Address2.Text,City.Text, State.Text, Zip.Text, TaxType.Text, LicenseKey.Text);
    if ((response.Error == null))
    {
        ProcessValidResponse(response);
    }
    else
    {
        ProcessErrorResponse(response.Error);
    }
}
catch (Exception er)
{
    //Set the Primary and Backup Service References as necessary
    try
    {
        DOTSFastTaxSoapClient wsbackup = new DOTSFastTaxSoapClient();
        BestMatchResponse response = new BestMatchResponse();
        response = wsbackup.GetBestMatch(Address.Text, Address2.Text, City.Text, State.Text, Zip.Text, TaxType.Text, LicenseKey.Text);
        if ((response.Error == null))
        {
            ProcessValidResponse(response);
        }
        else
        {
            ProcessErrorResponse(response.Error);
        }
    }
    catch (Exception ex)
    {
        resultsLabel.Visible = true;
        resultsLabel.Text = ex.Message;
    }
}


Fast Tax Java Code Snippet
URL TrialURL = new URL("https://trial.serviceobjects.com/ft/");
URL FailoverURL = new URL("https://trial.serviceobjects.com/ft/");

String Address,Address2,City,State,Zip,TaxType,LicenseKey;
Address = request.getParameter("iAddress");
Address2 = request.getParameter("iAddress2");
City = request.getParameter("iCity");
State = request.getParameter("iState");
Zip = request.getParameter("iZip");
TaxType = request.getParameter("iTaxType");
LicenseKey = request.getParameter("iLicenseKey");
BestMatchResponse FTResponse = null;
DOTSFastTax FTLocator = new DOTSFastTax(TrialURL);
DOTSFastTaxSoap FTClient = FTLocator.getDOTSFastTaxSoap();
try{
    FTResponse = FTClient.getBestMatch(Address, Address2, City, State, Zip, TaxType, LicenseKey);
}
catch(Exception r)
{
	// Implementing failover logic below as an example. 
    DOTSFastTax FTLocatorBackup = new DOTSFastTax(FailoverURL);
    DOTSFastTaxSoap backupClient = FTLocatorBackup.getDOTSFastTaxSoap();
	FTResponse = backupClient.getBestMatch(Address, Address2, City, State, Zip, TaxType, LicenseKey);
}


Fast Tax PHP Code Snippets
$Address        = trim($Address);
$Address2       = trim($Address2);
$City           = trim($City);
$State          = trim($State);
$Zip            = trim($Zip);
$TaxType        = trim($TaxType);
$LicenseKey     = trim($LicenseKey);

$params['Address']      = $Address;
$params['Address2']     = $Address2;
$params['City']         = $City;
$params['State']        = $State;
$params['Zip']          = $Zip;
$params['TaxType']      = $TaxType;
$params['LicenseKey']   = $LicenseKey;
try
{                          
    $soapClient = new SoapClient(TrialURL, array( "trace" => 1 ));
    $result = $soapClient->GetBestMatch($params)->GetBestMatchResult;
    
    if(isset($result->Error) && 
       $result->Error->Number == 4)
        {
            throw new Exception;
        }
}
catch(Exception $e)
{
   
    // Example fail over logic provided below. You should implement a variation which makes use of our backup datacenter
    // in the event of a failure at our primary datacenter.
    try
    {
        $soapClient = new SoapClient(FailOverURL, array( "trace" => 1 ));
        $result = $soapClient->GetBestMatch($params);
        
        
    }
    catch(Exception $ex)
    {//Both soap calls failed
        echo "<b> Primary and backup wsdls failed </b>";
        return;
    }
}


Fast Tax RoR Code Snippets
message = 	{
			"Address" => @request.address,
			"Address2" => @request.address2,
			"City" => @request.city,
			"State" => @request.state,
			"Zip" => @request.zipcode,
			"TaxType" => @request.taxtype,
			"LicenseKey" => @request.licensekey,
			}
#Implemented to make the code more readable when accessing the hash			
@ftresponse = :get_best_match_response
@ftresult = :get_best_match_result
@ftInfoItems = :tax_info_items
@ftBMtaxInfo = :best_match_tax_info
@fterror = :error
#Set Primary and Backup URLs here as needed
dotsFTPrimary = "https://trial.serviceobjects.com/ft/soap.svc?wsdl"
dotsFTBackup = "https://trial.serviceobjects.com/ft/soap.svc?wsdl"

begin
	#initializes the soap client. The convert request keys global is necessary to receive a response from the service.
	client = Savon.client(	wsdl: dotsFTPrimary,
							element_form_default: :qualified,
							convert_request_keys_to: :camelcase
						 )
	#Calls the operation with given inptus and converts response to a hash.
	response = client.call(:get_best_match, message: message).to_hash
	#Checks to see what results came back from the service
	#@displaydata = response
	if (response.nil? || (!response[@ftresponse][@ftresult][@fterror].nil? && response[@ftresponse][@ftresult][@fterror][:number] == "4"))
		raise
	else
		processresults(response)
	end			
	
#If an error occurs during the call, this will use backup url and attempt to retrieve data.
rescue StandardError => e
	begin
	backupclient = Savon.client(	wsdl: dotsFTBackup,
									element_form_default: :qualified,
									convert_request_keys_to: :camelcase
							   )
	#Sets the response to the backclient call to the operation and converts response to a hash.
	response = backupclient.call(:get_best_match, message: message).to_hash
	processresults(response)
	@status = "Backup Call Was Used"
	#If backup url failed, this will display the error received from the server
	rescue StandardError =>error
		@status = error
		@displaydata = {"error" => "A Big Error Occured"}
	end
end


Fast Tax Python Code Snippets
	
primaryURL = 'https://trial.serviceobjects.com/ft/soap.svc?wsdl'
backupURL = 'https://trial.serviceobjects.com/ft/soap.svc?wsdl'
#This block of code calls the web service and prints the resulting values to the screen
try:
    client = Client(primaryURL)
    result = client.service.GetBestMatch(Address=mAddress, Address2=mAddress2, City=mCity, State=mState, Zip=mPostalCode, TaxType=mTaxType, LicenseKey=mLicenseKey)
    #Loops through either the error result or proper result and displays values to the screen.
    if hasattr(result, 'Error') :
        if (result.Error.Number == "4"):
            raise Exception
        else:
            for value in result.Error:
                Label(swin.window, text=str(value[0]) + " : " + str(value[1]) if value[1] else str(value[1])+": None").pack()
    else:
        for value in result:
            Label(swin.window, text=str(value[0]) + ":  " + str(value[1]) if value[1] else str(value[0]) + " : None").pack()
#Tries the backup URL if the primary URL failed
except:
    try:
        client = Client(backupURL)
        result = client.service.GetBestMatch(Address=mAddress, Address2=mAddress2, City=mCity, State=mState, Zip=mPostalCode, TaxType=mTaxType, LicenseKey=mLicenseKey)
        if hasattr(result, 'Error') :
            for value in result.Error:
                Label(swin.window, text=str(value[0]) + " : " + str(value[1]) if value[1] else str(value[1])+": None").pack()
        else:
            for value in result:
                Label(swin.window, text=str(value[0]) + ":  " + str(value[1]) if value[1] else str(value[0]) + " : None").pack()
    #If the backup call failed then this will display an error to the screen
    except:
        Label(swin.window, text='Error').pack()
        print ("************************************************************************************************")
        print ("************************************************************************************************")
        print (result)
return


FastTax ColdFusion Code Snippet
<!--Makes Request to web service --->
<cfscript>
		try
		{
			if (isDefined("form.Action") AND Action neq "")
			{
				wsresponse = CreateObject("webservice", "https://trial.serviceobjects.com/ft/soap.svc?wsdl");							  
				outputs = wsresponse.GetBestMatch("#Address#", "#Address2#", "#City#", "#State#", "#Zip#", "#TaxType#", "#LicenseKey#");

				if ((Len(outputs.getError()) GT 0) AND outputs.getError().getNumber() == "4")
				{
					throw Exception;
				}
			}
		}
	catch(any Exception){
		try
			{
				if (isDefined("form.Action") AND Action neq "")
				{
					wsresponse = CreateObject("webservice", "https://trial.serviceobjects.com/ft/soap.svc?wsdl");							  
					outputs = wsresponse.GetBestMatch("#Address#", "#Address2#", "#City#", "#State#", "#Zip#", "#TaxType#", "#LicenseKey#");
					
				}
			}
			catch(any Exception)	
				{
		  		 writeoutput("An Error Has Occured. Please Reload and try again");		  		 
		 		}
	    }
</cfscript>


FastTax VB Code Snippet
Try
    Dim ws As New FTServiceReference.DOTSFastTaxSoapClient
    Dim response As FTServiceReference.BestMatchResponse

    response = ws.GetBestMatch(Address.Text, Address2.Text, City.Text, State.Text, Zip.Text, TaxType.Text, LicenseKey.Text)
    If (response.Error Is Nothing) Then

        ProcessValidResponse(response)
    Else
        ProcessErrorResponse(response.Error)
    End If


Catch er As Exception
    ''Set the Primary and Backup Service References as necessary
    Try
        Dim wsbackup As New FTServiceReference.DOTSFastTaxSoapClient
        Dim response As FTServiceReference.BestMatchResponse

        response = wsbackup.GetBestMatch(Address.Text, Address2.Text, City.Text, State.Text, Zip.Text, TaxType.Text, LicenseKey.Text)
        If (response.Error Is Nothing) Then
            ProcessValidResponse(response)
        Else
            ProcessErrorResponse(response.Error)
        End If
    Catch ex As Exception
        resultsLabel.Visible = True
        resultsLabel.Text = ex.Message

    End Try
End Try


FastTax Apex Code Snippet
wwwServiceobjectsCom.BestMatchResponse result;
try{
wwwServiceobjectsCom.DOTSFastTaxSoap client = new wwwServiceobjectsCom.DOTSFastTaxSoap();
result = client.GetBestMatch([Address], [Address2], [City], [State], [Zip], [TaxType], [LicenseKey]);
}
catch(Exception ex){
 //If the first request failed try the failover endpoint
wwwServiceobjectsCom.DOTSFastTaxSoap backupClient = new wwwServiceobjectsCom.DOTSFastTaxSoap();
//The backup environment will be provided to you upon purchasing a production license key
backupClient.endpoint_x = 'https://wsbackup.serviceobjects.com/ft/';
result = backupClient.GetBestMatch([Address], [Address2], [City], [State], [Zip], [TaxType], [LicenseKey]);
}



FastTax TSQL Code Snippet
SET @requestBody ='<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">'+
				   '<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">'+
				   '<GetBestMatch xmlns="http://www.serviceobjects.com/">'+
				   '<Address>' + @address + '</Address>'+
				   '<Address2>' + @address2 + '</Address2>'+
				   '<City>' + @city + '</City>'+
				   '<State>' + @state + '</State>'+
				   '<Zip>' + @zip + '</Zip>'+
				   '<TaxType>' + @taxtype + '</TaxType>'+
				   '<LicenseKey>' + @key + '</LicenseKey>'+
				   '</GetBestMatch>'+
				   '</s:Body>'+
				   '</s:Envelope>'

SET @requestLength = LEN(@requestBody)

	--If a production key is purchased, this will execute the failover 
IF @isLiveKey = 1
BEGIN
	EXEC sp_OACreate 'MSXML2.ServerXMLHttp', @obj OUT
	EXEC sp_OAMethod @obj, 'Open', NULL, 'POST', 'https://trial.serviceobjects.com/ft/', false
	EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'HOST', 'trial.serviceobjects.com'
	EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'Content-Type', 'text/xml; charset=UTF-8'
	EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'SOAPAction', '"http://www.serviceobjects.com/GetBestMatch"'
	EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'Content-Length', @requestLength 
	EXEC sp_OAMethod @obj, 'send', NULL, @requestBody
	EXEC sp_OAGetProperty @obj, 'Status', @responseCode OUTPUT
	EXEC sp_OAGetProperty @obj, 'StatusText', @statusText OUTPUT
	EXEC sp_OAGetProperty @obj, 'responseText', @response OUTPUT
			
	--Checks the Response for a fatal error or if null. 
	IF @response IS NULL
	BEGIN
		EXEC sp_OACreate 'MSXML2.ServerXMLHttp', @obj OUT
		EXEC sp_OAMethod @obj, 'Open', NULL, 'POST', 'https://trial.serviceobjects.com/ft/', false
		EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'HOST', 'trial.serviceobjects.com'
		EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'Content-Type', 'text/xml; charset=UTF-8'
		EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'SOAPAction', '"http://www.serviceobjects.com/GetBestMatch"'
		EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'Content-Length', @requestLength 
		EXEC sp_OAMethod @obj, 'send', NULL, @requestBody
		EXEC sp_OAGetProperty @obj, 'Status', @responseCode OUTPUT
		EXEC sp_OAGetProperty @obj, 'StatusText', @statusText OUTPUT
		EXEC sp_OAGetProperty @obj, 'responseText', @response OUTPUT
	END
END



Fast Tax C# Rest Code Snippet
BestMatchResponse result = null;
string mainURL = "https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=" + Address + "&Address2=" + Address2 + "&City=" + City + "&State=" + State + "&Zip=" + Zip + "&TaxType=" + TaxType + "&LicenseKey=" + LicenseKey;
// A trial license key is not compatible with the backup datacenter. 
// The backup url is provided with a production license key.
string backupURL = "https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=" + Address + "&Address2=" + Address2 + "&City=" + City + "&State=" + State + "&Zip=" + Zip + "&TaxType=" + TaxType + "&LicenseKey=" + LicenseKey;

try
{
    result = HttpGet(mainURL);
    //NULL ERROR || FATAL ERROR RETURNED -- TRY BACKUP 
    if (result == null|| (result.Error != null && result.Error.Number == "3"))
    {
        return HttpGet(backupURL);
    }
    else
    {
        return result;
    }
}
catch (Exception)
{
    //ERROR IN MAIN URL - USING BACKUP
    return HttpGet(backupURL);
}


Fast Tax Java Rest Code Snippet
 if ((Address == null)||(Address == ""))
     Address = " ";
 if ((Address2 == null)||(Address2 == ""))
     Address2 = " ";
 if ((City == null)||(City == ""))
     City = " ";
 if ((State == null)||(State == ""))
     State = " ";
 if ((Zip == null)||(Zip == ""))
     Zip = " ";
 if ((TaxType == null)||(TaxType == ""))
     TaxType = " ";
 if ((LicenseKey == null)||(LicenseKey == ""))
     LicenseKey = "YOUR-LICENSE-KEY";


 try {
    Address = URLEncoder.encode(Address,"UTF-8").replaceAll("\\+", "%20");
    Address2 = URLEncoder.encode(Address2,"UTF-8").replaceAll("\\+", "%20");
    City = URLEncoder.encode(City,"UTF-8").replaceAll("\\+", "%20");
    State = URLEncoder.encode(State,"UTF-8").replaceAll("\\+", "%20");
    Zip = URLEncoder.encode(Zip,"UTF-8").replaceAll("\\+", "%20");
    TaxType = URLEncoder.encode(TaxType,"UTF-8").replaceAll("\\+", "%20");
    LicenseKey = URLEncoder.encode(LicenseKey,"UTF-8").replaceAll("\\+", "%20");


} catch (UnsupportedEncodingException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
}
 

BestMatchResponse Response = null;
String Request = "https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=" + Address + "&Address2=" + Address2 + "&City=" + City + "&State=" + State + "&Zip=" + Zip + "&TaxType=" + TaxType + "&LicenseKey=" + LicenseKey;
try {
	
	Response = DoHttpRequest(Request);
	
	
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}


Fast Tax PHP Rest Code Snippets
$TrialURL = "https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=".rawurlencode($Address)."&Address2=".rawurlencode($Address2)."&City=".rawurlencode($City)."&State=".rawurlencode($State)."&Zip=".rawurlencode($Zip)."&TaxType=".rawurlencode($TaxType)."&LicenseKey=".rawurlencode($LicenseKey);
// A trial license key is not compatible with the backup datacenter.  
// The backup url is provided with a production license key.
$BackupURL = "https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=".rawurlencode($Address)."&Address2=".rawurlencode($Address2)."&City=".rawurlencode($City)."&State=".rawurlencode($State)."&Zip=".rawurlencode($Zip)."&TaxType=".rawurlencode($TaxType)."&LicenseKey=".rawurlencode($LicenseKey);

// Get cURL resource
$curl = curl_init();
curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => $TrialURL, CURLOPT_USERAGENT => 'Service Objects Fast Tax'));
//Https peer certification validation turned off
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT_MS, $TIMEOUT); //timeout in milliseconds
// Send the request & save response to $resp
$resp = curl_exec($curl);
$status = curl_getinfo($curl);
$decoded = json_decode($resp, TRUE);

if($resp == FALSE || (isset ($decoded['Error']) != NULL && $decoded['Error']['Number'] == 4) || (isset($status) && $status['http_code'] != 200))
{
    // the first service has failed over
    // create a new request to the backURL
    $curl2 = curl_init();
    curl_setopt_array($curl2, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => $BackupURL, CURLOPT_USERAGENT => 'Service Objects Fast Tax'));
    //Https peer certification validation turned off
    curl_setopt($curl2, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl2, CURLOPT_CONNECTTIMEOUT_MS, $TIMEOUT); //timeout in milliseconds
    // Send the request & save response to $resp
    $resp = curl_exec($curl2);
    $decoded = json_decode($resp, TRUE);
    if($resp == false)
    {
        echo "<b> Both rest calls failed </b>";
        curl_close($curl2);
        return;
    }
}
//Close request to clear up some resources
curl_close($curl);


Fast Tax RoR Code Snippets
#Set Primary and Backup URLs as needed. This method encodes and standardizes the URI to pass to the REST service.
primaryURL = URI.encode("https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=" + address + "&Address2=" + address2 + "&City=" + city + "&State=" + state + "&Zip=" + zipcode + "&TaxType=" + taxtype + "&LicenseKey=" + licensekey)
backupURL = URI.encode("https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=" + address + "&Address2=" + address2 + "&City=" + city + "&State=" + state + "&Zip=" + zipcode + "&TaxType=" + taxtype + "&LicenseKey=" + licensekey)

#These are set to access the hash that is returned
@ftresponse ="BestMatchResponse"
@ftitems = "TaxInfoItems"
@ftbestmatch = "BestMatchTaxInfo"
@fterror = "Error"



  #Begins the call the RESTful web service
begin
  response = HTTParty.get(primaryURL, timeout: default_timeout)
  #processes the response to display to the screen
  
  #Passes the response returned from HTTParty and processes them depending on the results
  if (!response[@ftresponse][@fterror].nil? && response[@ftresponse][@fterror]["Number"] == '4') 
      raise
  else
   processresults(response)
  end
  
  
 rescue StandardError => e
 		begin
 		#uses the backupURl in the event that the service encountered an error
 		response = HTTParty.get(backupURL, timeout: default_timeout)
    
    #processes the response returned from using the backupURL
 		processresults(response)
    #If the backup url railed this will raise an error and display the 
    #error message returned from the HTTParty gem.
 		rescue StandardError => error
 			@status = error.message + " " +  error.backtrace[0]
 			@displaydata = {"Error" => "A Big Error Occured"}
 		end

end


Fast Tax Python Rest Code Snippets
primaryURL = 'https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?'
backupURL = 'https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?'

#The Requests package allows the user to format the path parameters like so instead of having to manually insert them into the URL
inputs = {'Address': mAddress, 'Address2': mAddress2, 'City': mCity, 'State': mState, 'Zip': mZipCode, 'TaxType':mTaxType, 'LicenseKey': mLicenseKey}


try:
    result = requests.get(primaryURL, params=inputs)
    #Parses the XML response from the service into a python dictionary type
    outputs = xmltodict.parse(result.content)
    #checks the output for Errors and displays the info accordingly
    if 'Error' in outputs['BestMatchResponse']:
        #loops through the response from the service and prints the values to the screen.
        if outputs['BestMatchResponse']['Error']['Number'] == "4":
            raise Exception
        else:
            for key, value in outputs['BestMatchResponse']['Error'].iteritems():
                Label(swin.window, text=str(key) + " : " + str(value)).pack()

    else:
        #Removes unnecessary entries that were parsed into the python dictionary from XML response of service


        for key, value in outputs['BestMatchResponse']['TaxInfoItems']['BestMatchTaxInfo'].iteritems():
            Label(swin.window, text=str(key) + " : " + str(value)).pack()

#Attempts to use the backupURL if the call to the primary URL failed
except:
    try:
        result = requests.get(backupURL, params=inputs)
        #Parses the XML response from the service into a python dictionary type
        outputs = xmltodict.parse(result.content)
        #checks the output for Errors and displays the info accordingly
        if 'Error' in outputs['BestMatchResponse']:
            #loops through the response from the service and prints the values to the screen.
            for key, value in outputs['BestMatchResponse']['Error'].iteritems():
                Label(swin.window, text=str(key) + " : " + str(value)).pack()

        else:
            #Removes unnecessary entries that were parsed into the python dictionary from XML response of service


            for key, value in outputs['BestMatchResponse']['TaxInfoItems']['BestMatchTaxInfo'].iteritems():
                Label(swin.window, text=str(key) + " : " + str(value)).pack()

    #Prints an error message if the primary and backup urls failed
    except:
        Label(swin.window, text='Error').pack()
        print ("************************************************************************************************")
        print ("************************************************************************************************")
        print (response)
return


FastTax ColdFusion Rest Code Snippet
<!--Makes Request to web service --->
<cfIf isDefined("form.Action") AND Action neq ""  >
	<cftry>
		<cfset primaryURL = "https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=#Address#&Address2=#Address2#&City=#City#&State=#State#&Zip=#Zip#&TaxType=#TaxType#&LicenseKey=#LicenseKey#">
		<cfhttp url="#primaryURL#" method="get" result="response">
		<cfset outputs = XmlParse(response.FileContent)>
		<cfif (isNull(outputs) OR (!isNull(outputs.BestMatchResponse.Error) AND (outputs.BestMatchResponse.Error.Number is "10"))) >
			<cfthrow message="BackupCall Used">
		</cfif>
		<cfdump var="#outputs#" >
	<cfcatch >
		<cftry>
			<cfset backupURL = "https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=#Address#&Address2=#Address2#&City=#City#&State=#State#&Zip=#Zip#&TaxType=#TaxType#&LicenseKey=#LicenseKey#">
			<cfhttp url="#backupURL#" method="get" result="response">
			<cfset outputs = XmlParse(outputs.FileContent)>
			<cfdump var="#outputs#">	
			<cfcatch >
				<cfoutput >
					The Following Error Occured: #response.StatusCode# 
				</cfoutput>
			</cfcatch>
		</cftry>
	</cfcatch>
	</cftry>
</cfif>


FastTax VB Rest Code Snippet
Try
    'encodes the URLs for the get Call. Set the primary and back urls as necessary
    Dim primaryurl As String = "https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=" + address + "&Address2=" + address2 + "&City=" + city + "&State=" + state + "&Zip=" + zip + "&TaxType=" + taxtype + "&LicenseKey=" + licensekey
    Dim backupurl As String = "https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=" + address + "&Address2=" + address2 + "&City=" + city + "&State=" + state + "&Zip=" + zip + "&TaxType=" + taxtype + "&LicenseKey=" + licensekey

    Dim wsresponse As BestMatchResponse = httpGet(primaryurl)


    'checks if a response was returned from the service, uses the backup url if response is null or a fatal error occured.
    If wsresponse Is Nothing OrElse (wsresponse.[Error] IsNot Nothing AndAlso wsresponse.[Error].Number = "3") Then

        wsresponse = httpGet(backupurl)
    End If

    If wsresponse.[Error] IsNot Nothing Then
        ProcessErrorResponse(wsresponse.[Error])
    Else
        ProcessSuccessfulResponse(wsresponse)


    End If
Catch ex As Exception
    'Displays the relevant error mesasge if both backup and primary urls failed.
    StatusLabel.Text = ex.Message
    StatusLabel.Visible = True
End Try


FastTax TSQL Rest Code Snippet
SET @address =  CASE WHEN @address is NULL THEN ' ' ELSE @address END
SET @address2 =  CASE WHEN @address2 is NULL THEN ' ' ELSE @address2 END
SET @city =  CASE WHEN @city is NULL THEN ' ' ELSE @city END
SET @state =  CASE WHEN @state is NULL THEN ' ' ELSE @state END
SET @zip =  CASE WHEN @zip is NULL THEN ' ' ELSE @zip END
SET @taxtype =  CASE WHEN @taxtype is NULL THEN ' ' ELSE @taxtype END
SET @key =  CASE WHEN @key is NULL THEN ' ' ELSE @key END
SET @isLiveKey =  CASE WHEN @isLiveKey is NULL THEN 1 ELSE @isLiveKey END

--If a production key is purchased, this will execute the failover 
IF @isLiveKey = 1
BEGIN
	SET @sUrl = 'https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=' + @address + '&Address2=' + @address2 + '&City=' + @city + '&State=' + @state +  '&Zip=' + @zip + '&TaxType=' + @taxtype + '&LicenseKey=' + @key
	EXEC sp_OACreate 'MSXML2.ServerXMLHttp', @obj OUT
	EXEC sp_OAMethod @obj, 'Open', NULL, 'Get', @sUrl, false
	EXEC sp_OAMethod @obj, 'send'
	EXEC sp_OAGetProperty @obj, 'responseText', @response OUT
			
	--Checks the Response for a fatal error or if null. 
	IF @response IS NULL
	BEGIN
		SET @sBackupUrl = 'https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=' + @address + '&Address2=' + @address2 + '&City=' + @city + '&State=' + @state +  '&Zip=' + @zip + '&TaxType=' + @taxtype + '&LicenseKey=' + @key
		EXEC sp_OACreate 'MSXML2.ServerXMLHttp', @obj OUT
		EXEC sp_OAMethod @obj, 'Open', NULL, 'Get', @sBackupUrl, false
		EXEC sp_OAMethod @obj, 'send'
		EXEC sp_OAGetProperty @obj, 'responseText', @response OUT
	END
END



You can find and download full sample code to our services in various languages (PHP, JAVA and C#) by clicking here. Below is a C# version.

If you are looking for a particular integration not listed in our documentation please contact us at support@serviceobjects.com.

C#
using DOTSFT_CSharp_Soap_GetBestMatch.FTServiceReference;
using System;
using System.Data;
using System.Web.UI;
namespace DOTSFT_CSharp_Soap_GetBestMatch
{
    public partial class FTForm : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }
        protected void SubmitBtn_Click(object sender, EventArgs e)
        {
            try
            {
                DOTSFastTaxSoapClient ws = new DOTSFastTaxSoapClient();
                BestMatchResponse response = new BestMatchResponse();
                response = ws.GetBestMatch(Address.Text, Address2.Text,City.Text, State.Text, Zip.Text, TaxType.Text, LicenseKey.Text);
                if ((response.Error == null))
                {
                    ProcessValidResponse(response);
                }
                else
                {
                    ProcessErrorResponse(response.Error);
                }
            }
            catch (Exception er)
            {
                //Set the Primary and Backup Service References as necessary
                try
                {
                    DOTSFastTaxSoapClient wsbackup = new DOTSFastTaxSoapClient();
                    BestMatchResponse response = new BestMatchResponse();
                    response = wsbackup.GetBestMatch(Address.Text, Address2.Text, City.Text, State.Text, Zip.Text, TaxType.Text, LicenseKey.Text);
                    if ((response.Error == null))
                    {
                        ProcessValidResponse(response);
                    }
                    else
                    {
                        ProcessErrorResponse(response.Error);
                    }
                }
                catch (Exception ex)
                {
                    resultsLabel.Visible = true;
                    resultsLabel.Text = ex.Message;
                }
            }
        }
        protected void ProcessValidResponse(BestMatchResponse validResponse)
        {
            DataTable dtoutTable = new DataTable();
            dtoutTable.Columns.Add(new DataColumn("Outputs"));
            dtoutTable.Columns.Add(new DataColumn("Values"));
            //Checks for existence of the TaxInfoItems array, if it exists it will loop through the values and display them as results.  
            if (validResponse.TaxInfoItems != null)
            {
                dtoutTable.Rows.Add("MatchLevel", validResponse.MatchLevel);
                for (int i = 0; i < validResponse.TaxInfoItems.Length; i++)
                {
                    dtoutTable.Rows.Add("Zip", validResponse.TaxInfoItems[i].Zip);
                    dtoutTable.Rows.Add("City", validResponse.TaxInfoItems[i].City);
                    dtoutTable.Rows.Add("County", validResponse.TaxInfoItems[i].County);
                    dtoutTable.Rows.Add("StateName", validResponse.TaxInfoItems[i].StateName);
                    dtoutTable.Rows.Add("StateAbbreviation", validResponse.TaxInfoItems[i].StateAbbreviation);
                    dtoutTable.Rows.Add("TaxRate", validResponse.TaxInfoItems[i].TaxRate);
                    dtoutTable.Rows.Add("StateRate", validResponse.TaxInfoItems[i].StateRate);
                    dtoutTable.Rows.Add("CityRate", validResponse.TaxInfoItems[i].CityRate);
                    dtoutTable.Rows.Add("CountyRate", validResponse.TaxInfoItems[i].CountyRate);
                    dtoutTable.Rows.Add("CityDistrictRate", validResponse.TaxInfoItems[i].CityDistrictRate);
                    dtoutTable.Rows.Add("CountyDistrictRate", validResponse.TaxInfoItems[i].CountyDistrictRate);
                    dtoutTable.Rows.Add("SpecialDistrictRate", validResponse.TaxInfoItems[i].SpecialDistrictRate);
                    dtoutTable.Rows.Add("TotalTaxExempt", validResponse.TaxInfoItems[i].TotalTaxExempt);
                    dtoutTable.Rows.Add("NotesCodes", validResponse.TaxInfoItems[i].NotesCodes);
                    dtoutTable.Rows.Add("NotesDesc", validResponse.TaxInfoItems[i].NotesDesc);
                    dtoutTable.Rows.Add("Information Components", "--------");
                    foreach (InformationComponent IC in validResponse.TaxInfoItems[i].InformationComponents)
                    {
                        dtoutTable.Rows.Add(IC.Name, IC.Value);
                    }
                }
            }
            
            outputGrid.Visible = true;
            outputGrid.DataSource = new DataView(dtoutTable);
            outputGrid.DataBind();
        }
        protected void ProcessErrorResponse(Err errorResponse)
        {
            resultsLabel.Text = "Errors found!";
            DataTable dtErrorTable = new DataTable();
            dtErrorTable.Columns.Add(new DataColumn("Outputs"));
            dtErrorTable.Columns.Add(new DataColumn("Values"));
            dtErrorTable.Rows.Add("Desc", errorResponse.Desc);
            dtErrorTable.Rows.Add("Number", errorResponse.Number);
            dtErrorTable.Rows.Add("Location", errorResponse.Location);
            outputGrid.Visible = true;
            outputGrid.DataSource = new DataView(dtErrorTable);
            outputGrid.DataBind();
        }
    }
}



GetBestMatch Example Request and Response

JSON Request: 
https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=27+E+Cota+St+Ste+500&Address2=&City=Santa+Barbara&State=CA&Zip=93101&TaxType=sales&LicenseKey=[YourLicenseKey]


JSON response
{"TaxInfoItems":[{"Zip":"93101-7602","City":"Santa Barbara","County":"Santa Barbara","StateName":"California","StateAbbreviation":"CA","TaxRate":"0.0875","StateRate":"0.06","CityRate":"0.010","CountyRate":"0.0125","CityDistrictRate":"0","CountyDistrictRate":"0.005","SpecialDistrictRate":"0","NotesCodes":"","NotesDesc":"","InformationComponents":[{"Name":"CountyFIPS","Value":"083"}],"TotalTaxExempt":"LABOR\/FREIGHT\/SERVICES"}],"MatchLevel":"Address"}



XML Request: 
https://trial.serviceobjects.com/ft/web.svc/XML/GetBestMatch?Address=27+E+Cota+St+Ste+500&Address2=&City=Santa+Barbara&State=CA&Zip=93101&TaxType=sales&LicenseKey=[YourLicenseKey]


XML response
<BestMatchResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.serviceobjects.com/">
<TaxInfoItems>
<BestMatchTaxInfo>
<Zip>93101-7602</Zip>
<City>Santa Barbara</City>
<County>Santa Barbara</County>
<StateName>California</StateName>
<StateAbbreviation>CA</StateAbbreviation>
<TaxRate>0.0775</TaxRate>
<StateRate>0.0625</StateRate>
<CityRate>0</CityRate>
<CountyRate>0.010</CountyRate>
<CityDistrictRate>0</CityDistrictRate>
<CountyDistrictRate>0.005</CountyDistrictRate>
<SpecialDistrictRate>0</SpecialDistrictRate>
<NotesCodes/>
<NotesDesc/>
<InformationComponents>
<InformationComponent>
<Name>CountyFIPS</Name>
<Value>083</Value>
</InformationComponent>
</InformationComponents>
<TotalTaxExempt>LABOR/FREIGHT/SERVICES</TotalTaxExempt>
</BestMatchTaxInfo>
</TaxInfoItems>
<MatchLevel>Address</MatchLevel>
</BestMatchResponse>

GetTaxInfoByCityState Example Request and Response

JSON Request: 
https://trial.serviceobjects.com/ft/web.svc/JSON/GetTaxInfoByCityState?City=Santa+Barbara&State=CA&TaxType=sales&LicenseKey=licenseKey


JSON Response
{"Results":[{"City":"SANTA BARBARA","County":"SANTA BARBARA","CountyFIPS":"083","StateName":"CALIFORNIA","StateAbbreviation":"CA","TotalTaxRate":0.0875,"TotalTaxExempt":"LABOR\/FREIGHT\/SERVICES","StateRate":0.06,"CityRate":0.010,"CountyRate":0.0125,"CountyDistrictRate":0.005,"CityDistrictRate":0}]}



XML Request: 
https://trial.serviceobjects.com/ft/web.svc/XML/GetTaxInfoByCityState?City=Santa+Barbara&State=CA&TaxType=sales&LicenseKey=licenseKey


XML Response
<TaxInfoMultiResponse xmlns="http://serviceobjects.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<MultiTaxInfo>
<TaxInfoResponse>
<TaxInfo>
<City>SANTA BARBARA</City>
<County>SANTA BARBARA</County>
<CountyFIPS>083</CountyFIPS>
<StateName>CALIFORNIA</StateName>
<StateAbbreviation>CA</StateAbbreviation>
<TotalTaxRate>0.08</TotalTaxRate>
<TotalTaxExempt>LABOR/FREIGHT/SERVICES</TotalTaxExempt>
<StateRate>0.065</StateRate>
<CountyRate>0.010</CountyRate>
<CountyDistrictRate>0.005</CountyDistrictRate>
</TaxInfo>
</TaxInfoResponse>
</MultiTaxInfo>
</TaxInfoMultiResponse>

GetTaxInfoByCityCountyState Example Request and Response

JSON Request: 
https://trial.serviceobjects.com/ft/web.svc/JSON/GetTaxInfoByCityCountyState?City=Goleta&County=Santa+Barbara&State=CA&TaxType=sales&LicenseKey=licenseKey


JSON Response
{"City":"GOLETA","County":"SANTA BARBARA","CountyFIPS":"083","StateName":"CALIFORNIA","StateAbbreviation":"CA","TotalTaxRate":0.0775,"TotalTaxExempt":"LABOR\/FREIGHT\/SERVICES","StateRate":0.06,"CityRate":0,"CountyRate":0.0125,"CountyDistrictRate":0.005,"CityDistrictRate":0}



XML Request: 
https://trial.serviceobjects.com/ft/web.svc/XML/GetTaxInfoByCityCountyState?City=Goleta&County=Santa+Barbara&State=CA&TaxType=sales&LicenseKey=licenseKey


XML Response
<TaxInfoResponse xmlns="http://serviceobjects.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<TaxInfo>
<City>GOLETA</City>
<County>SANTA BARBARA</County>
<CountyFIPS>083</CountyFIPS>
<StateName>CALIFORNIA</StateName>
<StateAbbreviation>CA</StateAbbreviation>
<TotalTaxRate>0.08</TotalTaxRate>
<TotalTaxExempt>LABOR/FREIGHT/SERVICES</TotalTaxExempt>
<StateRate>0.065</StateRate>
<CountyRate>0.010</CountyRate>
<CountyDistrictRate>0.005</CountyDistrictRate>
</TaxInfo>
</TaxInfoResponse>

GetCanadianTaxInfoByProvince Example Request and Response

JSON Request: 
https://trial.serviceobjects.com/ft/web.svc/JSON/GetCanadianTaxInfoByProvince?Province=Ontario&LicenseKey=licenseKey


JSON Response
{"ProvinceName":"ONTARIO","ProvinceAbbreviation":"ON","GoodsSalesTax":0,"ProvinceSalesTax":0,"HarmonizedSalesTax":0.13,"ApplyGSTFirst":"False"}



XML Request: 
https://trial.serviceobjects.com/ft/web.svc/XML/GetCanadianTaxInfoByProvince?Province=Ontario&LicenseKey=licenseKey


XML Response
<CanadianTaxInfoResponse xmlns="http://serviceobjects.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CanadianTaxInfo>
<ProvinceName>ONTARIO</ProvinceName>
<ProvinceAbbreviation>ON</ProvinceAbbreviation>
<HarmonizedSalesTax>0.13</HarmonizedSalesTax>
<ApplyGTSFirst>False</ApplyGTSFirst>
</CanadianTaxInfo>
</CanadianTaxInfoResponse>


List of Operations

GetBestMatch (Recommend Operation) - Returns sales or use tax rates based on address information. If the address information fails, it will provide a zip code level match.  This operation can return multiple tax rates for zip Level matches
GetTaxInfoByCityCountyState – returns sales tax information for a given city/county/state combination. Returns one tax record.
GetTaxInfoByCityState – returns sales tax information for a given city/state combination. Can return multiple tax records in cases where the given city is bounded by multiple counties.
GetCanadianTaxInfoByProvince – returns sales tax information for a given Canadian province. All Canadian taxes are kept at the province level.

Each of these operations will be described in detail later in this document.

Operation Definitions

This document defines the input, output and behavior of the web service operations in FastTax. Each operation has its own unique behavior and output, although all of the operations are very similar and return almost identical output. You should examine your own business needs first before exploring what FastTax can provide. Different operations may be necessary based on the information you have, and the granularity of data you need.

GetBestMatch (Recommended Operation)

https://trial.serviceobjects.com/ft/web.svc/JSON/GetBestMatch?Address=[Address]&Address2=[Address2]&City=[City]&State=[State]&Zip=[Zip]&TaxType=[TaxType]&LicenseKey=[YourLicenseKeyHere]


This operation will return the best available tax rate match with the given input. If the given address input cannot be resolved or found, the operation will provide a Zip level match if the given zip code is valid. The service will provide a total tax rate for the given input as well as the different CountryDistrict, CityDistrict, City, County and State rates that the comprise the total rate returned. This operation also has the ability to determine whether or not a given address may be in an unincorporated area.  If the IsUnicorporated flag is returned in the NotesDesc field, then appropriate logic should be implemented tol remove the city or city district rates from the total rate as those would not apply for the given input. If the MatchLevel returned is "Zip" then this operation can also return multiple tax rates for the different tax jurisdictions combinations within the particular zip code. In this case, it would be up the user to determine what tax rate would prove to be the best match for the given input.

This operation may also return blank city or county information for certain requests.  Most of the time we can verify the location of an input address and fill in the appropriate city and county information with the verified address information. In other scenarios, the outputs may be missing those fields because the input address was bad, but we are still able to find applicable tax rates for the given address information. If you have further questions about this, please contact us at support@serviceobjects.com

NOTE: This operation will not remove any city tax rates for an address that receives an "IsUnincorporated" flag.  This logic will have to be set up in your code when calling this operation.


GetBestMatch Inputs

Name

Type

Values

Description

Address

String

Varies

 Address line associated with desired tax rates
Address2

String

Varies

Address2 line associated with desired tax rates
City

String

Varies

City associated with desired tax rates
State

String

Varies

 State associated with desired tax rates

Zip

String

Varies

The zip code associated with the desired tax rates

TaxType

String

sales / use

Selects the type of tax to look for, for the given area.

LicenseKey

String

Varies

Your license key to use the service.
Sign up for a free trial key at
https://www.serviceobjects.com/products/ecommerce/fasttax

GetBestMatch Outputs


GetBestMatchResponse
NameTypeValuesDescription
TaxInfoItemsBestMatchTaxInfo[]VariesPossible array of tax information
MatchLevelStringVariesA string indicating what level the returned tax rates could be resolved to (i.e. Address, Zip or Error)
ErrorErrorVariesAn error number and description associated with the input


BestMatchTaxInfo

Name

Type

Values

Description

Zip

String

Varies

The given zip code associated with the tax rate

City

String

Varies

The city associated with the given input

County

String

Varies

The county associated with the given input

StateAbbreviation

String

Two letter state code

The common two letter state abbreviation

StateNameStringVariesThe name of the state associated with the given tax rate

TaxRate

String

Decimal digit

The decimal representation of the overall tax rate

StateRate

String

Decimal digit

The decimal representation of the state's tax rate

CityRate

String

Decimal digit

The decimal representation of the city's tax rate

CountyRate

String

Decimal digit

The decimal representation of the county's tax rate

CountyDistrictRate

String

Decimal digit

The decimal representation of any special district tax rates for the county

CityDistrictRate

String

Decimal digit

The decimal representation of any special district tax rates for the city

SpecialDistrictRateStringDecimal digitThe decimal representation for any additional tax rates that may be added to a total tax rate.
InformationComponentsInformationComponent[]VariesAn array of name value pairs that contain extraneous information related to the input and or tax rate.
TotalTaxExemptStringVariesDifferent items that are exempt from being charged a sales tax.

NotesCodes

String

Varies

Codes corresponding to various NotesDesc results

NotesDesc

String

Varies

Various pieces of information about the tax information returned.

InformationComponent
NameTypeValueDescription
NameStringVariesThe variable name of the Name-Value pair that is to be returned
ValueStringValueThe resulting value of the of the variable returned in the "Name".

Error
NameTypeValueDescription
DescStringVariesDescriptions highlight what went wrong with the input given
NumberStringValueVarious codes that are associated with different types of errors. See error section for more information
LocationStringAlways nullDepreciated. No Longer Used

GetTaxInfoByCityCountyState

This operation returns a unique tax record given a city, county, state and tax type. It returns one record with the same data as the previous operations. 
This operation is a good one to use if the county information is readily available.DO NOT USE this operation for Minnesota rates though. Minnesota tracks rates by zip code and city and county rates might be different for each city/county based on the zip code.

GetTaxInfoByCityCountyState Inputs

Name

Type

Values

Description

City

String

Varies

A city name representing the city of the desired tax rate.

County

String

Varies

A county name representing the county of the desired tax rate.

State

String

Varies

The state name or abbreviation representing the state of the desired tax rate.

TaxType

String

sales / use

Selects the type of tax to look for, for the given area.

LicenseKey

String

Varies

Your license key to use the service.
Sign up for a free trial key at
https://www.serviceobjects.com/products/ecommerce/fasttax

GetTaxInfoByCityCountyState Outputs

Name

Type

Values

Description

Zip

String

Varies

The given zip code.

City

String

Varies

The city associated with the given zip code.

County

String

Varies

The county associated with the given zip code.

CountyFIPS

String

Three digit number

County FIPS(Federal Information Processing Standard) code; used to uniquely 
identify counties across the US.

StateName

String

Varies

The state associated with the give zip code.

StateAbbreviation

String

Two letter state code

The common two letter state abbreviation.

TotalTaxRate

String

Decimal digit

The decimal representation of the overall tax rate.

TotalTaxExempt

String

Varies

The exemptions available for that area. Combinations of Labor/Freight/Services.

StateRate

String

Decimal digit

The decimal representation of the state's tax rate.

CityRate

String

Decimal digit

The decimal representation of the city's tax rate.

CountyRate

String

Decimal digit

The decimal representation of the county's tax rate.

CountyDistrictRate

String

Decimal digit

The decimal representation of any special district tax rates for the county.

CityDistrictRate

String

Decimal digit

The decimal representation of any special district tax rates for the city.

Error – Desc

String

Varies

If there was an internal web service error, the description will be displayed here.

Error – Number

String

"1", "2", "4"

See "Error Codes" below.

Error – Location

String

Always null

Deprecated, no longer used.

GetTaxInfoByCityState

This operation returns a unique tax record given a city, state and tax type. It returns the exact same output as the previous operations. 
This operation is a replacement for GetTaxInfoByCityCountyState if county information is not present. It would be good to use if only city and state are available but has a higher likelihood than any other operation of returning multiple records. If more precise information is available, such as zip code it would be recommended to use that.DO NOT USE this operation for Minnesota rates. Minnesota tracks rates by zip code and city and county rates might be different for each city/county based on the zip code.

GetTaxInfoByCityState Inputs

Name

Type

Values

Description

City

String

Varies

A city name representing the city of the desired tax rate.

State

String

Varies

The state name or abbreviation representing the state of the desired tax rate.

TaxType

String

sales / use

Selects the type of tax to look for, for the given area.

LicenseKey

String

Varies

Your license key to use the service.
Sign up for a free trial key at
https://www.serviceobjects.com/products/ecommerce/fasttax

GetTaxInfoByCityState Outputs

Name

Type

Values

Description

Zip

String

Varies

The given zip code.

City

String

Varies

The city associated with the given zip code.

County

String

Varies

The county associated with the given zip code.

CountyFIPS

String

Three digit number

County FIPS(Federal Information Processing Standard) code; used to uniquely 
identify counties across the US.

StateName

String

Varies

The state associated with the give zip code.

StateAbbreviation

String

Two letter state code

The common two letter state abbreviation.

TotalTaxRate

String

Decimal digit

The decimal representation of the overall tax rate.

TotalTaxExempt

String

Varies

The exemptions available for that area. Combinations of Labor/Freight/Services.

StateRate

String

Decimal digit

The decimal representation of the state's tax rate.

CityRate

String

Decimal digit

The decimal representation of the city's tax rate.

CountyRate

String

Decimal digit

The decimal representation of the county's tax rate.

CountyDistrictRate

String

Decimal digit

The decimal representation of any special district tax rates for the county.

CityDistrictRate

String

Decimal digit

The decimal representation of any special district tax rates for the city.

Error – Desc

String

Varies

If there was an internal web service error, the description will be displayed here.

Error – Number

String

"1", "2", "4"

See "Error Codes" below.

Error – Location

String

Always null

Deprecated, no longer used.

GetCanadianTaxInfoByProvince

This operation should be used for any attempts to get Canadian tax information. Given a province name (or abbreviation), it returns sales tax information for that area. All Canadian taxes are kept at the province level and easy to check. But this operation provides an easy report for anyone using DOTS FastTax. While simple, Canadian rates do change periodically making this operation more useful. The outputs for Canadian Taxes are different from the previous operations. The full province name and its abbreviation are returned. In addition, there are three types of taxes returned for Canada. Provincial Sales Taxes (PST) are collected for most provinces. Goods and Services Tax (GST) is also applied in many cases. For a few provinces there is an alternative Harmonized Sales Tax (HST) which is a simplified blended version of PST and GST. In all cases, either HST or PST and GST apply (the other values will be 0 in each case). Finally, there is a last flag (ApplyGSTFirst). If set to true - GST should be applied to the price of the item first and then PST should be applied to the combined total. If false - the taxes are applied individually to the normal cost of the item.

GetCanadianTaxInfoByProvince Inputs

Name

Type

Values

Description

Province

String

Varies

The full name or abbreviation of the province to get tax rates for

LicenseKey

String

Varies

Your license key to use the service.
Sign up for a free trial key at
https://www.serviceobjects.com/products/ecommerce/fasttax

GetCanadianTaxInfoByProvince Outputs

Name

Type

Values

Description

ProvinceName

String

Varies

The full province name.

ProvinceAbbreviation

String

Two letter prov. code

The provinces abbreviated name.

GoodsSalesTax

String

Decimal digit

The value of the Goods and Services Tax for the province.

ProvinceSalesTax

String

Decimal digit

The value of the sales tax for the province. This value applies for PST, QST or RST.

HarmonizedSalesTax

String

Decimal digit

The value of the Harmonized sales tax for the province.

ApplyGSTFirst

String

"True" or "False"

A flag that tells if GST should be applied to the price prior to calculating PST, QST or RST. In the last several years this concept has gone away and all cases are now False.

Error – Desc

String

Varies

If there was an internal web service error, the description will be displayed here.

Error – Number

String

"1", "2", "4"

See "Error Codes" below.

Error – Location

String

Always null

Deprecated, no longer used.


GetTaxInfoByZip_V2 (Deprecated)

This is the basic operation for finding sales tax rates in the United States. Given a US zip code and a tax type, it returns sales tax information for that zip code. Several pieces of information are returned, starting with basic information about the area. Zip code, city, county, FIPS, and state are returned here. 
Six tax rates are also returned. An overall rate that represents the combined sales tax rate for that area and the five tax rates it is based on. These five rates are the state rate, the city rate, the county rate, the county district rate and the city district rate. Finally, a field representing any tax exemptions that might be available. Exemptions are normally kept at the state level and can consist of any combination of Labor, Freight and Services. By examining the WSDL, you may see that the service can return multiple tax rates (multiple TaxInfo results). This is because at the zip code level, it is possible that there may be additional matches found. Zip codes can border multiple cities and counties and each might have a different tax rate. It is important to consider all of the results since any of them may be the correct one.

GetTaxInfoByZip_V2 Inputs

Name

Type

Values

Description

PostalCode

String

Varies

The zip code associated with the desired tax rates

TaxType

String

sales / use

Selects the type of tax to look for, for the given area.

LicenseKey

String

Varies

Your license key to use the service. 
Sign up for a free trial key at 
www.serviceobjects.com.

GetTaxInfoByZip_V2 Outputs

Name

Type

Values

Description

Name

Type

Values

Description

Zip

String

Varies

The given zip code

City

String

Varies

The city associated with the given zip code

County

String

Varies

The county associated with the given zip code

CountyFIPS

String

Three digit number

The FIPS code associated with the zip code

StateName

String

Varies

The state associated with the give zip code

StateAbbreviation

String

Two letter state code

The common two letter state abbreviation

TotalTaxRate

String

Decimal digit

The decimal representation of the overall tax rate

TotalTaxExempt

String

Varies

The exemptions available for that area. Combinations of Labor/Freight/Services

StateRate

String

Decimal digit

The decimal representation of the state's tax rate

CityRate

String

Decimal digit

The decimal representation of the city's tax rate

CountyRate

String

Decimal digit

The decimal representation of the county's tax rate

CountyDistrictRate

String

Decimal digit

The decimal representation of any special district tax rates for the county

CityDistrictRate

String

Decimal digit

The decimal representation of any special district tax rates for the city

Error – Desc

String

Varies

If there was an internal web service error, the description will be displayed here.

Error – Number

String

"1", "2", "4"

See "Error Codes" below.

Error – Location

String

Always null

Deprecated, no longer used.


Error Codes

Error codes in DOTS FastTax are the same for all operations. They are as follows:

Error Code 1 – "Input cannot be less than zero length"

This error means the web service did not get any input. The connection to the service was made, and data was transferred, but no parameters were passed that the service could understand. This error often happens when input is passed to the service with namespaces that the service does not understand. Applying a namespace to any of the parameters (such as zip code or county , in this service) will cause this error. Additionally, requests made in the "rpc/encoded" format will cause this error. The only namespace that should appear in any element is the "http://www.serviceobjects.com" namespace on the root GetTaxInfoByZip_V2 element as so:

<TaxInfoMulti xmlns="http://www.serviceobjects.com/">


Note, however, that the namespace is not applied to the TaxInfoMulti element, it is only present.

Error Code 2 – Various descriptions

This error code appears when various errors occur, but are of the expected nature. Oftentimes, maligned or incomplete input will cause an error 2.

Error Code 4 – Various descriptions

An error code 4 is a fatal error and it means something has seriously gone wrong. You should never see an error code 4 in a live production environment.

Frequently Asked Questions

Which Operation Should You Use?

Our newest operation, GetBestMatch would be the recommended operation. It integrates the behavior of two deprecated operations, GetTaxInfoByAddress and GetTaxInfoByZipV2.  The GetBestMatch operation will first try to validate an address and find an applicable tax rate for it. If an address level tax rate cannot be found, the operation will then use the City, State and Zip Code inputs to provide a less granular match of tax rates.

GetBestMatch is returning blank City/County information. Why is the data not present?

Most of the time we can fill in the city and county information for a request.  There are certain cases where an input address may be bad and as such we cannot reliably fill in the city and/or county names for a certain request. This occurs most frequently in Zip  level matches, and occasionally in certain Address Level matches.  We are currently working on adding a field to the InformationComponents field that will allow us to provide a best guess at the applicable City or County name and still preserve the accuracy of the tax rate information that is returned.

Help! All I see is GST, PST and HST, what about QST for Quebec and RST for Manitoba?

When the GetTaxInfoByProvince operation was created, neither QST or RST existed as they do now. They were known as PST. The reality is that they still act the same as PST, they just have a more personalized name. While Service Objects continues to accurately update the Canadian tax rates anytime changes are needed, we have not created the new operation that would be needed to accurately display the new sales tax names for Quebec and Manitoba. Service Objects will never change the name of an existing output name as that would likely break the integrations of many of our clients.

Users looking up tax rates for Quebec and Manitoba can still get accurate rates by combining the values of <GoodsSalesTax> with <ProvinceSalesTax>.  While we did initially intend <ProvinceSalesTax> to mean PST, it can now instead be read as the tax rate for the Province which encompasses PST, QST and RST.

GetBestMatch doesn't return a value that I need. Can it be updated?

Potentially, yes! GetBestMatch has a field called "InformationComponents" this field returns an array of key-value pairs that allow us to add new fields to the service without risking the possibility of breaking current integrations with the service.  Please reach out to us at support@serviceobjects.com and we would be happy to look into updating the service to meet your needs.

Why are there operations that end with a V2?

When we need to enhance our service that includes the changing of either the input or output interfaces, its best to create a new operation. If we change the interface of an existing operation, we potentially adversely affect hundreds of current customers. 
If you are a new client or in a position to make a change, it is usually always best to switch to the new operation as it likely has important new enhancements.

What about restaurant, lodging and other taxes?

Currently, DOTS FastTax only supports general sales and use tax. There are no current plans to add other datasets/sources.

The Sample Code is Giving Strange Errors or is Crashing!

Most likely, the sample code cannot connect to Service Objects. Many environments will not allow you to connect out on port 80, or will clip out XML data from these requests/responses.

The easiest way to check for this is to open a browser on the machine running the sample code. In your browser, navigate to: 
https://trial.serviceobjects.com/ft/FastTax.asmx

Then try to run one of the operations with your trial key. If you get a browser error, or get no data back, then the sample code isn't able to connect, either. Contact your systems administrator to resolve why you are not able to connect to Service Objects.

I'm Not a Programmer. How Do I Use DOTS FastTax?

Service Objects runs batches for you! A free batch trial is available at
https://www.serviceobjects.com/batch/upload.

Conclusion

Service Objects is proud to offer you a free trial of DOTS FastTax. 

Other technical questions or concerns can be directed to support@serviceobjects.com.

If you are interested in purchasing DOTS FastTax, US, please contact sales@serviceobjects.com.


  
We want to hear from you! We're always looking to improve our developer guides. 
Please email your suggestions to devguidefeedback@serviceobjects.com.

  • No labels