定制 aliziodev/laravel-biteship 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

aliziodev/laravel-biteship

最新稳定版本:v1.4.0

Composer 安装命令:

composer require aliziodev/laravel-biteship

包简介

Laravel package for Biteship shipping aggregator API integration

README 文档

README

Tests Latest Version on Packagist Total Downloads PHP Version Laravel Version Ask DeepWiki

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

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-05-01

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固