VAT number validation with VIES
For a couple of our clients we implemented a webshop with Drupal and Ubercart. One feature which was missing from the default Ubercart setup, was a VAT number field, and the accompanying validation.
After some googling I found out about the VAT number module . This module adds a VAT field to the checkout billing fieldset, depending on which country you have selected. Because only european corporate visitors should be able to fill in a VAT number, it’s useless for other countries and can be hidden.
Now there are 2 ways of validating a VAT number:
1. Through a fixed preg-match scheme, which validates the format of the VAT number depending on the country. This method ensures you have a valid formatted VAT number but it does not validate if this VAT number belongs to an actual company. Hence method 2.
2. You can also validate a VAT number through the European VAT validation service, in short “VIES”. They allow for a developer to do a Soap call to their service, providing the country code and VAT number. The Drupal module already provides this Soap call, but there has been an update to the VIES services, and the endpoint url of the Soap service has moved.
So to get your VAT checker up and running again, here’s The Fix:
Just replace the existing endpoint by the new one:
$client = new SoapClient("http://ec.europa.eu/taxation_customs/vies/api/checkVatPort?wsdl");
By
$client = new SoapClient("http://ec.europa.eu/taxation_customs/vies/services/checkVatService.wsdl");
For a full implementation on how to do a VAT validation through SOAP:
function hale_validate_vat($args = array()) { if ( '' != $args['vatnumber'] ) { $vat_number = str_replace(array(' ', '.', '-', ',', ', '), '', $args['vatnumber']); $countryCode = substr($vat_number, 0, 2); $vatNumber = substr($vat_number, 2); if ( strlen($countryCode) != 2 || is_numeric(substr($countryCode, 0, 1)) || is_numeric(substr($countryCode, 1, 2)) ) { $error = array('result' => false, 'message' => 'Your VAT Number syntax is not correct. You should have something like this: BE805670816B01'); return $error; } if ( $args['country'] != $countryCode ) { $error = array('result' => false, 'message' => 'Your VAT Number is not valid for the selected country.'); return $error; } $client = new SoapClient("http://ec.europa.eu/taxation_customs/vies/services/checkVatService.wsdl"); $params = array('countryCode' => $countryCode, 'vatNumber' => $vatNumber); $result = $client->checkVat($params); if ( !$result->valid ) { $error = array('result' => false, 'message' => sprintf('Invalid VAT Number. Check the validity on the customer VAT Number via <a href="%s">Europa VAT Number validation webservice</a>', 'http://ec.europa.eu/taxation_customs/vies/lang.do?fromWhichPage=vieshome')); return $error; } else { return true; } } return false; }
Use it like this:
$result = hale_validate_vat(array(‘vatnumber’ => ‘BE0123456789′, ‘country’ => ‘BE’));
Where the result is either TRUE or contains the error message in $result['message']
Update: Like promised in the comments below I have created a txt file with the code of this post and some comments. Download it here.
Greets,
Kim