omisai/laravel-vies-rest

Laravel adapter for the VIES REST API package
1,751 1
Install
composer require omisai/laravel-vies-rest
Latest Version:v1.3.0
PHP:^8.1
Laravel:10 – 13
License:MIT
Last Updated:Sep 5, 2026
Links: GitHub  ·  Packagist
Maintainer: bornemisza

Laravel VIES REST

Latest Version on Packagist License Test PHP Version Require

A Laravel adapter for the VIES REST API package, utilizing Laravel's HTTP client.

Features

  • Type-safe: PHP 8.1+ type declarations and modern enum support
  • Clean architecture: DTOs, validation, and HTTP adapters
  • Production + test modes: Switch services via ViesConfig
  • Error handling: Structured exceptions for validation and REST errors
  • Approximate matching: Trader detail matching support
  • All EU countries: EU member states plus Northern Ireland
  • Tested: Pest-based test suite

Requirements

  • PHP 8.1 or higher
  • omisai/vies-rest (base package)
  • illuminate/http v10 or higher (Laravel HTTP client)

Installation

Install the package via Composer:

composer require omisai/laravel-vies-rest

Quick Start

This package requires the base omisai/vies-rest package.

The Omisai\LaravelViesRest\ViesRestServiceProvider service provider automatically registers the Laravel HTTP client adapter. The Omisai\ViesRest\ViesClient will use Laravel's HTTP client instead of direct Guzzle.

Via Dependency Injection

...
use Omisai\ViesRest\ViesClient;
use Omisai\ViesRest\Enum\EuropeanUnionCountry;

class ExampleController extends Controller
{
    public function __construct(
        private ViesClient $viesClient,
    ) {}

    public function checkVat(Request $request)
    {
        $countryCode = $request->input('country_code');
        $vatNumber = $request->input('vat_number');

        $isValidCountryCode = EuropeanUnionCountry::validateCountryCode($countryCode);
        if (!$isValidCountryCode) {
            return response()->json(['error' => 'Invalid country code'], 400);
        }

        $response = $this->viesClient->checkVat($countryCode, $vatNumber);

        return response()->json([
            'valid' => $response->valid,
            'name' => $response->name,
            'address' => $response->address,
        ]);
    }
}

Via Service Container Resolution

<?php
// In a controller, service, or route closure
$client = app(ViesClient::class);
$response = $client->checkVat('DE', '123456789');

Using the Test Service

use Omisai\ViesRest\ViesClient;
use Omisai\ViesRest\ViesConfig;

$config = ViesConfig::test(); /
$factory = app(HttpClientFactoryInterface::class);
$client = new ViesClient($config, $factory);

$response = $client->checkVat('DE', '100');

var_dump($response->valid); // true for test numbers

Configuration

Environment Configuration

use Omisai\ViesRest\ViesConfig;

$production = ViesConfig::production();
$test = ViesConfig::test();

$custom = ViesConfig::production(baseUrl: 'https://custom-vies.example.com');

HTTP Client Options

use Omisai\ViesRest\ViesClient;
use Omisai\ViesRest\ViesConfig;

$options = [
    'timeout' => 30,
    'connect_timeout' => 10,
    'headers' => [
        'User-Agent' => 'MyApp/1.0',
    ],
];

$client = new ViesClient(ViesConfig::production(options: $options));

API Reference

ViesClient

checkVat(string $countryCode, string $vatNumber): CheckVatResponse

Validates a VAT number and returns basic information.

checkVatApprox(CheckVatRequest $request): CheckVatResponse

Performs approximate validation with trader details.

checkStatus(): StatusInformationResponse

Returns availability info for member states.

Data Transfer Objects (DTOs)

CheckVatRequest
use Omisai\ViesRest\DTO\CheckVatRequest;

$request = new CheckVatRequest(
    countryCode: 'NL',
    vatNumber: '123456789B01',
    traderName: 'Example B.V.',
    traderStreet: 'Main Street 123',
    traderPostalCode: '1234AB',
    traderCity: 'Amsterdam',
    requesterMemberStateCode: 'DE',
    requesterNumber: '123456789',
);
CheckVatResponse
# Omisai\ViesRest\DTO\CheckVatResponse;

echo $response->countryCode;
echo $response->vatNumber;
echo $response->requestDate->format('Y-m-d');
echo $response->valid ? 'Yes' : 'No';

Supported Countries

use Omisai\ViesRest\Enum\EuropeanUnionCountry;

$isValid = EuropeanUnionCountry::isEuropeanUnionCountryCode('DE'); // true
$isValid = EuropeanUnionCountry::isEuropeanUnionCountryCode('US'); // false

Error Handling

Validation Errors

use Omisai\ViesRest\Exceptions\ViesValidationException;
use Omisai\ViesRest\ViesClient;

$client = app(ViesClient::class);

try {
    $client->checkVat('INVALID', '123');
} catch (ViesValidationException $e) {
    echo "Validation error: {$e->getMessage()}\n";
}

REST API Errors

use Omisai\ViesRest\Exceptions\ViesApiException;
use Omisai\ViesRest\ViesClient;

$client = app(ViesClient::class);

try {
    $client->checkVat('DE', '123456789');
} catch (ViesApiException $e) {
    echo "API error: {$e->getMessage()}\n";
    echo "Status code: {$e->getStatusCode()}\n";
}

Advanced Usage

Custom HTTP Client Factory

use Omisai\ViesRest\ViesClient;
use Omisai\ViesRest\Http\HttpClientFactoryInterface;

class CustomHttpClientFactory implements HttpClientFactoryInterface
{
    public function create(string $baseUrl, array $options = [])
    {
        // Return a custom adapter implementing HttpClientInterface
    }
}

$client = new ViesClient(clientFactory: new CustomHttpClientFactory());

Custom Validation

use Omisai\ViesRest\ViesClient;
use Omisai\ViesRest\Validation\VatNumberValidator;

class CustomVatNumberValidator extends VatNumberValidator
{
    // Implement custom validation logic
}

$client = new ViesClient(validator: new CustomVatNumberValidator());

Batch Processing

use Omisai\ViesRest\ViesClient;

$client = app(ViesClient::class);
$vatNumbers = [
    ['DE', '123456789'],
    ['NL', '123456789B01'],
    ['FR', '12345678901'],
];

$results = [];
foreach ($vatNumbers as [$country, $vat]) {
    try {
        $response = $client->checkVat($country, $vat);
        $results[] = [
            'country' => $response->countryCode,
            'vat' => $response->vatNumber,
            'valid' => $response->valid,
            'name' => $response->name,
        ];
    } catch (Exception $e) {
        $results[] = [
            'country' => $country,
            'vat' => $vat,
            'error' => $e->getMessage(),
        ];
    }
}

print_r($results);

Testing

Run the test suite using Pest:

composer test

Performance Considerations

  • The VIES service has rate limits - avoid excessive requests
  • REST calls are synchronous and may take 1-5 seconds
  • Consider caching valid VAT numbers to reduce API calls
  • Use the test service for development to avoid affecting production quotas

Limitations

  • Requires internet connection to VIES service
  • Service may be unavailable during maintenance windows
  • Rate limiting applies to prevent abuse
  • Some countries may have additional validation rules

Contributing

Please see CONTRIBUTING.md for details on how to contribute to this project.

Security

Please see SECURITY.md for details on reporting security vulnerabilities.

License

This package is open-sourced software licensed under the MIT license.

Sponsoring

If you find this package useful, please consider sponsoring the development: Sponsoring on GitHub

Your support helps us maintain and improve this open-source project!

Official VIES Documentation

Related Packages

leroy-merlin-br/exacttarget-client

Easy way to interact with ExactTarget REST API in Laravel

11,522 3
youxianbo/oceanengine-sdk

根据项目需求完成的接口,非所有接口都有相应的代码

27 0
jlevers/selling-partner-api

PHP client for Amazon's Selling Partner API

5,775,688 438
pdfgeneratorapi/php-client

Introduction PDF Generator API allows you easily generate transactional PDF docu...

238,371 5

Version History

Version Released PHP Laravel License
v1.3.0 ^8.1 ^10.0|^11.0|^12.0|^13.0 MIT
v1.2.0 ^8.1 ^10.0 || ^11.0 || ^12.0 MIT
v1.1.0 ^8.1 ^10.0 || ^11.0 || ^12.0 MIT
v1.0.0 ^8.1 >=10.0 MIT