Search code examples
phpxmlhttprequest

Why does this VAT number validation script return an error?


I am trying to validate EU VAT numbers using the script by Eugene Mihailescu that can be found here: https://stackoverflow.com/a/29955950 Although this script was working flawlessly up until a recently, now Apache comes up with the following error:

PHP Warning:  file_get_contents(http://ec.europa.eu/taxation_customs/vies/services/checkVatService): failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error

I searched and found a cUrl version of the same script by Professor Abronsius which can be found here:

https://stackoverflow.com/a/56035880

Unfortunately a similar error comes up in the console:

Object { response: false, info: {…}, errors: "The requested URL returned error: 500 Internal Server Error" } errors: "The requested URL returned error: 500 Internal Server Error" info: Object { url: "https://ec.europa.eu/taxation_customs/vies/services/checkVatService", http_code: 500, header_size: 0, … } …….

To my understanding the problem may rely in the "VIES" server itself, but there are no announcements in their website: https://ec.europa.eu/taxation_customs/vies/#/vat-validation

Any ideas/suggestions?


Solution

  • Ran into the same problem, searched a little bit, and it seems that soap envelope as changed. Made some changes and included some functions to maintain previous workflow. Hope it helps

    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 array_key_replace($item, $replace_with, array $array){
        $updated_array = [];
        foreach ($array as $key => $value) {
            if (!is_array($value) && $key == $item) {
                $updated_array = array_merge($updated_array, [$replace_with => $value]);
                continue;
            }
            $updated_array = array_merge($updated_array, [$key => $value]);
        }
        return $updated_array;
    }
    
     function string_between_two_string($str, $starting_word, $ending_word)
    {
        $subtring_start = strpos($str, $starting_word);
        //Adding the starting index of the starting word to
        //its length would give its ending index
        $subtring_start += strlen($starting_word); 
        //Length of our required sub string
        $size = strpos($str, $ending_word) - $subtring_start; 
        // Return the substring from the index substring_start of length size
        return substr($str, $subtring_start, $size); 
    }
    function viesCheckVAT($countryCode, $vatNumber, $timeout = 30) {
        $response = array ();
        $pattern = '/<(%s).*?>([\s\S]*)<\/\1/';
        $keys = array (
                'countryCode',
                'vatNumber',
                'requestDate',
                'valid',
                'name',
                'address' 
        );
        //Changed envelope
         $content = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'
     xmlns:tns1='urn:ec.europa.eu:taxud:vies:services:checkVat:types'
     xmlns:impl='urn:ec.europa.eu:taxud:vies:services:checkVat'>
     <soap:Header>
     </soap:Header>
     <soap:Body>
        <tns1:checkVat xmlns:tns1='urn:ec.europa.eu:taxud:vies:services:checkVat:types'
        xmlns='urn:ec.europa.eu:taxud:vies:services:checkVat:types'>
        <tns1:countryCode>".$countryCode."</tns1:countryCode>
        <tns1:vatNumber>".$vatNumber."</tns1:vatNumber>
       </tns1:checkVat>
     </soap:Body>
    </soap:Envelope>";
    
    
        $opts = array (
                'http' => array (
                        'method' => 'POST',
                        'header' => "Content-Type: text/xml; charset=utf-8;",
                        'content' => sprintf ( $content ),
                        'timeout' => $timeout 
                ) 
        );
    
        $ctx = stream_context_create ( $opts );
        $result = file_get_contents ( 'https://ec.europa.eu/taxation_customs/vies/services/checkVatService', false, $ctx );
        //extract necessary values from answer string
        $valid = string_between_two_string($result, '<ns2:valid>', '</ns2:valid>');
        $country = string_between_two_string($result, '<ns2:countryCode>', '</ns2:countryCode>');
        $vatnumber = string_between_two_string($result, '<ns2:vatNumber>', '</ns2:vatNumber>');
        $address = string_between_two_string($result, '<ns2:address>', '</ns2:address>');
        $name = string_between_two_string($result, '<ns2:name>', '</ns2:name>');
        $dater = string_between_two_string($result, '<ns2:requestDate>', '</ns2:requestDate>');
    
        //insert strings in array and replace index keys by name
        $vat = "$country$vatnumber";
        $vars = array($vat, $name, $address, $dater, $valid);
        $new_array = array_key_replace('0', 'vat', $vars);
        $new_array = array_key_replace('0', 'name', $new_array);
        $new_array = array_key_replace('0', 'address', $new_array);
        $new_array = array_key_replace('0', 'requestDate', $new_array);
        $new_array = array_key_replace('0', 'status', $new_array);
    
    
    
        return $new_array;
    }
    
    print_r (viesCheckVAT ( 'RO', '19386256' ));