ajangsupardi/laravel-postcode-id

Laravel package for seeding Indonesian address data (provinces, regencies, districts, villages) with postal codes from Pos Indonesia

Maintainers

Package info

github.com/ajangsupardi/laravel-postcode-id

pkg:composer/ajangsupardi/laravel-postcode-id

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-06-19 03:16 UTC

This package is auto-updated.

Last update: 2026-06-19 03:59:39 UTC


README

Latest Stable Version License Total Downloads

Laravel package for downloading and seeding Indonesian address data (provinces, regencies, districts, villages) with postal codes from the official Pos Indonesia website.

Features

  • Auto-download postcode data from Pos Indonesia
  • Hierarchical data parsing: Province → Regency → District → Village
  • Ready-to-use database seeders
  • Migration files included
  • Configurable and extendable Eloquent models
  • Supports Laravel 11, 12, and 13

Installation

composer require ajangsupardi/laravel-postcode-id

Publish Configuration (optional)

php artisan vendor:publish --tag=postcode-config

Publish Migrations (optional)

php artisan vendor:publish --tag=postcode-migrations

Note: Migrations are automatically loaded by the service provider, so publishing is only needed if you want to modify the table structure.

Usage

1. Download Postcode Data

php artisan postcode:download

This command will download all postcode data from Pos Indonesia and save it as a CSV file.

2. Run the Seeder

php artisan db:seed --class=Ajangsupardi\PostcodeId\Database\Seeders\PostcodeSeeder

Or add it to your DatabaseSeeder.php:

use Ajangsupardi\PostcodeId\Database\Seeders\PostcodeSeeder;

public function run(): void
{
    $this->call([
        PostcodeSeeder::class,
    ]);
}

3. Auto-download & Seed

If you want to combine download and seed in a single step, you can call the download command before the seeder:

use Illuminate\Support\Facades\Artisan;

$storagePath = config('postcode.storage_path');
if (! file_exists($storagePath.'/kodepos.csv')) {
    Artisan::call('postcode:download');
}

Database Tables

This package creates 4 tables:

Table Description
provinces Province data (id, name, code)
regencies Regency/city data (id, province_id, name)
districts District/sub-district data (id, regency_id, name)
villages Village data (id, district_id, name, postal_code)

Configuration

Edit config/postcode.php:

return [
    // CSV file storage path
    'storage_path' => storage_path('app/postcode'),

    // Database table prefix (null = no prefix)
    'table_prefix' => null,

    // Custom models
    'models' => [
        'province' => Ajangsupardi\PostcodeId\Models\Province::class,
        'regency'  => Ajangsupardi\PostcodeId\Models\Regency::class,
        'district' => Ajangsupardi\PostcodeId\Models\District::class,
        'village'  => Ajangsupardi\PostcodeId\Models\Village::class,
    ],

    // HTTP client settings
    'http' => [
        'timeout' => 60,
        'connect_timeout' => 10,
        'retry' => 3,
        'retry_delay' => 1000,
        'user_agent' => 'Mozilla/5.0 (compatible; LaravelPostcodeId/1.0)',
    ],
];

Custom Models

You can extend the default models to add columns or relationships:

namespace App\Models;

use Ajangsupardi\PostcodeId\Models\Province as BaseProvince;

class Province extends BaseProvince
{
    protected $fillable = ['name', 'code', 'your_custom_field'];

    // Add custom relationships or methods
}

Then update the configuration:

'models' => [
    'province' => App\Models\Province::class,
],

Table Prefix

If you want to use a prefix for your tables:

'table_prefix' => 'postcode_',

This will create tables: postcode_provinces, postcode_regencies, postcode_districts, postcode_villages.

Example Queries

use Ajangsupardi\PostcodeId\Models\Province;
use Ajangsupardi\PostcodeId\Models\Village;

// Get all provinces
$provinces = Province::all();

// Get regencies in East Java
$regencies = Province::where('name', 'Jawa Timur')
    ->first()
    ->regencies;

// Find a village by postal code
$village = Village::where('postal_code', '60111')->first();

// Get full address hierarchy from village to province
$village = Village::with('district.regency.province')
    ->where('postal_code', '60111')
    ->first();

Requirements

  • PHP ^8.3
  • Laravel ^11.0 / ^12.0 / ^13.0

License

MIT License. See LICENSE for more information.