Search by

daycry / taxid

daycry

Tax identification number library for CodeIgniter 4 (validation, parsing, formatting and taxpayer resolution) covering ~90 jurisdictions, usable standalone too.

Package info

github.com/daycry/taxid

pkg:composer/daycry/taxid

Statistics

Installs: 168

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.3.0 2026-10-28 13:27 UTC

README

Donate

Tax ID Validation for CodeIgniter 4 and Standalone PHP

Tests Coverage Status

PHPStan Code Style CodeQL

Latest Stable Version Latest Unstable Version Total Downloads Monthly Downloads License

PHP Version Require PHPStan level 8

GitHub stars GitHub forks GitHub issues

A tax identification number library for CodeIgniter 4, with a framework-free core for standalone PHP applications.

Validate, parse and format identifiers across 94 jurisdictions and 149 schemes, including NIF, CIF, VAT, CPF, CNPJ, RFC, AHV/AVS, IDNO, IDNP, EMBG and EDB. 101 schemes support arithmetic checksums; each validation result reports what was actually checked.

composer require daycry/taxid

Features

Validation

Feature Description
Country Registry 94 jurisdictions and 149 identifier schemes, with entity types, formats and examples
Checksum Verification 101 schemes with national algorithms, including mod-11, mod-97, Luhn, Verhoeff, EAN-13 and ISO 7064
Validation Assurance checksumVerified distinguishes a checked checksum from accepted structure/ranges
Explicit Scheme Selection Require a specific type such as nif, ahv, idnp, embg or edb
Country Inference Detect recognized country/VAT prefixes, including Greece's EL and Northern Ireland's XI
Detailed Errors Twelve violation codes for input, country, structure, scheme, reserved values and checksum failures
National Rules Personal/company variants, reserved ranges and supported calendar/century checks

Parsing & Formatting

Feature Description
Normalization Uppercase and remove supported separators before checking a value
Structured Results Country, accepting scheme, entity type, compact value and available check characters
Print Formatting Country-specific masks, including Swiss AHV/AVS 756.1234.5678.97
Anonymized Formatting Mask all but the final two characters for display or logging
VAT Representation Return the international VAT form when the scheme and country define one

Integration & Resolution

Feature Description
CodeIgniter Service Auto-discovered service('taxid') and a publishable configuration
Helper Functions Validation, parsing, formatting and taxpayer lookup helpers
CLI Commands Validate, parse, resolve and inspect country coverage, with JSON output
Standalone Core Validation, parsing and formatting without CodeIgniter or runtime Composer packages
Optional VIES Lookup EU VAT registration checks for the EU-27 and Northern Ireland
Provider Chain & Cache Combine local database records, VIES and custom providers with optional caching
Extension Points Custom registry loaders, national validators and lookup providers

Validity and registration are separate outcomes. A successful validation confirms that the value passes the implemented rules. It does not confirm that a taxpayer exists. Some schemes check structure/ranges only, and some checksum schemes have exceptional formats. See Validation Assurance and Algorithm Sources & Limits.

Quick Start

Requirements

  • PHP 8.3 or higher; CI tests PHP 8.3, 8.4 and 8.5.
  • Composer and the SimpleXML PHP extension, declared by the package for VIES response parsing.
  • CodeIgniter 4.6 or higher when using the service, helpers, commands or framework providers.

1. Install via Composer

composer require daycry/taxid

2. Validate a Tax ID

use Daycry\TaxId\TaxId;

$taxid = new TaxId();

$result = $taxid->validate('12345678Z', 'ES', 'nif');

$result->isValid();          // true
$result->checksumVerified;   // true
$result->scheme;             // 'nif'

$invalid = $taxid->validate('12345678A', 'ES', 'nif');
$invalid->errorCode();        // 'check_digit_failed'

$taxid->isValid('ESB12345674');                   // true: country inferred
$taxid->isValid('756.1234.5678.97', 'CH', 'ahv'); // true: Swiss personal identifier
$taxid->isValid('1000000000018', 'MD', 'idno');   // true: Moldovan organization ID
$taxid->isValid('2000000000015', 'MD', 'idnp');   // true: Moldovan personal ID
$taxid->isValid('0101990410012', 'MK', 'embg');   // true: Macedonian personal ID
$taxid->isValid('4000000000013', 'MK', 'edb');    // true: Macedonian tax registration

Always pass the third argument when a field requires one identifier type. Without it, any matching scheme for the country may accept the value.

3. Parse & Format

use Daycry\TaxId\Enums\TaxIdFormat;

$parsed = $taxid->parse('111.444.777-35', 'BR');

$parsed->countryCode;                         // 'BR'
$parsed->scheme;                              // 'cpf'
$parsed->compact;                             // '11144477735'
$parsed->format();                            // '111.444.777-35'
$parsed->format(TaxIdFormat::Anonymized);       // '*********35'

$taxid->parse('B12345674', 'ES')->vatNumber(); // 'ESB12345674'

parse() throws InvalidTaxIdException for an invalid value. Use tryParse() for a nullable result. validate() returns the violations without throwing for invalid string input.

4. Use the CodeIgniter Service or Helper

$taxid = service('taxid');
$taxid->isValid('756.1234.5678.97', 'CH', 'ahv'); // true

helper('taxid');

taxid_is_valid('12345678Z', 'ES', 'nif');       // true
taxid_format('11144477735', null, 'BR');        // '111.444.777-35'
vat_number('B12345674', 'ES');                 // 'ESB12345674'

Validation works immediately. To customize the CI4 configuration:

php spark taxid:publish

Set Config\TaxId::$defaultCountry when the helper and CLI should assume a country. The standalone facade continues to use its explicit country or a recognized input prefix.

CLI Commands

php spark taxid:validate 12345678Z --country ES --scheme nif
php spark taxid:validate 756.1234.5678.97 --country CH --scheme ahv --json
php spark taxid:parse 11.222.333/0001-81 --country BR
php spark taxid:countries
php spark taxid:countries MK --json

taxid:validate exits 0 for a valid value and 1 for an invalid one. JSON output includes the accepting scheme and nullable checksum_verified field.

Country Coverage

Region Examples
European Union ES NIF/NIE/CIF, PT NIF, IT codice fiscale/partita IVA, FR SIREN/SIRET/TVA, DE VAT/IdNr, PL NIP/PESEL/REGON
Other European Jurisdictions CH UID/IVA/AHV, NO organization/personal IDs, IS kennitala/VSK, MD IDNO/IDNP, MK EMBG/EDB, GB VAT/UTR/NINO, XI VAT
Americas BR CPF/CNPJ, MX RFC, AR CUIT, CL RUT, CO NIT, PE RUC, US EIN/SSN/ITIN, CA BN/SIN
Asia-Pacific IN GSTIN/PAN, CN USCC/resident ID, JP corporate number/My Number, KR BRN, AU ABN/ACN/TFN, NZ IRD, TW business number
Middle East & Africa IL personal/company IDs and registered formats for SA, AE, EG, ZA, KE, MA, NG, DZ and TN

The table lists coverage, not an identical validation level for every identifier. Country Coverage contains every scheme, its supported lengths and checksum capability. Algorithm Sources & Limits explains the arithmetic, exceptional formats and structural-only entries.

Taxpayer Resolution (Optional)

Configure a provider when the application needs registration or taxpayer data:

// app/Config/TaxId.php, after php spark taxid:publish
namespace Config;

use Daycry\TaxId\Config\TaxId as BaseTaxId;

class TaxId extends BaseTaxId
{
    public string $provider = 'vies';
    public ?int $cacheTtl = 86400;
}
$result = service('taxid')->resolve('ESB12345674');

$result->isValid();        // offline validation result
$result->isRegistered();   // true | false | null
$result->name();           // registered name, when available
Registration Result Meaning
true The configured provider found the taxpayer or confirmed registration
false A registration-checking provider explicitly reported no registration
null No answer: provider not configured, unsupported country, unavailable service or inconclusive lookup

For a local database or the database-first chain provider, run the optional migration:

php spark migrate --all

The tax_entities table starts empty. No taxpayer dataset is bundled. See Providers & Configuration before enabling external lookups.

Standalone Usage

require 'vendor/autoload.php';

$taxid = new \Daycry\TaxId\TaxId();
$taxid->isValid('756.1234.5678.97', 'CH', 'ahv'); // true

The core has no CodeIgniter dependency. The service, helper, commands, database integration, VIES client and CI4 cache adapter use CodeIgniter.

Documentation

Start with the Documentation Index for guides and feature summaries.

Section Description
Usage Guide Facade, validation assurance, helpers, CLI, providers and configuration
API Reference Public methods, DTOs, contracts and extension points
Country Coverage All 94 jurisdictions and 149 identifier schemes
Algorithm Sources & Limits Checksums, exceptional variants and verification provenance
Formatting Compact, print and anonymized output, with mask examples
Adding a Country Registry entries, validators and required checks
Architecture Dependency boundaries, validation pipeline and integrity checks
Translation Violation codes and application-level translation
Data & Licensing Registry authoring, example data and external lookups
Roadmap Current development, release history and future work

Development

composer update
composer test
composer analyze
composer cs
  • Tests: PHPUnit; test cases do not make network requests.
  • Static Analysis: PHPStan level 8 over src/ and tests/.
  • Code Style: PSR-12 with PHP-CS-Fixer; composer cs checks without editing.
  • Architecture: Tests enforce the framework-free core and registry/documentation consistency.
  • Dependencies: composer.lock is intentionally ignored for this library; CI resolves composer.json with composer update.

Contributing

Code, documentation, country rules and bug reports are welcome. See CONTRIBUTING.md for the workflow and Adding a Country for validation-specific requirements.

License

This project is licensed under the MIT License. See LICENSE for details.

Acknowledgements

Daycry TaxId contributors

Made with contrib.rocks.