deligoez/tckimlikno
A Laravel and PHP package for validating and generating Turkish Identification Numbers (TC Kimlik No). It provides a Laravel validation rule, checksum verification, and helpers for producing valid test numbers without external APIs.
tckimlikno is a small, focused package for validating Turkish Republic national ID numbers (T.C. Kimlik No) using the official checksum algorithm. v5.1.0 adds Laravel 12 support, so it now works on Laravel 10/11/12 (confirm your installed version against the tag before upgrading).
composer require deligoez/tckimlikno
No service provider or config file needs publishing — the package ships a single validation rule and supporting classes. First use case: add the rule to a form request.
use Deligoez\TCKimlikNo\Rules\TCKimlikNo;
public function rules(): array
{
return [
'tckn' => ['required', 'string', 'size:11', new TCKimlikNo()],
];
}
That's the whole 80% path. Look first at the rule class in src/Rules, then the README for the facade/validator helper if you need to check a number outside a validation context.
Request validation (most common). Use the rule object inline or in a form request. Pair it with required and size:11/digits:11 so the failure message is precise — the rule alone returns one generic message.
$rules = ['tckn' => ['required', 'digits:11', new TCKimlikNo()]];
Direct programmatic check. When you only need a boolean (e.g. importing records, seeding, backfilling), use the provided facade/validator helper rather than spinning up a Validator instance:
use Deligoez\TCKimlikNo\TCKimlikNo;
if (TCKimlikNo::validate($value)) {
// checksum-valid
}
Wrap it in your own service/action class so the rest of the app doesn't couple to the package namespace — this makes swapping or adding an external verification step later trivial.
Custom messages. Attach a message via the rule's message() (Laravel 10+) or pass it through the :attribute translator:
'tckn' => ['required', new TCKimlikNo()],
// lang/tr/validation.php → custom TC Kimlik No message under the rule key
Integration tips.
string column — never an integer (leading zeros and 32-bit overflow).Rule::unique('users', 'tckn') for registration flows.src/ before relying on it — it is not part of the validation rule contract.invalid_tckn) mapped from the validation failure so clients can localize.Validation ≠ verification. The rule only confirms the number satisfies the 11-digit checksum algorithm. It does not prove the ID belongs to a real person. For KYC-grade flows, add the NVI/MERSIS web-service check (or a provider) on top; treat a checksum pass as a cheap pre-filter only.
Do not store as integer. PHP's int on 32-bit builds will silently corrupt 11-digit values, and leading-zero edge cases are real. Use char(11)/string in migrations and cast to string in models.
Input normalization matters. Users paste numbers with spaces, dots, or Arabic-Indic digits. Normalize to ASCII digits and reject anything else before the rule runs, otherwise you'll get misleading "invalid" errors on otherwise-correct IDs.
Testing. Unit-test your wrapper, not the package: assert valid → passes, invalid checksum → fails, 10 digits → fails, all zeros → fails. The checksum algorithm rejects obvious patterns (e.g. all-identical digits), so don't assume "any 11 digits" is valid in fixtures.
Caching. If you validate large import batches, memoize results keyed by the raw number — the check is pure/stateless and repeat calls are wasted work.
Version notes. v5.1.0 is a maintenance release (Laravel 12 compatibility only) — no API or behaviour changes vs v5.0.0, so it's a safe minor bump. Pin ^5.1 in composer.json if you're on Laravel 12, otherwise ^5.0 is fine. Watch the changelog for future majors, as the rule's constructor/message signature has been the historical breaking point.
Extension points. The rule class is small and final-friendly; if you need a locale-specific message or a combined "checksum + NVI" rule, extend or compose around it rather than forking — the algorithm is stable and unlikely to need edits.
How can I help you explore Laravel packages today?