vldmir / tin
Enhanced Taxpayer Identification Number validator with input masks (fork of loophp/tin)
Fund package maintenance!
drupol
Requires
- php: >= 8.1
Requires (Dev)
- ext-pcov: *
- drupol/php-conventions: ^6
- friends-of-phpspec/phpspec-code-coverage: ^6
- infection/infection: ^0.27
- infection/phpspec-adapter: ^0.2.0
- phpspec/phpspec: ^7
- phpstan/phpstan-strict-rules: ^1.0.0
- dev-master
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- 1.1.1
- 1.1.0
- 1.0.3
- 1.0.2
- 1.0.1
- v1.0.0
- dev-main
- dev-coderabbitai/docstrings/20bTtA
- dev-feature/AddMaskAndTinName
- dev-renovate/cachix-install-nix-action-31.x
- dev-renovate/major-phpstan-packages
- dev-renovate/actions-stale-9.x
- dev-renovate/infection-infection-0.x
- dev-fawno/master
- dev-psalm-fix-tin
This package is auto-updated.
Last update: 2025-06-24 07:49:16 UTC
README
Enhanced Taxpayer Identification Number (TIN) Validator
Description
An enhanced library to validate TIN numbers for individuals with advanced features including input masks, TIN type identification, and comprehensive Docker support. This is a fork of the original loophp/tin library with significant enhancements.
New Features in v2.0.0:
- 🎯 Input Mask Support - Get format masks for TIN input fields
- 📝 Placeholder Generation - Generate example values for input fields
- 🔧 Input Formatting - Format user input according to TIN mask
- 🏷️ TIN Type Identification - Identify specific TIN types (DNI, NIE, CIF, etc.)
- 📊 TIN Types API - Get available TIN types for each country
- 🐳 Docker Support - Complete development environment with PHP 8.3
- 📚 Enhanced Documentation - Comprehensive examples and usage guides
Supported countries:
- Austria (AT)
- Belgium (BE)
- Bulgaria (BG)
- Croatia (HR)
- Cyprus (CY)
- Czech Republic (CZ)
- Denmark (DK)
- Estonia (EE)
- Finland (FI)
- France (FR)
- Germany (DE)
- Greece (GR) - only size
- Hungary (HU)
- Ireland (IE)
- Italy (IT)
- Latvia (LV) - no check digit
- Lithuania (LT)
- Luxembourg (LU)
- Malta (MT) - no check digit
- Netherlands (NL)
- Poland (PL)
- Portugal (PT)
- Romania (RO) - no check digit
- Slovakia (SK)
- Slovenia (SI)
- Spain (ES)
- Sweden (SE)
- United Kingdom (UK) - only structure
If your country is not there, feel free to open an issue with your country code, and a link to the specification. Ideally, you can provide a pull request with the algorithm and the tests.
Requirements
- PHP >= 8.1
Quick Start
Installation
composer require vldmir/tin
Basic Validation
To simply check the validity of a TIN number:
<?php require __DIR__ . '/vendor/autoload.php'; use loophp\Tin\TIN; $bool = TIN::fromSlug('be71102512345')->isValid();
If you want to get the reason why a number is invalid, you can use:
<?php require __DIR__ . '/vendor/autoload.php'; use loophp\Tin\TIN; use loophp\Tin\Exception\TINException; try { TIN::fromSlug('be71102512345')->check(); } catch (TINException $e) { echo "Validation Error: " . $e->getMessage(); }
Advanced Features
Input Masks and Formatting
The library provides comprehensive input mask and formatting capabilities:
<?php use loophp\Tin\TIN; // Get the input mask for a country $tin = TIN::fromSlug('be71102512345'); $mask = $tin->getInputMask(); // Returns: "99.99.99-999.99" // Get a placeholder example $placeholder = $tin->getPlaceholder(); // Returns: "85.07.30-033.61" // Format raw input according to the country's mask $formatted = $tin->formatInput('71102512345'); // Returns: "71.10.25-123.45" // Get mask information without creating a TIN instance $maskInfo = TIN::getMaskForCountry('BE'); // Returns: [ // 'mask' => '99.99.99-999.99', // 'placeholder' => '85.07.30-033.61', // 'country' => 'BE' // ]
TIN Type Identification
Different countries may have multiple types of TINs. The library can identify and categorize them:
<?php use loophp\Tin\TIN; // Get all TIN types for a country $types = TIN::getTinTypesForCountry('ES'); // Returns: // [ // 1 => ['code' => 'DNI', 'name' => 'Documento Nacional de Identidad', 'description' => 'Spanish Natural Persons ID'], // 2 => ['code' => 'NIE', 'name' => 'Número de Identidad de Extranjero', 'description' => 'Foreigners Identification Number'], // 3 => ['code' => 'CIF', 'name' => 'Código de Identificación Fiscal', 'description' => 'Tax Identification Code for Legal Entities'] // ] // Identify the type of a specific TIN $tin = TIN::fromSlug('es12345678Z'); $type = $tin->identifyTinType(); // Returns: ['code' => 'DNI', 'name' => 'Documento Nacional de Identidad', 'description' => 'Spanish Natural Persons ID'] // Get TIN types for the current TIN's country $allTypes = $tin->getTinTypes();
Complete Example
<?php require __DIR__ . '/vendor/autoload.php'; use loophp\Tin\TIN; use loophp\Tin\Exception\TINException; // Test different countries $testCases = [ ['country' => 'BE', 'tin' => '71102512345', 'description' => 'Belgian TIN'], ['country' => 'ES', 'tin' => '12345678Z', 'description' => 'Spanish DNI'], ['country' => 'DE', 'tin' => '12345678901', 'description' => 'German TIN'], ['country' => 'UK', 'tin' => 'AB123456C', 'description' => 'UK TIN'], ]; foreach ($testCases as $test) { echo "Testing {$test['description']} ({$test['country']}): {$test['tin']}\n"; try { $tin = TIN::fromSlug($test['country'] . $test['tin']); // Basic validation $isValid = $tin->isValid(); echo "Valid: " . ($isValid ? 'YES' : 'NO') . "\n"; // Get input mask and placeholder $mask = $tin->getInputMask(); $placeholder = $tin->getPlaceholder(); echo "Input Mask: $mask\n"; echo "Placeholder: $placeholder\n"; // Format input $formatted = $tin->formatInput($test['tin']); echo "Formatted: $formatted\n"; // Identify TIN type $tinType = $tin->identifyTinType(); if ($tinType) { echo "TIN Type: {$tinType['code']} - {$tinType['name']}\n"; echo "Description: {$tinType['description']}\n"; } echo "Validation: PASSED\n"; } catch (TINException $e) { echo "Validation Error: " . $e->getMessage() . "\n"; } echo "\n"; }
Examples by Country
Country | Mask | Placeholder | TIN Types |
---|---|---|---|
Belgium (BE) | 99.99.99-999.99 |
85.07.30-033.61 |
TIN |
Spain (ES) | 99999999A |
12345678Z |
DNI, NIE, CIF |
Germany (DE) | 999 999 999 99 |
123 456 789 01 |
IdNr, StNr |
United Kingdom (UK) | AA999999A |
AB123456C |
UTR, NINO |
France (FR) | 9 99 99 99 999 999 |
1 23 45 67 890 123 |
TIN |
Italy (IT) | AAAAAANNANNANAAA |
RSSMRA85T10A562S |
TIN |
Mask Format:
9
- Digit (0-9)A
- Uppercase lettera
- Lowercase letter- Other characters (
.
,-
, space) - Separators
Docker Development Environment
The library includes a complete Docker setup for easy development and testing:
Quick Start with Docker
# Start containers and install dependencies make up # Run tests make phpspec # Run the test script make tin-test # Open shell in container make shell
Available Commands
make up # Start containers and install dependencies make down # Stop containers make shell # Open bash shell in PHP container make composer # Run composer commands make test # Run all tests (PHPSpec + GrumPHP) make phpspec # Run PHPSpec tests make grumphp # Run GrumPHP checks make phpstan # Run PHPStan analysis make psalm # Run Psalm analysis make infection # Run mutation testing make tin-test # Run the TIN test script
Manual Docker Commands
# Start containers docker-compose up -d # Install dependencies docker-compose run --rm tin-composer composer install # Run tests docker exec tin-php vendor/bin/phpspec run -vvv --stop-on-failure # Run the TIN test script docker exec tin-php php test-tin.php # Open shell docker exec -it tin-php bash
For detailed Docker documentation, see DOCKER.md.
Strict Mode
If you want to use a stricter method (without normalizing the TIN number, that
is, using the raw TIN number), use the strict
parameter in the check
or
isValid
functions as shown below. By default, it is set to false
.
TIN::fromSlug('be7110.2512345')->check(); // Not strict TIN::fromSlug('be7110.2512345')->check(strict: false); // Not strict TIN::fromSlug('be7110.2512345')->check(true); // Strict TIN::fromSlug('be7110.2512345')->check(strict: true); // Strict
Code Quality, Tests and Benchmarks
Every time changes are introduced into the library, Github run the tests and the benchmarks.
The library has tests written with PHPSpec. Feel free
to check them out in the spec
directory. Run composer phpspec
to trigger the
tests.
Before each commit some inspections are executed with
GrumPHP, run ./vendor/bin/grumphp run
to
check manually.
PHPInfection is used to ensure that
your code is properly tested, run composer infection
to test your code.
Running Tests
# Using Composer composer phpspec # Using Docker make phpspec # With code coverage docker exec tin-php vendor/bin/phpspec run -vvv --stop-on-failure
Links
European Commission TIN service
TIN Algorithms - Public - Functional Specification
Taxpayer Identification Number
Authors
- Volodymyr Romantsov - Enhanced version with input masks and Docker support
- Thomas Portelange - Original library
- Pol Dellaiera - Original library
Contributing
We warmly welcome your contributions by submitting pull requests. Our team is highly responsive and will gladly guide you through the entire process, from the initial submission to the final resolution.
Development Setup
- Fork the repository
- Clone your fork
- Set up the Docker environment:
make up
- Make your changes
- Run tests:
make phpspec
- Submit a pull request
License
This project is licensed under the MIT License - see the LICENSE file for details.