aliziodev/laravel-biteship
最新稳定版本:v1.4.0
Composer 安装命令:
composer require aliziodev/laravel-biteship
包简介
Laravel package for Biteship shipping aggregator API integration
README 文档
README
Laravel package untuk integrasi Biteship API. Mendukung Rates, Orders, Tracking, Couriers, Location Search, Label Print, Webhook Events, dan optional DB layer via HasBiteship trait.
Requirements
- PHP 8.3+
- Laravel 12 atau 13
Installation
composer require aliziodev/laravel-biteship
php artisan biteship:install
Command ini akan mempublish config dan menanyakan apakah ingin menggunakan optional DB layer.
Environment
BITESHIP_API_KEY=biteship_live.xxxxxxxxxxxx # Sandbox — gunakan key dengan prefix biteship_test.* # BITESHIP_API_KEY=biteship_test.xxxxxxxxxxxx # Optional: default origin (dipakai oleh ->defaultOrigin()) BITESHIP_ORIGIN_AREA_ID=IDNP6... BITESHIP_ORIGIN_CONTACT_NAME=Nama Pengirim BITESHIP_ORIGIN_CONTACT_PHONE=0812xxxxxxxx BITESHIP_ORIGIN_ADDRESS=Jl. Contoh No. 1 # Optional: default courier (dipakai oleh ->defaultCourier()) BITESHIP_COURIER_COMPANY=jne # kurir untuk order BITESHIP_COURIER_TYPE=reg # tipe layanan untuk order BITESHIP_COURIER_INSURANCE=true # opsional BITESHIP_COURIER_FILTER=jne,sicepat # kurir untuk rate check (CSV), override COMPANY # Optional: default shipper branding (nama di label cetak) BITESHIP_SHIPPER_CONTACT_NAME=Nama Toko BITESHIP_SHIPPER_CONTACT_PHONE=021xxxxxxx BITESHIP_SHIPPER_ORGANIZATION=PT Nama Perusahaan # Optional: webhook signature verification BITESHIP_WEBHOOK_SIGNATURE_KEY=X-My-Header BITESHIP_WEBHOOK_SIGNATURE_SECRET=my-secret-value
Usage
Semua fitur diakses via Facade Biteship::.
use Aliziodev\Biteship\Facades\Biteship;
Maps (Area Search)
Biteship menyediakan Maps API untuk mencari area pengiriman berdasarkan teks input (autocomplete). Gunakan id (Area ID) dari hasil ini untuk keperluan pembuatan order.
$areas = Biteship::maps()->areas('Menteng'); // $areas → Collection of array foreach ($areas as $area) { // $area['id'], $area['name'], $area['postal_code'] }
Locations (Address Book)
Anda dapat menyimpan alamat yang sering digunakan menggunakan Location API Biteship.
// 1. Create Location $location = Biteship::locations()->create([ 'name' => 'Gudang Pusat', 'contact_name' => 'Budi', 'contact_phone' => '08123456789', 'address' => 'Jl. Sudirman No. 1', 'postal_code' => '12190', 'note' => 'Pintu gerbang warna merah', ]); // $location['id'] -> 'loc_...' // 2. Find Location $location = Biteship::locations()->find('loc_123456'); // 3. Update Location $location = Biteship::locations()->update('loc_123456', [ 'contact_name' => 'Andi', 'contact_phone' => '08987654321', ]); // 4. Delete Location $response = Biteship::locations()->delete('loc_123456'); // $response['success'] -> true
Rates (Ongkir)
Rates API menerima multi-kurir — hasilnya adalah daftar harga dari semua kurir yang diminta, untuk ditampilkan sebagai pilihan ke user.
use Aliziodev\Biteship\DTOs\Rate\RateRequest; $request = (new RateRequest) ->defaultOrigin() // dari config BITESHIP_ORIGIN_* ->destinationAreaId('IDNP6...') ->destinationContact('Budi', '08123456789') ->destinationAddress('Jl. Merdeka No. 10') ->addItem([ 'name' => 'Sepatu', 'value' => 350000, 'weight' => 500, // gram 'quantity' => 1, 'length' => 30, 'width' => 20, 'height' => 15, ]); $response = Biteship::rates()->check($request); // $response->pricing → Collection<CourierRate> foreach ($response->pricing as $rate) { // $rate->courier_name, $rate->courier_code, $rate->price, $rate->etd }
Filter kurir — default cek semua kurir aktif di akun Biteship ('biteship'):
// Eksplisit per-request $request->couriers(['jne', 'sicepat', 'jnt']); // Atau dari config BITESHIP_COURIER_FILTER=jne,sicepat,jnt $request->defaultCourier();
Cache & fresh:
// Bypass cache — selalu hit API $response = Biteship::rates()->fresh()->check($request); // Invalidate cache untuk payload tertentu Biteship::rates()->forget($request);
Cache: hasil ongkir di-cache otomatis (default 15 menit). Konfigurasikan via
config/biteship.php.
Draft Orders
Draft Order API memungkinkan Anda menyimpan pesanan sebelum dikonfirmasi (misalnya saat di keranjang belanja). Draft order dapat diubah kurirnya, dan tidak akan menghasilkan resi (waybill_id) sampai dikonfirmasi.
Create Draft Order
use Aliziodev\Biteship\DTOs\Order\OrderRequest; $request = (new OrderRequest) ->defaultOrigin() ->destinationContact('Budi', '08123456789') ->destinationAddress('Jl. Merdeka No. 10') ->addItem([ 'name' => 'Sepatu', 'value' => 350000, 'weight' => 500, 'quantity' => 1, ]); // Kurir opsional di Draft Order // Jika kurir diset, status akan menjadi 'ready' // Jika tidak diset, status akan menjadi 'placed' $draft = Biteship::draftOrders()->create($request); // $draft->id → Biteship draft order ID ('DRAFT-...') // $draft->status → DraftOrderStatus enum
Update, Find, Delete & Rates
// Update (set kurir agar siap dikonfirmasi) $updated = Biteship::draftOrders()->setCourier($draft->id, 'jne', 'reg'); // $updated->status → DraftOrderStatus::READY // Get detail $draft = Biteship::draftOrders()->find($draft->id); // Get ongkos kirim khusus untuk draft order ini (harus set kurir nantinya dari sini) $rates = Biteship::draftOrders()->rates($draft->id); // $rates->pricing → daftar harga // Delete draft $response = Biteship::draftOrders()->delete($draft->id);
Confirm Draft Order
Setelah draft order dalam status ready (memiliki kurir), Anda bisa mengkonfirmasinya menjadi order resmi.
$order = Biteship::draftOrders()->confirm($draft->id); // Mengembalikan OrderResponse (sama dengan Biteship::orders()->create()) // $order->id → Biteship order ID ('ORD-...') // $order->status → OrderStatus::CONFIRMED
DraftOrderStatus Enum
DraftOrderStatus memiliki 3 nilai:
placed: Baru dibuat, belum memiliki kurir.ready: Sudah memiliki kurir, siap dikonfirmasi.confirmed: Sudah dikonfirmasi menjadi order resmi.
Orders
Create Order
Order hanya bisa dibuat dengan 1 kurir spesifik (company + type). Kurir biasanya didapat dari pilihan user di checkout berdasarkan hasil Rates.
use Aliziodev\Biteship\DTOs\Order\OrderRequest; $request = (new OrderRequest) ->defaultOrigin() ->destinationAreaId('IDNP6...') ->destinationContact('Budi', '08123456789') ->destinationAddress('Jl. Merdeka No. 10') ->courier('jne', 'reg') // company + type dari pilihan user ->addItem([ 'name' => 'Sepatu', 'value' => 350000, 'weight' => 500, 'quantity' => 1, ]) ->referenceId('INV-2025-001') // optional: ID order dari sistem kamu ->orderNote('Jangan dilipat'); // optional // Koordinat origin & destination (opsional tapi disarankan) $request->originCoordinate(-6.2253114, 106.7993735) ->destinationCoordinate(-6.2892700, 106.7749200); // Pengaturan tambahan $request->collectionMethod('pickup') // 'pickup' atau 'drop_off' ->proofOfDelivery(true, 'Tolong foto rumah'); // minta kurir foto resi di lokasi // Dengan asuransi $request->courier('jne', 'reg', 'true'); // COD $request->cashOnDelivery(350000, '7_days'); // jumlah dalam rupiah, tipe COD (opsional) // Kurir dari config — cocok kalau toko sudah lock ke satu kurir (misal kontrak eksklusif) $request->defaultCourier(); // dari BITESHIP_COURIER_COMPANY + BITESHIP_COURIER_TYPE // Shipper branding (override .env default) $request->shipper('Toko Elektronik', '021xxxxxxx', organization: 'PT Toko Jaya'); $response = Biteship::orders()->create($request); // $response->id → Biteship order ID // $response->status → OrderStatus enum // $response->waybill_id → resi kurir (mungkin null saat baru dibuat) // $response->price → ongkir final // $response->raw → raw array dari API
Find, Update, Cancel
// Get detail $order = Biteship::orders()->find($orderId); // Cancel (gunakan reason_code, dan reason_description opsional untuk 'others') $order = Biteship::orders()->cancel($orderId, 'others', 'Pembeli membatalkan'); // Update (misal koreksi alamat sebelum pickup) $order = Biteship::orders()->update($orderId, [ 'destination_address' => 'Jl. Baru No. 5', ]);
OrderStatus Enum
use Aliziodev\Biteship\Enums\OrderStatus; $status = $response->status; $status->label(); // label Bahasa Indonesia $status->isFinal(); // sudah terminal (delivered/cancelled/dll) $status->isSuccess(); // delivered $status->isInTransit(); // sedang dalam perjalanan $status->isProblem(); // on_hold / return_in_transit $status->canCancel(); // masih bisa dicancel via API
14 values: confirmed, scheduled, allocated, picking_up, picked, dropping_off, delivered, on_hold, return_in_transit, returned, rejected, disposed, courier_not_found, cancelled
Tracking
// Track via Biteship order ID $tracking = Biteship::tracking()->trackByOrderId($orderId); // Track via resi + kode kurir (public tracking — tidak perlu order dari Biteship) $tracking = Biteship::tracking()->trackByWaybill('JD000000000', 'jne'); // $tracking->status → TrackingStatus enum // $tracking->waybill_id // $tracking->history → Collection<TrackingHistory> foreach ($tracking->history as $h) { // $h->status, $h->note, $h->updatedAt }
TrackingStatus memiliki 13 values (sama dengan OrderStatus minus cancelled — tracking tidak expose cancelled karena order sudah tidak ada di kurir).
Couriers
$couriers = Biteship::couriers()->all(); // Collection of array: // available_collection_method // available_for_cash_on_delivery // available_for_proof_of_delivery // available_for_instant_waybill_id // courier_name // courier_code // courier_service_name // courier_service_code // tier // description // service_type // shipping_type // shipment_duration_range // shipment_duration_unit
Label Print
Buat label pengiriman dari raw response order (zero API call tambahan).
$label = Biteship::label()->fromRaw($response->raw); // Render HTML string $html = Biteship::label()->render($label); // Return HTTP response siap di-print di browser return Biteship::label()->response($label);
Catatan: sender_name dan sender_phone di label menggunakan data shipper (branding toko) jika tersedia, dengan fallback ke origin. sender_address selalu dari origin.
Webhook & Events
Biteship mengirim webhook saat status order berubah. Package ini menangani routing, verifikasi signature, dan dispatch Laravel Event secara otomatis.
Route
Webhook URL sudah di-register otomatis:
POST /biteship/webhook
Daftarkan URL ini di Biteship Dashboard → Webhook Settings.
Signature Verification
Set di Biteship Dashboard pada bagian Custom Headers:
BITESHIP_WEBHOOK_SIGNATURE_KEY=X-Biteship-Signature BITESHIP_WEBHOOK_SIGNATURE_SECRET=rahasia-kamu
Jika kedua nilai ini kosong, verifikasi dilewati (cocok untuk development).
Listen Events
Daftarkan listener di AppServiceProvider atau EventServiceProvider:
use Aliziodev\Biteship\Events\OrderStatusUpdated; use Aliziodev\Biteship\Events\OrderWaybillUpdated; use Aliziodev\Biteship\Events\OrderPriceUpdated; Event::listen(OrderStatusUpdated::class, HandleBiteshipStatus::class); Event::listen(OrderWaybillUpdated::class, HandleBiteshipWaybill::class); Event::listen(OrderPriceUpdated::class, HandleBiteshipPrice::class);
Event Payloads
OrderStatusUpdated — dipicu saat status order berubah (order.status):
public function handle(OrderStatusUpdated $event): void { $payload = $event->payload; $payload->order_id; // string $payload->status; // OrderStatus enum $payload->waybill_id; // ?string $payload->courier_tracking_id; // ?string $payload->raw; // array mentah dari webhook }
OrderWaybillUpdated — dipicu saat resi diterbitkan (order.waybill_id):
public function handle(OrderWaybillUpdated $event): void { $payload = $event->payload; $payload->order_id; // string $payload->waybill_id; // string $payload->courier_tracking_id; // ?string }
OrderPriceUpdated — dipicu saat harga final dikonfirmasi (order.price):
public function handle(OrderPriceUpdated $event): void { $payload = $event->payload; $payload->order_id; // string $payload->price; // int (rupiah) $payload->insurance_fee; // int (rupiah) }
Respons 401 dikembalikan jika signature tidak valid. Respons 422 dikembalikan jika event tidak dikenal.
HasBiteship Trait (Optional DB Layer)
Simpan state pengiriman langsung di model Order kamu tanpa perlu menulis query manual.
Setup
Saat biteship:install, pilih Yes untuk optional DB layer. Ini akan mempublish migration:
php artisan migrate
Tambahkan trait ke model Order:
use Aliziodev\Biteship\Support\HasBiteship; class Order extends Model { use HasBiteship; }
Methods
// Simpan response Biteship setelah order dibuat $order->createBiteshipOrder($response); // Sync status terbaru dari Tracking API ke DB (idempoten — skip jika status sama) $order->syncBiteshipStatus(); // Cancel order via API + update status di DB $order->cancelBiteship('Pembeli request cancel'); // Generate label dari raw_response di DB (zero API call) $label = $order->generateLabel(); return Biteship::label()->response($label); // Relasi ke tabel biteship_orders $order->biteshipOrder; // BiteshipOrder model
Integrasi Webhook + HasBiteship
Pattern umum: update status DB langsung dari webhook tanpa API call tambahan.
class HandleBiteshipStatus { public function handle(OrderStatusUpdated $event): void { BiteshipOrder::where('biteship_order_id', $event->payload->order_id) ->update(['biteship_status' => $event->payload->status->value]); } }
Atau gunakan syncBiteshipStatus() jika ingin selalu pull dari Tracking API (lebih akurat tapi ada API call tambahan):
class HandleBiteshipStatus { public function handle(OrderStatusUpdated $event): void { $order = Order::whereHas('biteshipOrder', fn ($q) => $q->where('biteship_order_id', $event->payload->order_id) )->first(); $order?->syncBiteshipStatus(); } }
Testing / Mock Mode
Gunakan MockBiteshipClient untuk testing tanpa hit API:
use Aliziodev\Biteship\Http\MockBiteshipClient; // Bind di AppServiceProvider (untuk env testing) atau test setUp $this->app->bind( \Aliziodev\Biteship\Contracts\BiteshipClientInterface::class, MockBiteshipClient::class, );
Mock tersedia untuk semua endpoint: rates, orders, tracking, couriers, dan locations.
Configuration
php artisan vendor:publish --tag=biteship-config
Key konfigurasi di config/biteship.php:
| Key | Default | Keterangan |
|---|---|---|
api_key |
env('BITESHIP_API_KEY') |
API key Biteship |
cache.enabled |
true |
Cache hasil ongkir |
cache.ttl |
900 |
TTL dalam detik (15 menit) |
cache.store |
null |
Cache store (null = default) |
cache.prefix |
'biteship' |
Prefix cache key |
webhook.path |
'biteship/webhook' |
Path endpoint webhook |
webhook.signature_key |
null |
Nama custom header signature |
webhook.signature_secret |
null |
Nilai secret untuk verifikasi |
default_origin |
[...] |
Data origin default (dari env) |
default_courier |
[...] |
Kurir default untuk order & rates (dari env) |
default_shipper |
[...] |
Data shipper branding (dari env) |
label.view |
'biteship::label' |
Blade view untuk label print |
Exceptions
| Exception | Keterangan |
|---|---|
AuthenticationException |
API key salah atau tidak aktif (401) |
ValidationException |
Request tidak valid (422) |
RateLimitException |
Rate limit tercapai (429) |
ApiException |
Error lain dari Biteship API |
WebhookSignatureException |
Signature header tidak cocok |
InvalidWebhookEventException |
Event webhook tidak dikenal |
License
MIT — Alizio
统计信息
- 总下载量: 12
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-05-01