PHP code example of bensondevs / indonesian-ktp

1. Go to this page and download the library: Download bensondevs/indonesian-ktp library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

bensondevs / indonesian-ktp example snippets


use Bensondevs\IndonesianKtp\KTP;

KTP::nik('123')->isValid(); // false — wrong length
KTP::nik('9999991501900001')->isValid(); // false — unknown district (no expectations)

use Bensondevs\IndonesianKtp\KTP;

KTP::nik('3315131501901235')->isValid();

use Bensondevs\IndonesianKtp\Gender;
use Bensondevs\IndonesianKtp\KTP;

KTP::nik('3315131501901235')
    ->expectGender(Gender::Male)
    ->isValid();

use Bensondevs\IndonesianKtp\KTP;

KTP::nik('3315131501901235')->isValid();

use Bensondevs\IndonesianKtp\Rules\KtpNik;

$request->validate([
    'nik' => ['
    'nik' => ['

use Bensondevs\IndonesianKtp\Gender;
use Bensondevs\IndonesianKtp\KTP;

$query = KTP::nik('3315131501901235');

$query->matchBirthDate('1990-01-15');
$query->matchGender(Gender::Male);
$query->matchGender('male');

use Bensondevs\IndonesianKtp\Gender;
use Bensondevs\IndonesianKtp\KTP;

KTP::nik('3315131501901235')
    ->expectBirthDate('1990-01-15')
    ->expectGender(Gender::Male)
    ->expectProvince('jawa tengah')
    ->isValid();

use Bensondevs\IndonesianKtp\Gender;
use Bensondevs\IndonesianKtp\KTP;

KTP::nik('3315131501901235')
    ->birthDate('1990-01-15')
    ->gender(Gender::Male)
    ->province('jawa tengah')
    ->isValid();

use Bensondevs\IndonesianKtp\KTP;

$validationResult = KTP::nik('3315131501901235')->validate();

$validationResult->hasValidStructure();
$validationResult->hasValidRegionHierarchy();
$validationResult->hasValidGender(); // null — no expectation

$validationResult = KTP::nik('3315131501901235')
    ->birthDate('1990-01-01')
    ->validate();

$validationResult->hasValidBirthDate(); // false — mismatch

use Bensondevs\IndonesianKtp\KTP;

$validationResult = KTP::nik('3315131501901235')->validate();

$validationResult->isFullyValid(); // same as isValid() on the query

use Bensondevs\IndonesianKtp\KTP;
use Carbon\Carbon;

$parsed = KTP::nik('3315131501901235')->parsed();

$parsed->raw();
$parsed->structureValid();
$parsed->districtCode();              // NIK wilayah key, e.g. "33.15.13"
$parsed->provinceCode();              // "33"
$parsed->regencyCode();               // "33.15"
$parsed->province();                 // e.g. "Jawa Tengah" — null if lookup has no row
$parsed->regency();                  // e.g. "Kabupaten Grobogan"; alias: city(), kabupaten(), kota()
$parsed->district();                 // e.g. "Purwodadi"; alias: kecamatan()
$parsed->birthDate();                // null if ambiguous (no asOf on query)
$parsed->possibleBirthDates();
$parsed->gender();
$parsed->serial();
$parsed->age();                      // optional asOf; defaults to now()
$parsed->age(Carbon::parse('2026-01-01'));
$parsed->isSeventeenOrOlder(Carbon::parse('2026-01-01'));

use Bensondevs\IndonesianKtp\KTP;

$sampleNik = '3315131501901235';

KTP::nik($sampleNik)->expectProvince(33)->isValid();
KTP::nik($sampleNik)->expectProvince('JAWA TENGAH')->isValid();

use Bensondevs\IndonesianKtp\KTP;

KTP::nik('3315131501901235')
    ->expectRegency(15) // province taken from NIK (33…)
    ->isValid();

use Bensondevs\IndonesianKtp\KTP;

KTP::nik('3315131501901235')
    ->expectRegency(15)
    ->expectSubdistrict(13)
    ->isValid();

use Bensondevs\IndonesianKtp\KTP;

KTP::nik('9999991501900001')->isValid(); // false

use Bensondevs\IndonesianKtp\KTP;
use Carbon\Carbon;

// No asOf: every plausible century for YY that fits a 17–120 age window (evaluated at query build time)
KTP::nik('3315131501901235');

// With asOf: single resolved birth year for that pivot
KTP::nik('3315131501901235')->asOf(Carbon::parse('2026-01-01'));

use Bensondevs\IndonesianKtp\KTP;
use Carbon\Carbon;

$query = KTP::nik('3315131501901235')->asOf(Carbon::parse('2026-01-01'));

$query->matchAge(35);
$query->matchAtLeastYears(21);

use Bensondevs\IndonesianKtp\KTP;
use Carbon\Carbon;

Carbon::setTestNow('2026-09-01');

$ambiguousNik = '3315130109090002';

KTP::nik($ambiguousNik)->parsed()->birthDate();              // null
count(KTP::nik($ambiguousNik)->parsed()->possibleBirthDates()); // 2

KTP::nik($ambiguousNik)->asOf(Carbon::parse('2026-09-01'))->parsed()->birthDate(); // single date

Carbon::setTestNow();

use Bensondevs\IndonesianKtp\Regions\Lookup\FileRegionHierarchyLookup;
use Bensondevs\IndonesianKtp\Regions\Lookup\RegionHierarchyLookup;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(RegionHierarchyLookup::class, function (): FileRegionHierarchyLookup {
            $path = storage_path('app/wilayah.php'); // your compiled file

            return new FileRegionHierarchyLookup($path);
        });
    }
}

use Bensondevs\IndonesianKtp\Concerns\HasIndonesianKtp;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasIndonesianKtp;

    // Optional: if your NIK column is not named `nik`
    // protected function getIndonesianKtpNikColumn(): string
    // {
    //     return 'id_number';
    // }
}

// $model is an Eloquent model using HasIndonesianKtp

$model->hasValidNik();
$model->nikGenderIs($model->gender);
$model->nikProvinceIs($model->province);
$model->nikAgeIs((int) $model->age);

protected function getIndonesianKtpNikColumn(): string
{
    return 'national_id';
}

// With default getIndonesianKtpNikColumn() => 'nik'
protected function getNikAttribute(?string $value): ?string
{
    return $value !== null ? preg_replace('/\D/', '', $value) : null;
}

use Bensondevs\IndonesianKtp\Concerns\HasIndonesianKtp;
use Illuminate\Database\Eloquent\Model;

class Applicant extends Model
{
    use HasIndonesianKtp;

    protected function getIndonesianKtpNikColumn(): string
    {
        return 'identity_number';
    }
}

// Validation-style usage (attributes / casts apply on reads):
$applicant->hasValidNik()
    && $applicant->nikBirthdateIs($applicant->profile?->dob ?? $applicant->legacy_birthdate)
    && $applicant->nikGenderIs($applicant->sex_code)
    && $applicant->nikProvinceIs($applicant->prov_name)
    && $applicant->nikRegencyIs($applicant->kab_name)
    && $applicant->nikSubdistrictIs($applicant->kec_name);

use Carbon\Carbon;
use Carbon\CarbonInterface;

protected function indonesianKtpReferenceDate(): ?CarbonInterface
{
    return null; // ambiguous
}

protected function indonesianKtpReferenceDate(): ?CarbonInterface
{
    return Carbon::now(); // pivot on “now”
}