omisai / vies-rest
PHP package to check Vat number through REST API of VIES
Installs: 9
Dependents: 1
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/omisai/vies-rest
Requires
- php: ^8.1
- ext-curl: *
- ext-json: *
- ext-mbstring: *
- guzzlehttp/guzzle: ^7.3
- guzzlehttp/psr7: ^1.7 || ^2.0
Requires (Dev)
- laravel/pint: ^1.27
- pestphp/pest: ^4.3
This package is auto-updated.
Last update: 2026-02-11 14:24:02 UTC
README
A lightweight, type-safe PHP package for validating EU VAT numbers via the European Commission's VIES (VAT Information Exchange System) REST service.
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
- ext-curl
- ext-json
- ext-mbstring
Installation
Install the package via Composer:
composer require omisai/vies-rest
Quick Start
Basic VAT Validation
use Omisai\ViesRest\ViesClient; $client = new ViesClient(); $response = $client->checkVat('DE', '123456789'); if ($response->valid) { echo "✅ Valid VAT: {$response->countryCode}{$response->vatNumber}\n"; echo "Company: {$response->name}\n"; echo "Address: {$response->address}\n"; } else { echo "❌ Invalid VAT number\n"; }
Using the Test Service
use Omisai\ViesRest\ViesClient; use Omisai\ViesRest\ViesConfig; $client = new ViesClient(ViesConfig::test()); $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
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 = new ViesClient(); 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 = new ViesClient(); 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 = new ViesClient(); $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
If you discover any security-related issues, please email security@omisai.com instead of using the issue tracker.
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!