nicxonsolutions / rajaongkir
Laravel package for RajaOngkir/Komerce destination search and shipping cost calculation.
Requires
- php: ^8.2
- illuminate/http: ^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/routing: ^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/session: ^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/view: ^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0|^12.0
README
Laravel package for the latest RajaOngkir Komerce API, including the current 2026 RajaOngkir API endpoints for destination lookup, shipping cost calculation, district-level shipping costs, and AWB tracking.
This package provides a Laravel-native API client, facade, optional API routes, courier metadata, and helpers for domestic and international shipping workflows.
Built and maintained by PT. Nicxon International Solutions.
Table of Contents
- Why This Package Exists
- Requirements
- Installation
- Configuration
- Basic Usage
- Search Destinations
- Calculate Shipping Costs
- Track Shipments
- Checkout Quote Helper
- Optional API Routes
- API Key Validation
- Error Handling
- Courier Metadata
- Production Notes
- License
- Support
Why This Package Exists
RajaOngkir is widely used in Indonesian ecommerce, but the Laravel ecosystem has lacked an up-to-date package for the current RajaOngkir Komerce API. RajaOngkir itself does not provide an official Laravel package, and many existing community packages target older API versions or outdated endpoint structures.
I at PT. Nicxon International Solutions created this package to fill that gap: a production-ready Laravel integration for the modern RajaOngkir Komerce API, with support for the latest destination hierarchy, domestic and international rates, district-level shipping cost calculation, and package tracking.
All rights reserved by PT. Nicxon International Solutions.
Requirements
- PHP
^8.2 - Laravel / Illuminate
6.xthrough13.x - RajaOngkir/Komerce API key
Installation
Install the package with Composer:
composer require nicxonsolutions/rajaongkir
Publish the configuration file:
php artisan vendor:publish --tag=rajaongkir-config
Add your RajaOngkir credentials and defaults to .env:
RAJAONGKIR_API_KEY=your-api-key RAJAONGKIR_BASE_URL=https://rajaongkir.komerce.id/api RAJAONGKIR_ACCOUNT_TYPE=starter RAJAONGKIR_ORIGIN=31555 RAJAONGKIR_ORIGIN_LABEL="Your Store Origin" RAJAONGKIR_TIMEOUT=10
Clear cached config when deploying or changing environment values:
php artisan config:clear
Configuration
The published config file is available at config/rajaongkir.php.
Important options:
return [ 'api_key' => env('RAJAONGKIR_API_KEY'), 'base_url' => env('RAJAONGKIR_BASE_URL', 'https://rajaongkir.komerce.id/api'), 'account_type' => env('RAJAONGKIR_ACCOUNT_TYPE', 'starter'), 'origin' => env('RAJAONGKIR_ORIGIN'), 'base_weight' => (int) env('RAJAONGKIR_BASE_WEIGHT', 0), 'sort_shipping' => env('RAJAONGKIR_SORT_SHIPPING', 'no'), ];
Supported sort_shipping values:
nocostcost_descnamename_desc
Enabled couriers and services are configured in selected_couriers.
Basic Usage
Use the facade when calling methods statically:
use Nicxonsolutions\Rajaongkir\Facades\Rajaongkir; $destinations = Rajaongkir::searchDomesticDestination('Jakarta');
Make sure you import Nicxonsolutions\Rajaongkir\Facades\Rajaongkir for static-style calls. If you import Nicxonsolutions\Rajaongkir\Rajaongkir, use dependency injection instead.
Or inject the service:
use Nicxonsolutions\Rajaongkir\Rajaongkir; class CheckoutController { public function shipping(Rajaongkir $rajaongkir) { return $rajaongkir->searchDomesticDestination('Bandung'); } }
Search Destinations
Search-Based Lookup
Domestic destination search:
$destinations = Rajaongkir::searchDomesticDestination('Jakarta');
Example response item:
[
'id' => 31711,
'text' => 'Gambir, Jakarta Pusat, DKI Jakarta 10110',
'label' => 'Gambir, Jakarta Pusat, DKI Jakarta 10110',
'subdistrict_name' => 'Gambir',
'district_name' => 'Gambir',
'city_name' => 'Jakarta Pusat',
'province_name' => 'DKI Jakarta',
'zip_code' => '10110',
]
International destination search:
$countries = Rajaongkir::searchInternationalDestination('Singapore');
Province, City, District, and Sub-District Lookup
You can also use the structured Indonesian location hierarchy endpoints.
Get all provinces:
$provinces = Rajaongkir::provinces();
Get one province by province ID:
$province = Rajaongkir::province($provinceId);
Get cities by province ID:
$cities = Rajaongkir::cities($provinceId);
Get one city by province ID and city ID:
$city = Rajaongkir::city($provinceId, $cityId);
If you only have the city ID, you can search all provinces:
$city = Rajaongkir::findCity($cityId);
Get districts by city ID:
$districts = Rajaongkir::districts($cityId);
Get one district by city ID and district ID:
$district = Rajaongkir::district($cityId, $districtId);
Get sub-districts by district ID:
$subDistricts = Rajaongkir::subDistricts($districtId);
Get one sub-district by district ID and sub-district ID:
$subDistrict = Rajaongkir::subDistrict($districtId, $subDistrictId);
The package normalizes each item with common keys:
[
'id' => 1,
'text' => 'Bali',
'name' => 'Bali',
// Original API fields are preserved as well.
]
Calculate Shipping Costs
Domestic rates:
$rates = Rajaongkir::calculateDomestic([ 'origin' => '31555', 'destination' => '31711', 'weight' => 1200, 'courier' => ['jne', 'jnt', 'pos'], ]);
International rates:
$rates = Rajaongkir::calculateInternational([ 'origin' => '31555', 'destination' => '702', 'weight' => 1200, 'courier' => ['jne', 'pos'], ]);
District-level domestic rates:
$rates = Rajaongkir::calculateDistrictDomestic([ 'origin' => '4570', 'destination' => '4571', 'weight' => 1200, 'courier' => ['jne', 'jnt', 'pos'], ]);
Example parsed rate:
[
'courier' => 'jne',
'courier_label' => 'JNE',
'service' => 'REG',
'description' => 'Layanan Reguler',
'cost' => 18000,
'currency' => 'IDR',
'etd' => '2-3',
'note' => '',
'cost_conversion' => false,
]
The calculation methods return:
[
'parsed' => [...],
'raw' => [...],
]
Track Shipments
Track a shipment by AWB number and courier:
$tracking = Rajaongkir::trackWaybill( awb: 'YOUR_AWB_NUMBER', courier: 'jne', );
Some couriers require the last 5 digits of the recipient phone number for validation, including JNE:
$tracking = Rajaongkir::trackWaybill( awb: 'YOUR_AWB_NUMBER', courier: 'jne', lastPhoneNumber: '12345', );
The API response contains shipment summary, details, delivery status, and manifest history when available:
[
'delivered' => true,
'summary' => [...],
'details' => [...],
'delivery_status' => [...],
'manifest' => [...],
]
Checkout Quote Helper
For application carts, you can use quote() and pass the cart weight plus destination data:
$quote = Rajaongkir::quote( cart: ['weight' => 1200], destination: [ 'country' => 'ID', 'id' => '31711', ], );
You may override default origin or request parameters:
$quote = Rajaongkir::quote( cart: ['weight' => 1200], destination: ['country' => 'ID', 'id' => '31711'], options: [ 'origin' => '31555', 'params' => [ 'courier' => ['jne', 'sicepat'], ], ], );
Optional API Routes
Package routes are disabled by default. Enable them in .env:
RAJAONGKIR_ROUTES_ENABLED=true RAJAONGKIR_ROUTES_PREFIX=api/rajaongkir
Available routes:
GET /api/rajaongkir/destinations/domestic?search=Jakarta
GET /api/rajaongkir/destinations/international?search=Singapore
GET /api/rajaongkir/destinations/provinces
GET /api/rajaongkir/destinations/provinces/{provinceId}
GET /api/rajaongkir/destinations/cities/{provinceId}
GET /api/rajaongkir/destinations/cities/{provinceId}/{cityId}
GET /api/rajaongkir/destinations/districts/{cityId}
GET /api/rajaongkir/destinations/districts/{cityId}/{districtId}
GET /api/rajaongkir/destinations/sub-districts/{districtId}
GET /api/rajaongkir/destinations/sub-districts/{districtId}/{subDistrictId}
POST /api/rajaongkir/costs/domestic
POST /api/rajaongkir/costs/international
POST /api/rajaongkir/costs/district/domestic
POST /api/rajaongkir/track/waybill
Cost request body:
{
"origin": "31555",
"destination": "31711",
"weight": 1200,
"courier": ["jne", "jnt", "pos"]
}
District domestic cost requests use the same body shape, but origin and destination should be district IDs.
Tracking request body:
{
"awb": "YOUR_AWB_NUMBER",
"courier": "jne",
"last_phone_number": "12345"
}
last_phone_number is optional for the package request, but certain couriers may require it.
API Key Validation
You can perform a simple API key check:
$valid = Rajaongkir::validateApiKey();
This performs a small domestic destination search request.
Error Handling
The package throws Nicxonsolutions\Rajaongkir\Exceptions\RajaongkirException for missing configuration, invalid parameters, or API errors.
use Nicxonsolutions\Rajaongkir\Exceptions\RajaongkirException; use Nicxonsolutions\Rajaongkir\Facades\Rajaongkir; try { $rates = Rajaongkir::calculateDomestic([...]); } catch (RajaongkirException $e) { report($e); return back()->withErrors([ 'shipping' => $e->getMessage(), ]); }
Courier Metadata
Courier and service metadata is stored in config/couriers.php. The package includes domestic and international services ported from the original WooCommerce plugin.
Get available couriers:
$all = Rajaongkir::couriers(); $domestic = Rajaongkir::couriers('domestic'); $international = Rajaongkir::couriers('international');
Use courier() when you want to fetch all couriers, one courier, or couriers matching a service code:
$all = Rajaongkir::courier('all'); $jne = Rajaongkir::courier('jne'); $regularServices = Rajaongkir::courier('REG');
When the filter matches a courier code, response code, or courier label, one courier is returned. When the filter matches a service code or service label, matching couriers are returned with a matched_services key.
Production Notes
- Keep
RAJAONGKIR_API_KEYprivate and never expose it in frontend JavaScript. - Use your own controller endpoints for checkout flows when you need authentication, rate limiting, cart validation, or custom business rules.
- Cache destination search results if your checkout receives heavy traffic.
- Re-run
php artisan config:cacheduring deployment if your application uses cached config.
License
GPL-2.0-or-later.
Copyright (c) PT. Nicxon International Solutions. All rights reserved.