[SOLVED] EU VAT ID validation doesn't work if your hosting is in a non-English-speaking country

Discussion in 'Troubleshooting' started by riccardo, May 21, 2016.

Thread Status:
Not open for further replies.
  1. riccardo

    riccardo New Member

    Joined:
    May 19, 2016
    Messages:
    13
    Hello everybody,
    I've started configuring my first aMember PRO (v5.1.1) yesterday. Looking for a way to solve another couple of problems (today being Saturday, I thought I may as well take a look myself before contacting support on Monday) I stumbled into a bug in EU VAT ID validation.

    In file amember/library/Am/Form/Brick.php, starting from line 2387, the following code validates a VAT ID by checking it with the European Commission web site:

    PHP:
            $req = new Am_HttpRequest('http://ec.europa.eu/taxation_customs/vies/vatResponse.html'Am_HttpRequest::METHOD_POST);
            
    $req->addPostParameter('action''check')
                ->
    addPostParameter('check''Verify')
                ->
    addPostParameter('memberStateCode'strtoupper(substr($id02)))
                ->
    addPostParameter('number'substr($id2))
                ->
    addPostParameter('requesterMemberStateCode''')
                ->
    addPostParameter('traderName''')
                ->
    addPostParameter('traderCompanyType''')
                ->
    addPostParameter('traderStreet''')
                ->
    addPostParameter('traderPostalCode''')
                ->
    addPostParameter('traderCity''')
                ->
    addPostParameter('requesterNumber''');
            try {
                
    $resp $req->send();
                
    $ok preg_match('/Yes[,\s]+valid\s+VAT\s+number/i'$resp->getBody());
                
    Am_Di::getInstance()->cache->save($ok 0$cacheKey);
                if (!
    $ok)
                    return 
    $this->___('Invalid VAT Id, please try again');
            } catch (
    Exception $e) {
                
    Am_Di::getInstance()->errorLogTable->log($e);
                return 
    $this->___("Cannot validate VAT Id, please try again");
            }
    This simulates a VAT ID check done with a browser. Which is fine, except that the EU Commission server uses gelocation to serve content in different languages... so if your hosting server is in Italy you will never find the string "Yes, valid VAT number" in the response; instead it will state "Sì, partita IVA valida".

    The solution is, obviously, to look for a language-independent string that characterizes a "valid VAT number" response. Luckily it was not hard to find.

    The "Yes..." / "Sì..." sentence is always enclosed in a span tag with a class of "validStyle". If the posted VAT ID is not valid, the corresponding "No" answer is in a span tag with an "invalidStyle" class.

    Therefore, to make the validation work regardless of locale, I modified line 2401 as such:
    PHP:
                $ok preg_match('/<span\s+class\s*=\s*"validStyle"\s*>/i'$resp->getBody());
    It's not the technically most correct approach (that would involve actually parsing the HTML response) but it gets the job done.

    By the way, I also noticed that validation results get cached, which may not be desirable in times when small enterprises (at least here in Italy) get shut down practically every day.
    To disable caching of VAT ID validation results, just comment out lines 2379 to 2383 and line 2402.

    I'm posting here in case this is useful to someone else.

    All the best
    Ric
    caesar likes this.
  2. caesar

    caesar aMember Pro Developer Staff Member

    Joined:
    Oct 16, 2009
    Messages:
    1,669
    It is good point. We will include it to upcoming release as well.
Thread Status:
Not open for further replies.

Share This Page