ux2dev/speedy
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
ux2dev/speedy 适用场景与选型建议
ux2dev/speedy 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 34 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 04 月 30 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 ux2dev/speedy 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 ux2dev/speedy 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 34
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 34
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-04-30