Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nif Validator Laravel Package

ulabox/nif-validator

A Laravel package for validating Spanish NIF, NIE and CIF tax identification numbers. It offers validation rules and simple helpers to verify document numbers in forms, requests and Eloquent models, making Spanish tax ID checks clean and reliable.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install via Composer:

    composer require ulabox/nif-validator
    
  2. No manual registration needed on Laravel 5.5+ — the package uses package auto-discovery to register its service provider and validation extensions. On older Laravel versions, add the provider to config/app.php.

  3. Look first at the README for the exact rule names and facade signature, since this is a small (25-star) package and the surface API is minimal — typically a set of Laravel validation rules such as nif, cif, and nie, plus a small validator class/facade you can call directly.

  4. First use case — validate a Spanish tax ID on a signup or billing form:

    $request->validate([
        'tax_id' => ['required', 'string', 'nif'],   // NIF/NIE for individuals
        // or
        'tax_id' => ['required', 'string', 'cif'],   // CIF for companies
    ]);
    

If you only need programmatic checks (outside Validator), the facade/helper typically exposes something like NifValidator::isValidNif($value) — confirm the method names against the README before wiring it into services.

Implementation Patterns

Form Requests (recommended). Keep the rule in a FormRequest so the same tax-ID contract is reused across registration, checkout, and profile-update flows:

class StoreBillingRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'tax_id' => [
                'required', 'string', 'max:20', 'nif',
                Rule::unique('customers', 'tax_id')->ignore($this->user()),
            ],
        ];
    }
}

Choose the rule by customer type. Model this explicitly — a company should be validated as a cif, an individual as a nif/nie. A clean pattern is a single tax_id input plus a customer_type enum, then select rules conditionally:

$rule = match ($this->input('customer_type')) {
    'company'    => 'cif',
    default      => 'nif',   // NIF or NIE depending on package support
};

return ['tax_id' => ['required', 'string', $rule]];

If the package exposes a combined "any Spanish ID" rule, prefer that instead of match — it removes an entire class of bugs where a valid NIE is rejected because the user picked the wrong type.

Normalize before validating. Users paste tax IDs with spaces, dots, or lowercase. Put normalization in prepareForValidation() so validation, storage, and later lookups all see the same canonical string:

protected function prepareForValidation(): void
{
    $this->merge([
        'tax_id' => strtoupper(preg_replace('/[\s\.\-]/', '', (string) $this->tax_id)),
    ]);
}

Reuse in a domain service. For imports, seeders, and background jobs, call the underlying validator directly rather than constructing Validator instances:

if (! NifValidator::isValidNif($row['tax_id'])) {
    $this->warn("Skipping invalid NIF: {$row['tax_id']}");
    continue;
}

Test fixtures. Build a small TaxIdFactory of known-good NIFs/CIFs/NIEs (one per entity subtype: A/B/C societies, X/Y/Z NIEs) so tests don't rely on random strings — the checksum math means random data almost always fails.

Gotchas and Tips

  • Whitespace and case are not forgiven. These validators are strict string checks; "12345678-Z" and "12345678z" fail where "12345678Z" passes. Always trim and uppercase before hitting the rule (see prepareForValidation above).
  • NIF ≠ CIF ≠ NIE in practice. A CIF (company) will fail a NIF rule and vice versa. Do not point nif at a company field "because it works for most users" — model the entity type and pick the rule deliberately.
  • NIE checksums use a letter remap. NIE prefixes X, Y, Z are translated to 0, 1, 2 internally before the mod-23 check; if you write your own front-end mirror, replicate this or your JS will drift from the server.
  • CIF control character can be a digit or a letter. The final character depends on the entity-type letter, so simple is_numeric checks are wrong. Trust the package rather than reimplementing this.
  • Version coupling. Check composer.json constraints against your Laravel version; a 2023 release will target Laravel 9/10. If you're on 11+, verify auto-discovery and Illuminate\Contracts\Validation\Rule compatibility before rollback, and check whether the rule uses the newer ValidationRule interface.
  • Debugging tip. When a rule "silently" fails, test it in isolation: php artisan tinker → Validator::make(['id'=>'12345678Z'], ['id'=>'nif'])->errors(). This separates a bad value from a wiring/misconfiguration problem.
  • Message customization / i18n. If the package ships translations, publish them (usually php artisan vendor:publish) to customize the error message users see; otherwise override in resources/lang/*/validation.php under the rule key.
  • Extension point. Wrap the raw rule in your own Rule object (SpanishTaxId) when you want to bundle normalization + entity-type logic + uniqueness in one place, keeping controllers and requests clean and making the behavior unit-testable.
  • Don't rely on a 25-star package for the algorithm forever. The validation is ~30 lines of checksum math; if maintenance stalls, vendor a copy into app/Support/ so you're not blocked on a Laravel upgrade. MIT license makes this safe.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums