antalaron/vat-number-validator
PHP VAT number validation library built on Symfony Validator. Validate EU VAT formats with easy constraint usage, get violation messages, and optionally plug in custom VAT rules via an extraVat callback. Installable via Composer; MIT licensed.
Installation:
composer require antalaron/vat-number-validator
No additional configuration is required beyond this.
First Use Case: Validate a VAT number in a Laravel controller or form request:
use Antalaron\Component\VatNumberValidator\VatNumber;
use Illuminate\Support\Facades\Validator;
$validator = Validator::make(['vat' => 'ATU37675002'], [
'vat' => ['required', new VatNumber()]
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
Where to Look First:
tests/ directory, showcasing edge cases and valid/invalid VAT examples.src/VatNumber.php for understanding the validation logic and extension points.Form Request Validation:
Extend Laravel's FormRequest to validate VAT numbers during user input:
use Antalaron\Component\VatNumberValidator\VatNumber;
use Illuminate\Foundation\Http\FormRequest;
class StoreCustomerRequest extends FormRequest
{
public function rules()
{
return [
'vat_number' => ['required', 'string', new VatNumber()],
];
}
}
API Request Validation:
Validate VAT numbers in API payloads using Laravel's Validator facade:
use Antalaron\Component\VatNumberValidator\VatNumber;
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'vat_number' => ['required', new VatNumber()],
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
Custom Validation Rules: Create reusable validation rules for VAT numbers:
use Antalaron\Component\VatNumberValidator\VatNumber;
use Illuminate\Validation\Rule;
class VatNumberRule extends Rule
{
public function validate($attribute, $value, $fail)
{
$validator = \Symfony\Component\Validator\Validation::createValidator();
$violations = $validator->validate($value, new VatNumber());
if (!empty($violations)) {
$fail($violations->first()->getMessage());
}
}
}
Use it in your validation rules:
'vat_number' => ['required', new \App\Rules\VatNumberRule],
Custom VAT Logic:
Extend the validator with additional rules using the extraVat option:
$validator = Validator::make(['vat' => '11'], [
'vat' => [new VatNumber([
'extraVat' => function ($number) {
return preg_match('/^(\d{2})$/', $number);
}
])],
]);
User Onboarding: Validate VAT numbers during customer registration to ensure compliance before account creation.
Invoice Processing: Validate VAT numbers in invoicing systems to ensure accurate tax calculations and compliance with EU directives.
B2B Transactions: Validate VAT numbers for business-to-business transactions to avoid penalties and ensure smooth cross-border operations.
Data Migration: Validate VAT numbers in existing databases during data migration to ensure data integrity.
Laravel Service Providers: Bind the validator to the Laravel container for easier dependency injection:
use Antalaron\Component\VatNumberValidator\VatNumber;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(VatNumber::class, function () {
return new VatNumber();
});
}
}
Localization: Customize error messages for different locales:
$validator = Validator::make(['vat' => 'INVALID'], [
'vat' => [new VatNumber()],
], [
'vat.required' => 'The VAT number field is required.',
'vat.vat_number' => 'The provided VAT number is invalid.',
]);
Testing: Write unit tests to ensure VAT validation works as expected:
use Antalaron\Component\VatNumberValidator\VatNumber;
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Validator\ValidatorInterface;
public function testValidVatNumber()
{
$validator = Validation::createValidator();
$violations = $validator->validate('ATU37675002', new VatNumber());
$this->assertEmpty($violations);
}
public function testInvalidVatNumber()
{
$validator = Validation::createValidator();
$violations = $validator->validate('INVALID', new VatNumber());
$this->assertNotEmpty($violations);
}
Logging: Log validation failures for auditing and debugging:
$validator = Validator::make(['vat' => 'INVALID'], [
'vat' => [new VatNumber()],
]);
if ($validator->fails()) {
\Log::error('VAT validation failed', [
'errors' => $validator->errors()->toArray(),
'input' => $request->all(),
]);
}
Symfony Version Compatibility:
False Positives/Negatives:
Performance:
Custom Logic Maintenance:
extraVat logic requires PHP knowledge and may need updates if business rules change.Error Messages:
Validation Failures:
src/VatNumber.php).dd($violations) to inspect the validation errors and identify the specific rule that failed.Custom Rules:
extraVat logic fails, ensure the callback returns true for valid VAT numbers and false for invalid ones.extraVat callback to verify its behavior.Symfony Dependency Issues:
composer why-not symfony/validator:^5.0 to check for version conflicts.ExtraVat Option:
extraVat option allows adding custom validation logic but must return a boolean value. Ensure your callback adheres to this requirement.'extraVat' => function ($number) {
return 'invalid'; // Wrong: must return boolean
}
Country-Specific Rules:
Custom Validators:
VatNumber class to add support for non-EU VAT formats or business-specific rules.use Antalaron\Component\VatNumberValidator\VatNumber as BaseVatNumber;
class CustomVatNumber extends BaseVatNumber
{
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefaults([
'extraVat' => function ($number) {
// Add custom logic here
return true;
},
]);
}
}
Integration with Laravel Rules:
use Antalaron\Component\VatNumberValidator\VatNumber;
use
How can I help you explore Laravel packages today?