2

I have fine this interesting function at this link This work well for check the VAT number in EU. But I can't integrate with my registration form. I will like to transform this in a js function, to use this before I send the registration data, I'm trying but I can't do it, can same one help me?

The code is this in the link

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 ( 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService', 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;
  }

   $arr = viesCheckVAT($countryCode, $vatNumber);

   if ($arr[valid] == fasle) {
    ...
    } else {
    ...
    }

Now I really like to use this servis true Javasscript. In the way I can check the number before sending data via PHP.

How I can write this function in JS? For the array there are not problem, but can I make the SOAP call?

Marco Romano
  • 272
  • 1
  • 14
  • Rather than convert the above to javascript ( which would be a lot of work ) might I suggest that you keep this as PHP and call it via ajax / fetch from your registration form prior to sending the form? – Professor Abronsius May 08 '19 at 06:46
  • In my experience this validation service regularly doesn't work. Don't make form submission dependent on it. I always check afterwards. – KIKO Software May 08 '19 at 06:48
  • @RamRaider I know that are long work, but in ajax I can keep the same code? How I can tell to the ajax to check this before send the data? – Marco Romano May 08 '19 at 06:50
  • @KIKOSoftware thank you for your feedback. I try just a few numbers and work well. But if you tell this maybe you are true. do you have fine another solution? – Marco Romano May 08 '19 at 06:52
  • 1
    No this is _the_ autority. You have to use it, but just don't depend on it always working. It does not. I googled and did find a JS version: [jsvat](https://github.com/se-panfilov/jsvat). – KIKO Software May 08 '19 at 06:54
  • @KIKOSoftware, yes, I had seen this, but they only do a syntax check. I know that is something but isn't the best solution. I try to write the code if I can well, otherwise I try to use this service. thank you. – Marco Romano May 08 '19 at 06:59
  • Ah, and here's a blog confirming what I am trying to warn you about: [How the EU made our website slow](https://scotthelme.co.uk/how-the-eu-made-our-website-slow) – KIKO Software May 08 '19 at 06:59
  • 1
    Ok, well, I only googled that, it looked good. I would do as RamRaider said: Don't bother converting this to JS, use AJAX if you really need it in JS. – KIKO Software May 08 '19 at 07:01
  • yes I try to do in ajx. I find this link that give me some idea to how make the soap call. https://stackoverflow.com/questions/12796941/how-to-call-soap-ws-from-javascript-jquery – Marco Romano May 08 '19 at 07:05
  • 1
    The easiest way to perform an AJAX call to your VAT validation PHP script is with JQuery. See: [jQuery Ajax](https://www.tutorialrepublic.com/jquery-tutorial/jquery-ajax.php). Some people insist on doing it without JQuery, which is definately possible: [Pure JavaScript ajax](https://medium.com/@igorstimoli/pure-javascript-ajax-imagine-a-world-without-jquery-eb22d438df22) – KIKO Software May 08 '19 at 07:10

1 Answers1

4

Having mentioned that perhaps you ought to keep the above as PHP and call it via an Ajax call I quickly put together the following to show how this might be done. The PHP code is based upon the above function but modified to use curl instead.

<?php
    if( $_SERVER['REQUEST_METHOD']=='POST' && !empty( $_POST['task'] ) && $_POST['task']=='check' ){
        ob_clean();

        $result=null;

        function curl( $url=NULL, $options=NULL, $headers=false ){
            /* Initialise curl request object */
            $curl=curl_init();

            /* Define standard options */
            curl_setopt( $curl, CURLOPT_URL,trim( $url ) );
            curl_setopt( $curl, CURLOPT_AUTOREFERER, true );
            curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
            curl_setopt( $curl, CURLOPT_FAILONERROR, true );
            curl_setopt( $curl, CURLOPT_HEADER, false );
            curl_setopt( $curl, CURLINFO_HEADER_OUT, false );
            curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
            curl_setopt( $curl, CURLOPT_BINARYTRANSFER, true );
            curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 20 );
            curl_setopt( $curl, CURLOPT_TIMEOUT, 60 );
            curl_setopt( $curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' );
            curl_setopt( $curl, CURLOPT_MAXREDIRS, 10 );
            curl_setopt( $curl, CURLOPT_ENCODING, '' );

            /* Assign runtime parameters as options */
            if( isset( $options ) && is_array( $options ) ){
                foreach( $options as $param => $value ) curl_setopt( $curl, $param, $value );
            }

            if( $headers && is_array( $headers ) ){
                curl_setopt( $curl, CURLOPT_HTTPHEADER, $headers );
            }

            /* Execute the request and store responses */
            $res=(object)array(
                'response'  =>  curl_exec( $curl ),
                'info'      =>  (object)curl_getinfo( $curl ),
                'errors'    =>  curl_error( $curl )
            );
            curl_close( $curl );
            return $res;
        }






        function checkvat( $code, $vatnumber, $timeout=30 ){
            $url='http://ec.europa.eu/taxation_customs/vies/services/checkVatService';

            $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>";

            $headers=array(
                'Content-Type'  =>  'text/xml; charset=utf-8',
                'SOAPAction'    =>  'checkVatService'
            );
            $options=array(
                CURLOPT_POST        =>  true,
                CURLOPT_POSTFIELDS  =>  sprintf ( $content, $code, $vatnumber )
            );
            return curl( $url, $options, $headers );
        }








        $code=$_POST['code'];
        $vatnumber=$_POST['vat'];

        /* check the VAT number etc */
        $obj=checkvat( $code, $vatnumber );

        /* if we received a valid response, process it */
        if( $obj->info->http_code==200 ){

            $dom=new DOMDocument;
            $dom->loadXML( $obj->response );

            $reqdate=$dom->getElementsByTagName('requestDate')->item(0)->nodeValue;
            $valid=$dom->getElementsByTagName('valid')->item(0)->nodeValue;
            $address=$dom->getElementsByTagName('address')->item(0)->nodeValue;

            $result=sprintf( 'VAT Number "%s" in Country-Code "%s" - Date: %s, Valid: %s, Address: %s', $vatnumber, $code, $reqdate, $valid, $address ); 
        }

        exit( $result );
    }
?>
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>VAT checker</title>
        <script>

            const ajax=function( url, params, callback ){
                let xhr=new XMLHttpRequest();
                xhr.onload=function(){
                    if( this.status==200 && this.readyState==4 )callback( this.response )
                };
                xhr.open( 'POST', url, true );
                xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
                xhr.send( buildparams( params ) );
            };

            const buildparams=function(p){/* construct payload/querystring from object */
                if( p && typeof( p )==='object' ){
                    p=Object.keys( p ).map(function( k ){
                        return typeof( p[ k ] )=='object' ? buildparams( p[ k ] ) : [ encodeURIComponent( k ), encodeURIComponent( p[ k ] ) ].join('=')
                    }).join('&');
                }
                return p;
            };




            document.addEventListener('DOMContentLoaded', ()=>{
                let form=document.forms.registration;
                    form.bttn.addEventListener('click', e=>{
                        let url=location.href;
                        let params={
                            'task':'check',
                            'vat':form.vat.value,
                            'code':form.code.value
                        };
                        let callback=function(r){
                            document.querySelector('pre').innerHTML=r
                        }
                        ajax.call( this, url, params, callback );
                    })
            });
        </script>
    </head>
    <body>
        <form method='post' name='registration'>
            <!-- lots of other form elements -->


            <!--
                The details in the form (vat-number) is bogus
                and will not return live data...
            -->
            <label for='vat'><input type='text' name='vat' value='10758820' /></label>
            <label for='code'><input type='text' name='code' value='GB' /></label>
            <input type='button' value='Check VAT' name='bttn' />


        </form>
        <pre></pre>
    </body>
</html>
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • wow. ok. I have just try to use this in a page and works! thank you! Now I try to use in my website to see if I can check VAT before make the registration. but thank you!! – Marco Romano May 08 '19 at 07:58
  • No problems - though as pointed out by @KikoSoftware if it is prone to failure (? I do not know ) then any code that relies upon the result from the VAT check needs to be carefully considered. Good luck – Professor Abronsius May 08 '19 at 08:04
  • I try to use some real VAT from different country and at moment works. I don't know if is a problem about connection or database. But my random tests were positive. ca you give me a hint? instead of using the click function, to check the vat when the field has been filled in what I can use. type Change? – Marco Romano May 08 '19 at 08:22
  • Ok I trying to use keyup – Marco Romano May 08 '19 at 08:41
  • work really well!! I just use `keyup` + adding some more js in the `callback=function` and I can do everything! big thank you!! – Marco Romano May 08 '19 at 10:07
  • :-) glad that it has helped ! Good luck with the rest – Professor Abronsius May 08 '19 at 10:16