sorciulus/check-partita-iva
Laravel package to validate Italian VAT numbers (Partita IVA). Provides quick checks (format and checksum) to detect invalid P.IVA values, useful for signup forms, invoicing, and customer data imports.
Installation Add the package via Composer:
composer require sorciulus/check-partita-iva
Require the autoloader in your project (Laravel handles this automatically via composer.json).
First Use Case Validate an Italian VAT number (Partita IVA) in a Laravel controller or form request:
use Sorciulus\CheckPartitaIva\PartitaIva;
$vatNumber = '12345678901'; // Example VAT number
$validator = new PartitaIva($vatNumber);
if ($validator->isValid()) {
// VAT is valid
} else {
// VAT is invalid or requires further checks
}
Where to Look First
src/PartitaIva.php for logic (e.g., Luhn algorithm checks, format validation).use Illuminate\Support\Facades\Validator;
$validator = Validator::make(['vat' => $vatNumber], [
'vat' => ['required', function ($attribute, $value, $fail) {
$validator = new \Sorciulus\CheckPartitaIva\PartitaIva($value);
if (!$validator->isValid()) {
$fail('The :attribute is invalid.');
}
}]
]);
Basic Validation Validate a VAT number in isolation:
$validator = new PartitaIva('01234567890');
if ($validator->isValid()) {
// Proceed
}
Batch Validation Validate multiple VAT numbers (e.g., in a CSV import):
$vatNumbers = ['12345678901', '09876543210', 'invalid'];
$results = array_map(function ($vat) {
return (new PartitaIva($vat))->isValid();
}, $vatNumbers);
Laravel Form Requests
Extend Laravel’s FormRequest for API/controller validation:
use Illuminate\Foundation\Http\FormRequest;
use Sorciulus\CheckPartitaIva\PartitaIva;
class StoreCustomerRequest extends FormRequest
{
public function rules()
{
return [
'vat_number' => 'required|vat_valid',
];
}
public function withValidator($validator)
{
$validator->after(function ($validator) {
$vat = $this->input('vat_number');
if (!$validator->passes(['vat_number' => 'required'])) {
return;
}
if (!(new PartitaIva($vat))->isValid()) {
$validator->errors()->add('vat_number', 'The VAT number is invalid.');
}
});
}
}
Add 'vat_valid' => 'Sorciulus\CheckPartitaIva\Rules\VatValid' to your AppServiceProvider if the package provides a rule.
API Responses Return structured validation feedback:
return response()->json([
'valid' => (new PartitaIva($request->vat))->isValid(),
'message' => (new PartitaIva($request->vat))->getMessage(),
]);
User Registration Validate VAT during customer onboarding:
$customer = new Customer();
$customer->vat_number = $request->vat;
if (!(new PartitaIva($request->vat))->isValid()) {
return back()->withErrors(['vat' => 'Invalid VAT number.']);
}
$customer->save();
Supplier Management Validate supplier VAT numbers in a B2B context:
$supplier = Supplier::find($id);
if (!(new PartitaIva($supplier->vat))->isValid()) {
$supplier->markAsInvalid();
$supplier->save();
}
Data Migration Cleanse existing VAT numbers in a database:
$customers = Customer::all();
foreach ($customers as $customer) {
$validator = new PartitaIva($customer->vat_number);
if (!$validator->isValid()) {
$customer->vat_number = null; // or default value
$customer->save();
}
}
Localization
Store validation messages in Laravel’s language files (resources/lang/it/validation.php):
'vat_valid' => 'Il numero di partita IVA :attribute non è valido.',
Caching Cache validation results for frequently checked VAT numbers:
$cacheKey = 'vat_'.$vatNumber;
if (Cache::has($cacheKey)) {
$isValid = Cache::get($cacheKey);
} else {
$isValid = (new PartitaIva($vatNumber))->isValid();
Cache::put($cacheKey, $isValid, now()->addHours(1));
}
Testing
Mock the PartitaIva class in PHPUnit:
$mock = $this->createMock(\Sorciulus\CheckPartitaIva\PartitaIva::class);
$mock->method('isValid')->willReturn(true);
$this->assertTrue($mock->isValid());
False Positives/Negatives
Format Sensitivity
12345678901). Leading zeros (e.g., 01234567890) are valid but may fail if stripped.$vat = str_pad(trim($request->vat), 11, '0', STR_PAD_LEFT);
Deprecated Package
No Built-in Rule
namespace App\Rules;
use Sorciulus\CheckPartitaIva\PartitaIva;
class VatValid implements \Illuminate\Contracts\Validation\Rule
{
public function passes($attribute, $value)
{
return (new PartitaIva($value))->isValid();
}
}
Then use it in rules:
'vat' => ['required', new \App\Rules\VatValid],
Edge Cases
IT12345678901) are not handled.if (str_starts_with($vat, 'IT')) {
$vat = substr($vat, 2); // Remove 'IT' prefix
}
Validation Messages The package provides limited feedback. Extend it:
$validator = new PartitaIva($vat);
if (!$validator->isValid()) {
$errors = [
'format' => !$validator->isCorrectFormat(),
'checksum' => !$validator->isCorrectChecksum(),
];
}
Logging Log invalid VAT attempts for auditing:
if (!(new PartitaIva($vat))->isValid()) {
\Log::warning("Invalid VAT submitted: {$vat}", ['ip' => $request->ip()]);
}
config/check-partita-iva.php exists.PartitaIva logic by extending the class:
class CustomPartitaIva extends \Sorciulus\CheckPartitaIva\PartitaIva
{
public function isValid()
{
// Custom logic
return parent::isValid() && $this->customCheck();
}
}
How can I help you explore Laravel packages today?