VIES VAT number validation

If for some reasons you can't use SOAP on your server (no available, whatever) then file_get_contents is your friend.

The implementation below does not depend on SOAP, Curl, XMLParser (Simple or not). It is standard PHP code that should work on any PHP version you may have.

The function returns the following items:

  • countryCode
  • vatNumber
  • requestDate
  • valid
  • name
  • address

Well, I hope it helps :-)

<?php
DEFINE ( 'VIES_URL', 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService' );

/**
 * VIES VAT number validation
 *
 * @author Eugen Mihailescu
 *        
 * @param string $countryCode           
 * @param string $vatNumber         
 * @param int $timeout          
 */
function viesCheckVAT($countryCode, $vatNumber, $timeout = 30) {
    $response = array ();
    $pattern = '/<(%s).*?>([\s\S]*)<\/\1/';
    $keys = array (
            'countryCode',
            'vatNumber',
            'requestDate',
            'valid',
            'name',
            'address' 
    );

    $content = "<s11:Envelope xmlns:s11='http://schemas.xmlsoap.org/soap/envelope/'>
  <s11:Body>
    <tns1:checkVat xmlns:tns1='urn:ec.europa.eu:taxud:vies:services:checkVat:types'>
      <tns1:countryCode>%s</tns1:countryCode>
      <tns1:vatNumber>%s</tns1:vatNumber>
    </tns1:checkVat>
  </s11:Body>
</s11:Envelope>";

    $opts = array (
            'http' => array (
                    'method' => 'POST',
                    'header' => "Content-Type: text/xml; charset=utf-8; SOAPAction: checkVatService",
                    'content' => sprintf ( $content, $countryCode, $vatNumber ),
                    'timeout' => $timeout 
            ) 
    );

    $ctx = stream_context_create ( $opts );
    $result = file_get_contents ( VIES_URL, false, $ctx );

    if (preg_match ( sprintf ( $pattern, 'checkVatResponse' ), $result, $matches )) {
        foreach ( $keys as $key )
            preg_match ( sprintf ( $pattern, $key ), $matches [2], $value ) && $response [$key] = $value [2];
    }
    return $response;
}

print_r ( viesCheckVAT ( 'RO', '19386256' ) );
?>

Actually, the VIES database can be queried via their API.
They support only the SOAP protocol, but that should be sufficient.

Here's a simple example:

$client = new SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl");
var_dump($client->checkVat(array(
  'countryCode' => $countryCode,
  'vatNumber' => $vatNo
)));

Here's the WSDL: http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

There are multiple providers of APIs which are based on the original one, but provide it using different protocols. Simply told, they act like translators - using json with your application and connect using SOAP to the original API. These have a major problem with the connection timeout.

There are times where the VIES database is responding slowly, thus requiring more time to return a response. This should be considered while designing your application.