VATify.eu API
PHP example

The script below implements a very simple VATify.eu REST API client written in PHP. Note that this is example code without input sanitization or proper error handling.

Download the source file here. To test with a browser, first edit the $API_CLIENT_ID and $API_ACCESS_KEY constants, then upload the file to your web server. Input parameters should be specified as query string within the URL. For example:
https://host.domain.tld/api_client.php?coun­try=BE&com­pany=0248015142

See this guide for more in­for­ma­ti­on about how to use the VATify.eu REST APIs.

<?php
/*
 *  VATify.eu REST API: PHP client (example code)
 *  Copyright (C) 2022 KoMnA d.o.o. <code@komna.com>
 *
 *  Permission to use, copy, modify, and distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

$API_CLIENT_ID = '...<YourClientID>...';
$API_ACCESS_KEY = '...<YourAccessKey>...';

error_reporting(E_ALL);
ini_set('display_errors', 'On');
ini_set('html_errors', 'On');


/*
 *  API client demonstration -- main function
 *
 *  Use query string parameters to obtain the country and company ID,
 *  authenticate to the VATify.eu API server, preform a real-time
 *  query, and print the resulting company data.
 */
function main() {

    // Get country and company ID.
    $country = $_GET['country'];
    $company = $_GET['company'];

    // Authenticate by exchanging the long-term login credentials for a
    // time-limited bearer token.
    $bearer_token = get_bearer_token($API_CLIENT_ID, $API_ACCESS_KEY);

    // Start a VATify.eu real-time query.
    $polling_url = run_query($bearer_token, $country, $company);

    // Wait until the results are ready.
    $results = null;
    $delay = 0;
    while (!$results) {
        if ($delay < 10000000)
            $delay += 500000;
        usleep($delay);
        $results = get_query_results($bearer_token, $polling_url);
    }

    // Output the results.
    $output = '<!DOCTYPE html><HTML><HEAD><TITLE>PHP API Client Demo</TITLE>'
      . '<META http-equiv="Content-Type" content=text/html; charset=UTF-8" />'
      . '</HEAD><BODY><PRE>'
      . htmlspecialchars(json_encode($results, JSON_PRETTY_PRINT))
      . '</PRE></BODY></HTML>';
    echo $output;
}


/*
 *  A general function used by all API calls for actual HTTPS request handling.
 * 
 *  Makes an HTTPS request as specified by the arguments, returning server's
 *  response with status, headers and payload included.  This is just basic
 *  processing, no header analysis or JSON encoding/decoding.
 */
function make_https_request($method, $url, $headers, $payload) {

    // Initialize cURL session.
    $handle = curl_init();

    // Specify the HTTP method and target URL.
    curl_setopt($handle, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($handle, CURLOPT_URL, $url);

    // Set request headers.
    if ($headers) {
        $array = [];
        foreach ($headers as $name => $value) {
            array_push($array, $name . ': ' . $value);
        }
        curl_setopt($handle, CURLOPT_HTTPHEADER, $array);
    }

    // Set request payload.
    if ($payload)
        curl_setopt($handle, CURLOPT_POSTFIELDS, $payload);

    // Make sure the result will include response headers as well as payload.
    curl_setopt($handle, CURLOPT_HEADER, true);
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);

    // Send the HTTPS request and obtain the response.
    $data = curl_exec($handle);

    // End the cURL session.
    curl_close($handle);

    // Initialize a response object.
    $response = new stdClass();

    // Parse the first line of the response to get the status code.
    $tokens = explode("\r\n", $data, 2);
    $line = $tokens[0];
    $data = $tokens[1];
    if (substr($line, 0, 5) !== 'HTTP/')
        throw new Exception('Invalid HTTP response: ' . json_encode($line));
    $response->status = intval(explode(' ', $line, 3)[1]);

    // Parse response headers, line by line.
    $response->headers = [];
    while (true) {
        $tokens = explode("\r\n", $data, 2);
        $line = $tokens[0];
        $data = $tokens[1];
        if (strlen($line) == 0)
            break;  // end of headers
        $tokens = explode(':', $line, 2);
        $header_field = strtolower(trim($tokens[0]));
        $header_value = trim($tokens[1]);
        if (array_key_exists($header_field, $response->headers))
            $response->headers[$header_field] .= ', ' . $header_value;
        else
            $response->headers[$header_field] = $header_value;
    }

    // The rest of the data is the response payload.
    $response->payload = $data;

    // return the response object.
    return $response;
}


/*
 *  Throw an exception with the appropriate message after a wrong/unexpected
 *  response was received from the VATify.eu REST API.
 */
function handle_bad_response($context, $response) {

    try {
        $msg = json_decode($response->payload)->errors[0]->detail;
    } catch (Exception $e) {
        $msg = 'API responded with wrong status code: ' . $response['status'];
    }

    throw new Exception($context . ': ' . $msg);
}


/*
 *  Authenticate to the VATify.eu REST API by exchanging a (long-term)
 *  client ID and access key for a (time-limited) bearer token.  The
 *  return value is a string representing the newly issued bearer token.
 */                                                                             
function get_bearer_token($client_id, $access_key) {

    // Concatenate the client ID and access key using colon as a separator.
    $credentials = $client_id . ':' . $access_key;

    // Convert to a Base64-encoded string for HTTP "Basic" authentication.
    $credentials = base64_encode($credentials);

    // Prepare request headers.
    $headers = [
        'Accept' => 'application/json',
        'Content-Type' => 'application/json',
        'Authorization' => 'Basic ' . $credentials
      ];

    // Prepare request payload.
    $payload = json_encode([
        'grant_type' => 'client_credentials'
      ]);

    // Make the API call and obtain the response.
    $response = make_https_request('POST',
                                   'https://api.vatify.eu/v1/oauth2/token',
                                   $headers,
                                   $payload);

    // Check the response status.
    if ($response->status !== 200)
        handle_bad_response('get_bearer_token()', $response);

    // Return the bearer token.
    return json_decode($response->payload)->access_token;
}


/*
 *  Run a VATify.eu real-time query for company information.  The return
 *  value is a URL address of the API endpoint to poll for query results.
 */
function run_query($bearer_token, $country_id, $company_id) {

    // Prepare request headers.
    $headers = [
        'Accept' => 'application/json',
        'Content-Type' => 'application/json',
        'Authorization' => 'Bearer ' . $bearer_token
      ];

    // Prepare request payload.
    $payload = json_encode([
        'country' => $country_id,
        'identifier' => $company_id
      ]);

    // Make the API call and obtain the response.
    $response = make_https_request('POST',
                                   'https://api.vatify.eu/v1/query',
                                   $headers,
                                   $payload);

    // Check the response status.
    if ($response->status !== 202)
        handle_bad_response('run_query()', $response);

    // Return the bearer token.
    return $response->headers['location'];
}


/*
 *  Check the status of a VATify.eu real-time query.  Return the query
 *  results (company data), if already available.
 */
function get_query_results($bearer_token, $polling_url) {

    // Prepare request headers.
    $headers = [
        'Accept' => 'application/json',
        'Authorization' => 'Bearer ' . $bearer_token
      ];

    // Make the API call and obtain the response.
    $response = make_https_request('GET', $polling_url, $headers, null);

    // Check the response status.
    if ($response->status === 202)
        return null;  // result not ready yet
    if ($response->status !== 200)
        handle_bad_response('get_query_results()', $response);

    // Return the bearer token.
    return json_decode($response->payload)->result->items;
}


/*
 *  Run the function main() which can be found at the top of this file.
 */
main();

?>