Shipping Service Package for Laravel with Strategy and Adapter patterns

Maintainers

Package info

github.com/linh20000/shipping-workflow

pkg:composer/shippable/hub

Statistics

Installs: 10

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.4 2026-06-22 02:53 UTC

This package is auto-updated.

Last update: 2026-06-22 02:57:33 UTC


README

Laravel Package cung cấp dịch vụ vận chuyển qua Strategy + Adapter Pattern, hỗ trợ GHN, GHTK và ViettelPost.

Cài đặt

1. Thêm local path (development)

// composer.json của dự án
{
    "repositories": [
        {
            "type": "path",
            "url": "../package-php/shipping",
            "options": { "symlink": true }
        }
    ],
    "require": {
        "wf/shipping": "*"
    }
}
composer require wf/shipping --ignore-platform-reqs

2. Publish config (tuỳ chọn)

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

Package sẽ tự động load config mặc định nếu bạn chưa publish. Chỉ publish khi muốn tuỳ chỉnh.

3. Thêm biến môi trường vào .env

# GHN
GHN_TOKEN=your-ghn-token
GHN_BASE_URL=https://dev-online-gateway.ghn.vn/shiip/public-api

# GHTK
GHTK_TOKEN=your-ghtk-token
GHTK_B2C_TOKEN=your-ghtk-b2c-token
GHTK_ENDPOINT=https://services.giaohangtietkiem.vn

# ViettelPost
VIETTELPOST_TOKEN=your-vtp-token
VIETTELPOST_ENDPOINT=https://partner.viettelpost.vn

Cách sử dụng

Package sử dụng Factory Pattern để bạn có thể tuỳ ý gọi dịch vụ ở bất cứ đâu (Controller, Job, Command) mà không bị phụ thuộc vào HTTP Request.

Cách 1 — Inject qua Constructor (Recommended)

use Wf\Shipping\ShippingFactory;
use Wf\Shipping\DTO\StandardShippingPayload;

class OrderController extends Controller
{
    public function __construct(
        private readonly ShippingFactory $shippingFactory
    ) {}

    public function createOrder(Request $request)
    {
        $payload = StandardShippingPayload::fromArray($request->validated());
        
        // Bạn có thể chọn hãng vận chuyển động từ request hoặc fix cứng
        $method = $request->input('service_method', 'express'); // express, standard, fast
        $strategy = $this->shippingFactory->make($method);
        
        $result = $strategy->createOrder($payload);

        return response()->json($result);
    }
}

Cách 2 — Resolve thủ công qua app()

use Wf\Shipping\ShippingFactory;

$factory = app(ShippingFactory::class);
$ghnStrategy = $factory->make('express');
$ghtkStrategy = $factory->make('standard');

Cách 3 — Dùng trực tiếp SDK thô

use Wf\Shipping\GHN;
use Wf\Shipping\GHTK;
use Wf\Shipping\ViettelPost;

$ghn  = new GHN(config('shipping.ghn.token'));
$resp = $ghn->getProvince(); // array

$ghtk = new GHTK(config('shipping.ghtk.token'));
$fee  = $ghtk->caculateFee([...]); // json string

$vtp  = new ViettelPost(config('shipping.viettelpost.token'));
$provinces = $vtp->getProvice(); // json string

Cấu trúc package

src/
├── config/
│   └── shipping.php          ← Cấu hình endpoint, token, service_method
├── Contracts/
│   └── ShippingStrategyInterface.php  ← Interface chính dự án inject
├── DTO/
│   └── StandardShippingPayload.php    ← DTO chuẩn hoá payload đầu vào
├── Adapters/
│   ├── GHNAdapter.php        ← Map DTO → format GHN
│   ├── GHTKAdapter.php       ← Map DTO → format GHTK
│   └── ViettelPostAdapter.php← Map DTO → format VTP
├── Strategies/
│   ├── GHNStrategy.php       ← Xử lý logic GHN, gọi GHN SDK
│   ├── GHTKStrategy.php      ← Xử lý logic GHTK, gọi GHTK SDK
│   └── ViettelPostStrategy.php
├── GHN.php                   ← SDK gọi GHN API thật
├── GHTK.php                  ← SDK gọi GHTK API thật
├── ViettelPost.php            ← SDK gọi ViettelPost API thật
└── Providers/
    └── ShippingServiceProvider.php

Thêm hãng vận chuyển mới

  1. Tạo src/Adapters/NewCarrierAdapter.php — map DTO sang format của hãng.
  2. Tạo src/Strategies/NewCarrierStrategy.php — gọi SDK qua Adapter.
  3. Thêm vào ShippingServiceProvider::register():
    new NewCarrierStrategy(token: config('shipping.newcarrier.token')),
  4. Thêm config vào src/config/shipping.php.

Interface cần implement

interface ShippingStrategyInterface
{
    public function getServiceMethodName(): string;
    public function createOrder(StandardShippingPayload $payload): array;
    public function calculateFee(StandardShippingPayload $payload): array;
    public function cancelOrder(string $orderCode): array;
    public function getOrderDetail(string $orderCode): array;
    public function getProvince(): array;
    public function getDistrict(int $provinceId): array;
    public function getWard(int|string $districtId): array;
}