承接 laraditz/courier 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

laraditz/courier

Composer 安装命令:

composer require laraditz/courier

包简介

A unified interface for multiple courier and shipping carrier services in Laravel.

README 文档

README

A unified interface for multiple courier and shipping carrier services in Laravel.

Overview

This package provides a driver-based abstraction layer for courier integrations. Define your shipments once using strongly-typed DTOs — the driver handles the carrier-specific API calls and returns normalized results.

Each carrier ships as a separate Composer package. Install only what you need.

Requirements

  • PHP 8.1+
  • Laravel 10, 11, 12, or 13

Installation

composer require laraditz/courier

The service provider is auto-discovered. Publish the config:

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

Available Drivers

Package Carrier
laraditz/courier-sfexpress SF Express

Configuration

config/courier.php:

return [
    'default' => env('COURIER_DRIVER', 'sfexpress'),

    'drivers' => [
        'sfexpress' => [
            'account' => env('SFEXPRESS_ACCOUNT'),
            'key'     => env('SFEXPRESS_KEY'),
            'secret'  => env('SFEXPRESS_SECRET'),
            'sandbox' => env('SFEXPRESS_SANDBOX', false),
        ],
    ],
];

Available Methods

Method Parameters Returns Description
createShipment ShipmentPayload $payload ShipmentResult Book a new shipment and get a waybill number
track string $trackingNumber TrackingResult Get current status and full tracking history
getRates RatePayload $payload RateCollection Fetch available service options and prices for a route
cancelShipment string $waybillNumber CancelResult Cancel an existing shipment
getLabel string $waybillNumber LabelResult Retrieve the shipping label (base64 PDF or ZPL)
getAvailability AvailabilityPayload $payload ServiceCollection List services available between two locations

Result DTOs

DTO Key Properties
ShipmentResult waybillNumber, status, estimatedDelivery, meta()
TrackingResult waybillNumber, status, estimatedDelivery, events[], meta()
TrackingEvent timestamp, location, description, status
RateCollection items[]RateOption
RateOption serviceCode, serviceName, price, currency, estimatedDays
CancelResult success, message, meta()
LabelResult waybillNumber, format, content, meta()
ServiceCollection items[]ServiceOption
ServiceOption code, name, description, estimatedDays

Payload DTOs

DTO Properties
ShipmentPayload sender: Address, recipient: Address, parcel: Parcel, serviceCode: string, remarks: ?string
RatePayload origin: Location, destination: Location, parcel: Parcel
AvailabilityPayload origin: Location, destination: Location
Address name, phone, email, line1, line2, line3, city, state, postcode, country
Location postcode, city, state, country
Parcel weight, length, width, height, declaredValue, description, quantity

Usage

Create a Shipment

use Laraditz\Courier\Facades\Courier;
use Laraditz\Courier\DTOs\Shared\Address;
use Laraditz\Courier\DTOs\Shared\Parcel;
use Laraditz\Courier\DTOs\Payloads\ShipmentPayload;

$result = Courier::createShipment(new ShipmentPayload(
    sender: new Address(
        name: 'Raditz Farhan',
        phone: '+60123456789',
        email: null,
        line1: 'No 1 Jalan Test',
        line2: null,
        line3: null,
        city: 'Kuala Lumpur',
        state: 'Wilayah Persekutuan',
        postcode: '50000',
        country: 'MY',
    ),
    recipient: new Address(/* ... */),
    parcel: new Parcel(
        weight: 1.5,
        length: 20.0,
        width: 15.0,
        height: 10.0,
        declaredValue: 100.0,
        description: 'Goods',
        quantity: 1,
    ),
    serviceCode: 'STANDARD',
));

$result->waybillNumber; // 'SF1234567890'
$result->status;        // 'pending'

Track a Shipment

$result = Courier::track('SF1234567890');

$result->waybillNumber;  // 'SF1234567890'
$result->status;         // 'in_transit'
$result->events;         // TrackingEvent[]

foreach ($result->events as $event) {
    $event->timestamp;   // Carbon
    $event->location;    // 'Kuala Lumpur Hub'
    $event->description; // 'Package picked up'
    $event->status;      // 'picked_up'
}

Get Rates

use Laraditz\Courier\DTOs\Shared\Location;
use Laraditz\Courier\DTOs\Payloads\RatePayload;

$rates = Courier::getRates(new RatePayload(
    origin: new Location('50000', 'Kuala Lumpur', 'Wilayah Persekutuan', 'MY'),
    destination: new Location('10000', 'Georgetown', 'Pulau Pinang', 'MY'),
    parcel: new Parcel(1.5, 20, 15, 10, 100, 'Goods', 1),
));

foreach ($rates->items as $option) {
    $option->serviceCode;    // 'STANDARD'
    $option->serviceName;    // 'Standard Delivery'
    $option->price;          // 12.50
    $option->currency;       // 'MYR'
    $option->estimatedDays;  // 3
}

Other Operations

// Cancel
$result = Courier::cancelShipment('SF1234567890');
$result->success;  // true

// Get label (returns base64-encoded PDF or ZPL)
$result = Courier::getLabel('SF1234567890');
$result->format;   // 'pdf'
$result->content;  // base64 string

// Check service availability by route
$services = Courier::getAvailability(new AvailabilityPayload(
    origin: new Location('50000', 'Kuala Lumpur', 'Wilayah Persekutuan', 'MY'),
    destination: new Location('10000', 'Georgetown', 'Pulau Pinang', 'MY'),
));

Switching Drivers

// Use a specific driver explicitly
Courier::driver('sfexpress')->track('SF1234567890');

Testing

Use Courier::fake() to mock courier calls in tests:

use Laraditz\Courier\Facades\Courier;

$fake = Courier::fake();

// Your code under test runs here...
$this->service->bookShipment($order);

$fake->assertShipmentCreated(1);
$fake->assertShipmentCreated(fn ($payload) => $payload->serviceCode === 'STANDARD');
$fake->assertTracked('SF1234567890');
$fake->assertCancelled('SF1234567890');
$fake->assertRatesFetched();
$fake->assertLabelFetched('SF1234567890');
$fake->assertNothingSent();

Provide preset responses:

use Laraditz\Courier\DTOs\Results\ShipmentResult;

$fake = Courier::fake([
    'createShipment' => new ShipmentResult('CUSTOM-001', 'pending', null),
]);

Normalized Status Vocabulary

All drivers map their carrier-specific statuses to these values:

Status Meaning
pending Shipment created, not yet picked up
picked_up Collected by courier
in_transit Moving through the network
out_for_delivery On the delivery vehicle
delivered Successfully delivered
failed_delivery Delivery attempt failed
returned Returned to sender
cancelled Shipment cancelled
unknown Status not recognized

Building a Custom Driver

Implement Laraditz\Courier\Contracts\CourierDriver and register it:

// In your ServiceProvider
$this->app->make('courier')->extend('mycarrier', function ($app, $config) {
    return new MyCarrierDriver($config);
});

License

MIT

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-18