Installation
composer require besmartand-pro/vies-bundle
Add to config/bundles.php:
return [
// ...
BesmartandPro\ViesBundle\ViesBundle::class => ['all' => true],
];
Configuration Publish the default config (optional):
php bin/console besmartand-pro:vies:install
Or manually configure in config/packages/vies.yaml:
vies:
client:
timeout: 30
cache: true
cache_ttl: 3600
First Use Case Validate a VAT number in a Symfony form:
use Symfony\Component\Validator\Constraints as Assert;
$builder->add('vatNumber', TextType::class, [
'constraints' => [
new Assert\ViesVatNumber(['countryCode' => 'FR'])
]
]);
Form Validation
Use the ViesVatNumber constraint with country-specific validation:
$builder->add('vat', TextType::class, [
'constraints' => [
new Assert\ViesVatNumber(['countryCode' => 'DE'])
]
]);
Manual Validation Validate outside forms via the validator service:
$validator = $this->get('validator');
$vatNumber = 'FR123456789';
$errors = $validator->validate($vatNumber, [
new Assert\ViesVatNumber(['countryCode' => 'FR'])
]);
API Integration Fetch VAT details programmatically:
$client = $this->get('vies.client');
$response = $client->validate('FR', '123456789');
Caching Responses
Enable caching in config (vies.cache: true) to avoid repeated API calls for the same VAT number.
ViesClientInterface).ViesException for rate limits or service unavailability.ViesClientInterface in unit tests:
$this->mockBuilder()
->disableOriginalConstructor()
->getMock();
Country-Specific Rules
US, CA) require additional validation logic. Check the VIES API docs for edge cases.GB (not UK).API Downtime
try {
$response = $client->validate('FR', '123456789');
} catch (ViesException $e) {
// Fallback logic
}
Configuration Overrides
vies.yaml. Ensure no duplicate keys:
# Avoid this:
vies:
client:
timeout: 30 # Overrides default
timeout: 60 # Duplicate (last wins)
Constraint Validation Order
NotBlank + ViesVatNumber), ensure ViesVatNumber runs last to avoid redundant API calls.Enable Debug Mode
Set vies.debug: true in config to log API responses:
vies:
debug: true
Common Errors
| Error | Cause | Fix |
|---|---|---|
Invalid country code |
Unsupported country (e.g., US) |
Use countryCode: null for global validation. |
VAT number format invalid |
Malformed input (e.g., FR123) |
Add Regex constraint first. |
VIES API timeout |
Network issues | Increase timeout or implement retry logic. |
Custom Validators Extend the base validator to add business logic:
class CustomVatValidator extends ViesVatNumberValidator {
public function validate($vatNumber, Constraint $constraint) {
$errors = parent::validate($vatNumber, $constraint);
if ($errors->count() === 0 && $vatNumber === 'EXEMPT123') {
$errors->add($this->context->buildViolation('Exempt VAT number')->atPath('vatNumber'));
}
return $errors;
}
}
Event Listeners
Subscribe to vies.response events to modify responses:
$eventDispatcher->addListener(ViesEvents::RESPONSE, function (ViesResponseEvent $event) {
$event->setData(['custom_field' => 'value']);
});
Override Services
Replace the default ViesClient with a custom implementation:
# config/services.yaml
services:
App\Service\CustomViesClient:
arguments:
$httpClient: '@http_client'
tags: ['vies.client']
How can I help you explore Laravel packages today?