blissjaspis/laravel-rajaongkir-komerce is a Laravel package for laravel rajaongkir from komerce.
It currently has 2 GitHub stars and 27 downloads on Packagist (latest version v2.1.0).
Install it with composer require blissjaspis/laravel-rajaongkir-komerce.
Discover more Laravel packages by blissjaspis
or browse all Laravel packages to compare alternatives.
Last updated
This package provides a simple and easy-to-use Laravel wrapper for the RajaOngkir Komerce API. It supports two methods of address lookup: hierarchical step-by-step selection and direct search with autocomplete functionality.
| Requirement | Version | |-------------|---------| | PHP | ^8.2 | | Laravel | ^11.0, ^12.0, or ^13.0 |
You can install the package via composer:
composer require blissjaspis/laravel-rajaongkir-komerce
You must publish the configuration file with:
php artisan vendor:publish --tag=rajaongkir-komerce-config
Or using the provider:
php artisan vendor:publish --provider="BlissJaspis\RajaOngkir\Providers\RajaOngkirServiceProvider" --tag="config"
Add the following to your .env file:
RAJAONGKIR_API_KEY=your-api-key
RAJAONGKIR_BASE_URL=https://rajaongkir.komerce.id/api/v1
# Optional
RAJAONGKIR_TIMEOUT=30
RAJAONGKIR_RETRY_TIMES=0
RAJAONGKIR_RETRY_SLEEP=100
RAJAONGKIR_FAKE=false
Set RAJAONGKIR_FAKE=true in local development to stub all API responses without calling Komerce.
The package is auto-discovered via Laravel's package discovery. No manual registration is required.
There are two ways to use Rajaongkir-Komerce:
For existing users whose data is still using the old method, you can continue using method 1.
This package supports 2 ways to access RajaOngkir data:
province -> city -> district -> subdistrict)You can call the API through the facade or Laravel's service container:
use BlissJaspis\RajaOngkir\Facades\RajaOngkir;
use BlissJaspis\RajaOngkir\RajaOngkir as RajaOngkirClient;
// Via Facade (recommended)
$response = RajaOngkir::getProvinces();
$provinces = $response->data;
// Via dependency injection (interface)
use BlissJaspis\RajaOngkir\Contracts\RajaOngkirClient;
public function __construct(private RajaOngkirClient $rajaOngkir) {}
// Or resolve from the container
app(RajaOngkirClient::class)->getProvinces();
API methods return a RajaOngkirResponse object with meta, data, status(), and successful(). Use getListCourier() when you need the static courier list (hardcoded from Komerce documentation — no API endpoint).
RajaOngkir is registered as a singleton in the service container, so the facade and app() resolve the same instance.
Failed HTTP requests and API error responses throw BlissJaspis\RajaOngkir\Exceptions\RajaOngkirException:
use BlissJaspis\RajaOngkir\Exceptions\RajaOngkirException;
use BlissJaspis\RajaOngkir\Facades\RajaOngkir;
try {
$response = RajaOngkir::getProvinces();
} catch (RajaOngkirException $exception) {
$statusCode = $exception->statusCode;
$body = $exception->response;
}
Use Method 1 (Step-by-step) if:
Use Method 2 (Direct Search) if:
Method 2 is recommended for new implementations as it provides a more modern and user-friendly approach.
Use this method when users select addresses hierarchically.
$response = RajaOngkir::getProvinces();
$provinces = $response->data;
{
"meta": {
"message": "Success Get Provinces",
"code": 200,
"status": "success"
},
"data": [
{
"id": 11,
"name": "DKI Jakarta"
},
{
"id": 6,
"name": "Jawa Barat"
}
// ... more provinces
]
}
$provinceId = 11;
$cities = RajaOngkir::getCity($provinceId);
{
"meta": {
"message": "Success Get Cities",
"code": 200,
"status": "success"
},
"data": [
{
"id": 1,
"name": "Jakarta Pusat"
},
{
"id": 2,
"name": "Jakarta Selatan"
}
// ... more cities
]
}
$cityId = 1;
$districts = RajaOngkir::getDistrict($cityId);
{
"meta": {
"message": "Success Get Districts",
"code": 200,
"status": "success"
},
"data": [
{
"id": 1,
"name": "Kemayoran"
}
// ... more districts
]
}
$districtId = 1;
$subdistricts = RajaOngkir::getSubDistrict($districtId);
{
"meta": {
"message": "Success Get Subdistricts",
"code": 200,
"status": "success"
},
"data": [
{
"id": 1,
"name": "Sumur Batu"
}
// ... more subdistricts
]
}
Use this method when users type destination keywords directly, then you calculate shipping.
$search = 'sinduharjo';
$limit = 10; // optional
$offset = 0; // optional
$destinations = RajaOngkir::searchDomestic($search, $limit, $offset);
{
"meta": {
"message": "Success Get Domestic Destinations",
"code": 200,
"status": "success"
},
"data": [
{
"id": 31555,
"label": "SINDUHARJO, NGAGLIK, SLEMAN, DI YOGYAKARTA, 55581",
"subdistrict_name": "SINDUHARJO",
"district_name": "NGAGLIK",
"city_name": "SLEMAN",
"province_name": "DI YOGYAKARTA",
"zip_code": "55581"
}
]
}
$search = 'Malaysia';
$limit = 10; // optional
$offset = 0; // optional
$destinations = RajaOngkir::searchInternational($search, $limit, $offset);
{
"meta": {
"message": "Success Get International Destinations",
"code": 200,
"status": "success"
},
"data": [
{
"id": 108,
"name": "Malaysia"
}
// ... more destinations
]
}
$origin = 1;
$destination = 108;
$weight = 1000;
$courier = 'jne';
$filter = 'lowest';
$cost = RajaOngkir::getCostDomestic($origin, $destination, $weight, $courier, $filter);
{
"meta": {
"message": "Success Calculate Domestic Shipping cost",
"code": 200,
"status": "success"
},
"data": [
{
"name": "Nusantara Card Semesta",
"code": "ncs",
"service": "DARAT",
"description": "Regular Darat",
"cost": 8000,
"etd": "6-7 day"
},
{
"name": "Citra Van Titipan Kilat (TIKI)",
"code": "tiki",
"service": "ECO",
"description": "Economy Service",
"cost": 15000,
"etd": "5 day"
}
]
}
$origin = 1;
$destination = 108;
$weight = 1000;
$courier = 'jne';
$filter = 'lowest';
$cost = RajaOngkir::getCostInternational($origin, $destination, $weight, $courier, $filter);
{
"meta": {
"message": "Success Calculate International Shipping Cost",
"code": 200,
"status": "success"
},
"data": [
{
"name": "Rayspeed Indonesia",
"code": "ray",
"service": "Regular Service",
"description": "Retail",
"currency": "IDR",
"cost": 55000,
"etd": ""
},
{
"name": "Lion Parcel",
"code": "lion",
"service": "INTERPACK",
"description": "Active",
"currency": "IDR",
"cost": 65000,
"etd": "2-3 day"
}
]
}
$waybill = 'MT685U91';
$courier = 'jne';
$waybill = RajaOngkir::getWaybill($waybill, $courier);
{
"meta": {
"message": "Success Get Waybill",
"code": 200,
"status": "success"
},
"data": {
"delivered": true,
"summary": {
"courier_code": "wahana",
"courier_name": "Wahana Prestasi Logistik",
"waybill_number": "MT685U91",
"service_code": "",
"waybill_date": "2024-10-08",
"shipper_name": "TOKO ALAT LUKIS (08112XXXXXX)",
"receiver_name": "FIKRI EL SARA (085668XXXXXX)",
"origin": "",
"destination": "di Kota Sukabumi",
"status": "DELIVERED"
},
"details": {
"waybill_number": "MT685U91",
"waybill_date": "2024-10-08",
"waybill_time": "11:14:29",
"weight": "",
"origin": "",
"destination": "di Kota Sukabumi",
"shipper_name": "TOKO ALAT LUKIS (08112XXXXXX)",
"shipper_address1": "",
"shipper_address2": "",
"shipper_address3": "",
}
"delivery_status": {
"status": "DELIVERED",
"pod_receiver": "FIKRI EL SARA (085668XXXXXX)",
"pod_date": "2024-10-11",
"pod_time": "09:26:13"
},
"manifest": [
// ... more manifest
]
}
}
getListCourier() returns a static list of supported courier codes and display names (not an API call):
$couriers = RajaOngkir::getListCourier();
// [
// 'jne' => 'JNE',
// 'sicepat' => 'SICEPAT',
// 'tiki' => 'TIKI',
// // ...
// ]
For comprehensive API documentation including:
Please see API-REFERENCE.md for detailed technical documentation optimized for developers and AI assistants.
This package uses GitHub Actions for continuous integration: lint runs once, then tests run across PHP 8.2–8.5 and Laravel 11–13.
| Command | Description |
|---------|-------------|
| composer test | Run PHPUnit tests |
| composer lint | Syntax check, Pint (dry-run), and PHPStan (level 6) |
| composer analyse | Run PHPStan static analysis only |
| composer format | Auto-format code with Laravel Pint |
| composer check | Run lint + test (recommended before PRs) |
composer check
Please see CHANGELOG for more information on what has changed recently.
For contribution guidelines and local development setup, see CONTRIBUTING.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.