承接 ux2dev/speedy 相关项目开发

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

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

ux2dev/speedy

最新稳定版本:0.9.0alpha

Composer 安装命令:

composer require ux2dev/speedy

包简介

Framework-agnostic PHP SDK for Speedy courier (api.speedy.bg)

README 文档

README

Warning: Developer testing version of the library — use at your own risk.

Framework-agnostic PHP SDK for the Speedy courier API at https://api.speedy.bg/v1. Covers all ten Speedy service groups (Shipment, Print, Track, Pickup, Location, Calculate, Client, Validation, Services, Payments) as resource methods that return typed Response DTOs. Works with plain PHP or Laravel.

Requirements

  • PHP 8.2 or higher
  • JSON extension
  • A PSR-18 HTTP client and PSR-17 request/stream factories (Guzzle provides both)

Installation

composer require ux2dev/speedy

Quick start — plain PHP

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\HttpFactory;
use Ux2Dev\Speedy\Config\SpeedyConfig;
use Ux2Dev\Speedy\Speedy;
use Ux2Dev\Speedy\Dto\Request\Shipment\CreateShipmentRequest;

$config = new SpeedyConfig(
    userName: 'your-username',
    password: 'your-password',
    language: 'EN',
);

$factory = new HttpFactory();
$speedy  = new Speedy($config, new Client(), $factory, $factory);

$response = $speedy->shipment()->create(new CreateShipmentRequest(
    ref1: 'ORDER-1234',
));

echo $response->id;

Quick start — Laravel

The package auto-registers SpeedyServiceProvider and a Speedy facade.

Publish the config:

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

Set credentials in .env:

SPEEDY_USERNAME=demo
SPEEDY_PASSWORD=secret
SPEEDY_LANGUAGE=EN

Use the facade:

use Ux2Dev\Speedy\Laravel\Facades\Speedy;
use Ux2Dev\Speedy\Dto\Request\Shipment\CreateShipmentRequest;

$response = Speedy::shipment()->create(new CreateShipmentRequest(ref1: 'ORDER-1234'));

Multiple accounts

return [
    'default'  => 'main',
    'accounts' => [
        'main'   => ['user_name' => env('SPEEDY_USERNAME'),   'password' => env('SPEEDY_PASSWORD'),   'language' => 'EN'],
        'second' => ['user_name' => env('SPEEDY_USERNAME_2'), 'password' => env('SPEEDY_PASSWORD_2'), 'language' => 'BG'],
    ],
];
Speedy::account('second')->shipment()->create($req);

account() returns an immutable clone — the default stays untouched.

How the SDK is organised

Layer Location Purpose
Config Ux2Dev\Speedy\Config\SpeedyConfig Base URL + credentials, validated, password redacted
Transport Ux2Dev\Speedy\Http\SpeedyTransport PSR-18 dispatch, auth auto-injection, error mapping
Request DTOs Ux2Dev\Speedy\Dto\Request\{Group}\*Request Generated, toArray()
Response DTOs Ux2Dev\Speedy\Dto\Response\{Group}\*Response Generated, fromArray()
Model DTOs Ux2Dev\Speedy\Dto\Model\* Shared entities (Address, Office, Site, ...)
Resources Ux2Dev\Speedy\Resources\{Group} Generated, one method per operation
Root client Ux2Dev\Speedy\Speedy Aggregator
Laravel Ux2Dev\Speedy\Laravel\* Service Provider + multi-account Manager + Facade

Generated from bin/endpoints.json (a hand-curated catalog of 45 operations) plus bin/schemas/ (a snapshot of https://api.speedy.bg/v1/schema) by bin/generate.php.

Resources

10 generated resource groups, mirroring Speedy's service organisation:

shipment      print        track       pickup
location      calculate    clients     validation
services      payments

Every resource method takes a Request DTO plus optional $language and $clientSystemId overrides, and returns a typed Response DTO:

$speedy->shipment()->create($createShipmentRequest);
$speedy->shipment()->cancel($cancelShipmentRequest);
$speedy->location()->findOffice($findOfficeRequest);
$speedy->track()->track($trackRequest);
$speedy->print()->voucher($printVoucherRequest);

Print Service

Print endpoints currently follow Speedy's documented JSON envelope (PrintVoucherResponse carries the PDF as a pdf byte-array). When you need the binary path directly, the SDK exposes Ux2Dev\Speedy\Http\PrintResult with body, contentType, filename, plus bytes(), saveTo($path), isPdf(), and isZpl() helpers.

Errors

Successful return paths always carry a "good" Response DTO. When the API responds with a populated error field, the transport throws Ux2Dev\Speedy\Exception\ApiException with structured fields (apiCode, apiMessage, context, errorId, component, httpStatus). The raw response body is intentionally not retained on the exception — the structured fields cover every documented error attribute, and dropping the body avoids leaking PII or credentials into logs and traces.

Exception When
ConfigurationException Invalid SpeedyConfig input or unknown Laravel account
TransportException PSR-18 client failure (network, timeout)
InvalidResponseException Empty body, malformed JSON, or unexpected envelope
ApiException Speedy returned a non-null error field

All extend SpeedyException.

Regenerating the SDK

composer speedy:fetch-schemas    # snapshots /v1/schema into bin/schemas
composer speedy:generate         # rewrites src/Resources, src/Dto, and the Speedy/Facade method blocks
vendor/bin/pest                  # snapshot test catches drift

Testing

composer install
vendor/bin/pest
XDEBUG_MODE=coverage vendor/bin/pest --coverage --min=100

The suite mocks a PSR-18 client to exercise every resource method end-to-end.

License

MIT

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-30

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固