Checking VAT identification numbers using JavaScript

The EU Commission provides the checkVat web service to check the validity of EU VAT Identification Numbers (wsdl, redirected target).

To perform the web service query in the browser, I used the JavaScript SOAP Client on CodePlex which worked after a couple of tweaks.

First, IE9 seems to be unable to concatenate an XML document and an empty string, resulting in a Script Error. (see this post on the Discussion page). Edit the _loadWsdl function and modify the line checking the wsdl to:

if(typeof(wsdl) != "object" && wsdl + "" != "" && wsdl + "" != "undefined")

Next, the version of MSXML installed on my current work PC does not support the local-name() XPath function required in the function _getElementsByTagName. Since this function is used to retrieve the SOAP result only, and the result node is always on the same level in XML, I added to the function:

try
{
  var nd = document.selectNodes("//*/*/*/" + tagName );
  if (nd.length > 0) {
   return nd;
  }
}
catch (ex) {}
try
{
  return document.selectNodes("//*/*/urn:" + tagName );
}
catch (ex) {}

This handles both the SOAP *Result and *Response nodes (the checkVat service adds a urn: namespace to the response attributes).

The checkVat web service is somewhat “special” (at least according to my experience) in that it defines the parameters types in a sub-namespace (xsd:schema targetNamespace=”urn:ec.europa.eu:taxud:vies:services:checkVat:types”) rather than the web service’s namespace (wsdl:definitions targetNamespace=”urn:ec.europa.eu:taxud:vies:services:checkVat”). The parameter types namespace is also used in the Response (xmlns:urn=”urn:ec.europa.eu:taxud:vies:services:checkVat:types”).

I finally gave up trying to retrieve the correct namespace with XPath and simply added the line to _sendSoapRequest:

ns = ns + ":types";

The mismatch in namespaces causes Visual Studio to issue a comment in the generated Reference.cs file:

// CODEGEN: Generating message contract since the wrapper namespace (urn:ec.europa.eu:taxud:vies:services:checkVat:types) of message “checkVatRequest” does not match the default value (urn:ec.europa.eu:taxud:vies:services:checkVat).

Further, the checkVat service does not return a Result node, but only a Response message (probably the cause for the out parameters generated in C#).

So I had to fix the _onSendSoapRequest function to parse the Response node:

var nd = SOAPClient._getElementsByTagName(req.responseXML, method + "Result");
if(nd.length == 0)
  nd = SOAPClient._getElementsByTagName(req.responseXML, method + "Response");
if(nd.length == 0)
  nd = SOAPClient._getElementsByTagName(req.responseXML, "return"); // PHP web Service?

and remove the urn: namespace in the result elements (_node2object):

obj[node.childNodes[i].nodeName.replace("urn:", "")] = p;

Finally, my test page containing the web service call for both a valid and an invalid VATID was able to call the script:

var url = "http://ec.europa.eu/taxation_customs/vies/services/checkVatService";

function CheckVATOk()
{
  var pl = new SOAPClientParameters();
  pl.add("countryCode", "AT");
  pl.add("vatNumber", "U40600000");
  SOAPClient.invoke(url, "checkVat", pl, true, CheckVAT_callBack);
}
function CheckVATInvalid()
{
  var pl = new SOAPClientParameters();
  pl.add("countryCode", "XX");
  pl.add("vatNumber", "U40600000");
  SOAPClient.invoke(url, "checkVat", pl, true, CheckVAT_callBack);
}
function CheckVAT_callBack(r, rawXml)
{
  if (typeof(r.valid) != "undefined")
  {
    alert(r.countryCode + " " + r.vatNumber + "\r\n" + r.name + ": " +
      r.address + "\r\n" + r.valid);
  }
  else if (typeof(r.number) != "undefined")
  {
    alert(r.name + " " + r.number + ": " +
      r.message.replace(/[{}\s']/g, ""));
  }
  else
  {
    alert(r);
  }
}

In case of an error, the error message needs to be stripped of a couple of “special” characters to get a character-only error string.

The code worked from a local html page, but not when executed inside a web application. This is due to the Same Origin Policy and raises the message “This Page Accesses Data on Another Domain” in IE9 unless you make the browser “trust” the web service’s host.

To work around this problem, you’d need to implement a local webservice calling the remote checkVat web service.

Advertisements

5 Responses to Checking VAT identification numbers using JavaScript

  1. Your corrections to the soap client aren’t exact enough, that I can fix it myself. Is there anyway you could provide the fixed file?

  2. Franz Sepphonen says:

    Is it possible that you could upload the file a second time?

  3. Krish says:

    Dear devio,

    I was trying to implement VAT validation by referring your method, how ever I keep on getting an error Access is denied for : “xmlHttp.open(“GET”, url + “?wsdl”, async);”

    Please help me with this.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: