whalesky-labs/jd-sdk-php

京东开放平台 PHP SDK,支持京准通、POP、自营、V1 和 SP API

Maintainers

Package info

github.com/whalesky-labs/jd-sdk-php

pkg:composer/whalesky-labs/jd-sdk-php

Transparency log

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.0.1 2026-08-12 07:02 UTC

This package is auto-updated.

Last update: 2026-08-12 07:05:18 UTC


README

WhaleSky Labs

JD Open Platform SDK for PHP

京东开放平台 PHP SDK

京准通、POP 与自营 · V1 与 SP · Guzzle 7 · Swoole 协程连接池

PHP >= 7.4 Composer package Swoole supported

WhaleSky Labs 维护

whalesky-labs/jd-sdk-php 是面向京东开放平台的 PHP Composer SDK,统一封装京准通、POP、自营三类官方下载包,并同时提供 V1 与 SP 两套接口的调用入口。

本项目不是京东官方发布的 Composer 包。京东官方下载包中的 Request、Domain、Api、Model 及安全 SDK 是接口定义的权威来源;本项目负责命名空间隔离、统一配置、Guzzle 传输、异常转换、重试和 Swoole 协程连接池。

当前三类官方 SDK 的生成版本如下。京东下载包未提供独立的语义化版本号,因此这里以压缩包文件名中的生成日期标识当前导入快照:

SDK 类型 V1 生成版本 SP 生成版本
京准通 2026-08-10 2026-08-10
POP 2026-08-06 2026-08-06
自营 2026-08-09 2026-08-09

运行要求

  • PHP 7.4 或更高版本
  • cURL 扩展
  • JSON 扩展
  • OpenSSL 扩展
  • Composer 2

主要运行时依赖为 Guzzle 7。使用安全 SDK 时,需要根据京东安全 SDK 的运行方式提供 APCu 或 Yac 缓存。Swoole/Hyperf 支持是可选能力,不影响 PHP-FPM 或普通 CLI 环境使用。

安装

项目尚未发布稳定版本到 Packagist。当前可将 GitHub 仓库注册为 Composer VCS 源后安装 dev-main

composer config repositories.jd-sdk-php vcs https://github.com/whalesky-labs/jd-sdk-php.git
composer require whalesky-labs/jd-sdk-php:dev-main

dev-main 是开发分支,不提供稳定版本兼容承诺。生产项目应提交自身的 composer.lock,并在升级前审查变更;需要严格复现时可在业务项目中锁定已审核的提交引用。

发布稳定版本到 Packagist 后,安装命令将简化为:

composer require whalesky-labs/jd-sdk-php

Swoole 或 Hyperf 项目建议额外安装:

composer require hyperf/guzzle

接口覆盖与选择

当前代码由以下官方下载快照导入:

接口类型 协议 调用入口 当前覆盖 官方代码文件
京准通 V1 $sdk->jzt()->v1() 318 个 Request 740
京准通 SP $sdk->jzt()->sp() 3 个 operation 35
POP V1 $sdk->pop()->v1() 564 个 Request 961
POP SP $sdk->pop()->sp() 135 个 operation 1,114
自营 V1 $sdk->selfOperated()->v1() 577 个 Request 961
自营 SP $sdk->selfOperated()->sp() 135 个 operation 1,235

此外导入 67 个安全 SDK 文件。来源压缩包名称、由本项目计算的 SHA-256 文件校验值、文件数量及兼容修复记录见 resources/sdk-manifest.json

京准通、POP 与自营不是同一套接口。三类下载包的 Request、Api 和 Model 覆盖均不同,因此项目保持六套独立命名空间,不对官方接口做合并或推断。

命名空间映射如下:

接口集 根命名空间
京准通 V1 JdSdk\Api\Jzt\V1
京准通 SP JdSdk\Api\Jzt\Sp
POP V1 JdSdk\Api\Pop\V1
POP SP JdSdk\Api\Pop\Sp
自营 V1 JdSdk\Api\SelfOperated\V1
自营 SP JdSdk\Api\SelfOperated\Sp
安全 SDK ACES

定位接口类

接口权限、字段定义和业务规则以京东开放平台文档为准。本项目不维护另一份接口目录,避免它与官方下载包产生版本漂移。

V1 可以按官方 API 方法名搜索 Request。例如定位 jingdong.pop.order.get

rg -l 'jingdong\.pop\.order\.get' src/Api/Pop/V1/Request

SP 可以按官方 operation 名或资源路径搜索 Api。例如定位 listOrders

rg -l 'function listOrders\(' src/Api/Pop/Sp

搜索前应先确定店铺类型和协议;不要因为 POP 与自营存在同名类,就假设其参数、响应或权限完全相同。

快速开始

<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use JdSdk\JdSdk;

$sdk = new JdSdk(
    $appKey,
    $appSecret,
    ['access_token' => $accessToken]
);

建议按京东开放平台应用维度复用 JdSdk 实例。凭证和 Access Token 应由业务系统、密钥管理服务或配置中心提供,不要写入仓库。

调用京准通 V1

use JdSdk\Api\Jzt\V1\Request\JztFindAllSubPinsRequest;

$result = $sdk->jzt()->v1()->callApi(
    JztFindAllSubPinsRequest::class
);

京准通通常使用独立应用凭证和授权 Token。不要使用同一个 JdSdk 实例同时承载京准通和其他应用的不同授权上下文。

调用京准通 SP

use JdSdk\Api\Jzt\Sp\sp\data\v0\api\ReportSchemasApi;
use JdSdk\Api\Jzt\Sp\sp\data\v0\model\GetReportSchemasRequest;

$request = $sdk->jzt()->sp()->model(GetReportSchemasRequest::class, [
    'subject_info' => $subjectInfo,
]);

$response = $sdk->jzt()->sp()->callApi(
    ReportSchemasApi::class,
    'getReportSchemas',
    [$reportSchemaId, $request]
);

调用 POP V1

use JdSdk\Api\Pop\V1\Request\PopOrderGetRequest;

$result = $sdk->pop()->v1()->callApi(
    PopOrderGetRequest::class,
    [
        'order_id' => '1234567890',
        'optional_fields' => 'orderInfo,venderInfo',
    ]
);

V1 调用返回数组。京东返回 error_response 时,SDK 抛出统一的 JdSdk\Core\Exception\ApiException

调用 POP SP

use JdSdk\Api\Pop\Sp\sp\order\v0\api\OrdersApi;
use JdSdk\Api\Pop\Sp\sp\order\v0\model\ListOrdersRequest;

$request = $sdk->pop()->sp()->model(ListOrdersRequest::class, [
    'page' => 1,
    'page_size' => 20,
    'start_time' => strtotime('-1 day') * 1000,
    'end_time' => time() * 1000,
]);

$response = $sdk->pop()->sp()->callApi(
    OrdersApi::class,
    'listOrders',
    [$request]
);

SP 返回类型以官方生成方法为准;该示例返回官方响应 Model。使用 callApi() 时,官方 SP ApiException 会转换为本项目统一的 ApiException

自营接口的调用方式相同,只需切换到 selfOperated() 并使用 JdSdk\Api\SelfOperated 命名空间下的官方类。

公共入口

本项目维护的封装层提供以下主要入口:

方法 返回值 用途
JdSdk::jzt() ShopClient 选择京准通接口集
JdSdk::pop() ShopClient 选择 POP 接口集
JdSdk::selfOperated() ShopClient 选择自营接口集
ShopClient::v1() V1Client 选择 V1 协议
ShopClient::sp() SpClient 选择 SP 协议
JdSdk::config() JdConfig 读取或调整 SDK 配置
JdSdk::security() ACES\TDEClient 创建京东安全 SDK 客户端
JdSdk::poolStats() array 获取当前进程的客户端与连接池统计
JdSdk::shutdown() void 释放静态客户端和 SDK 连接池

V1 的主要调用方法是 callApi()request()domain()execute();SP 的主要调用方法是 callApi()model()api()configuration()。官方 Request、Domain、Api 和 Model 的公共方法不由本项目重新定义。

V1 API

参数映射

V1Client::callApi() 根据 Request setter 注入参数。以下两种形式都会匹配 setOrderId()

['orderId' => '1234567890']
['order_id' => '1234567890']

无法匹配 setter 的参数会交给官方 Request 的 putOtherTextParam()。字段名称、必填条件和业务含义仍以京东开放平台文档为准。

构造官方 Request

需要调用官方 Request 的额外方法时,可以先创建对象再执行:

use JdSdk\Api\SelfOperated\V1\Request\AigcCopilotTestHelloRequest;

$request = $sdk->selfOperated()->v1()->request(
    AigcCopilotTestHelloRequest::class,
    ['param1' => 'hello']
);

$request->setVersion('2.0');
$result = $sdk->selfOperated()->v1()->execute($request);

单次调用需要覆盖默认 Access Token 时,可传入 callApi() 的第三个参数:

$result = $sdk->pop()->v1()->callApi(
    PopOrderGetRequest::class,
    ['order_id' => '1234567890'],
    $requestAccessToken
);

构造 Domain 对象

$caller = $sdk->pop()->v1()->domain(
    'WareStockSkuFivestarSet\\CallerParam'
);

$caller->setPin('example-pin');

V1 Request 和 Domain 必须属于当前选择的 POP 或自营命名空间;跨类型执行会抛出 InvalidApiException

SP API

Model 与 Api

SP 保留 OpenAPI Generator 生成的 Model、Api、方法名和返回类型。model() 接受完整类名或相对于当前 SP 根命名空间的类名:

$request = $sdk->pop()->sp()->model(
    'sp\\address\\v0\\model\\ListAreasRequest',
    ['level' => 2, 'parent_id' => 10]
);

推荐通过 callApi() 调用,以获得统一异常转换。需要直接访问官方 Api 对象时,可以使用:

use JdSdk\Api\Pop\Sp\sp\address\v0\api\AreasApi;

$api = $sdk->pop()->sp()->api(AreasApi::class);
$response = $api->listAreas($request);

直接调用官方 Api 对象时,异常类型遵循该官方命名空间,而不是本项目统一异常类型。

异步与并发

官方 SP Api 提供异步方法。通过 callApi() 调用异步方法时,Promise 中的官方 SP ApiException 同样会被转换为本项目的统一 ApiException

use GuzzleHttp\Promise\Utils;

$promises = [
    'first' => $sdk->pop()->sp()->callApi(
        OrdersApi::class,
        'listOrdersAsync',
        [$firstRequest]
    ),
    'second' => $sdk->pop()->sp()->callApi(
        OrdersApi::class,
        'listOrdersAsync',
        [$secondRequest]
    ),
];

$responses = Utils::unwrap($promises);

V1 官方协议只提供同步 execute()。V1 并发应由业务任务、进程或 Swoole 协程调度。

配置

$sdk = new JdSdk($appKey, $appSecret, [
    'access_token' => $accessToken,
    'v1_server_url' => 'https://api.jd.com/routerjson',
    'sp_server_url' => 'https://api-cn.jd.com/rest',
    'timeout' => [
        'connect' => 5000,
        'read' => 15000,
    ],
    'retry' => [
        'enable' => true,
        'max_times' => 2,
        'interval' => 200,
        'non_idempotent' => false,
    ],
    'pool' => [
        'max_connections' => 50,
        'max_idle_time' => 60,
        'wait_timeout' => 3.0,
    ],
    'debug' => false,
    'user_agent' => 'MyApplication/1.0',
]);
配置项 类型 默认值 说明
access_token string '' 默认 Access Token
v1_server_url string https://api.jd.com/routerjson V1 网关地址
sp_server_url string https://api-cn.jd.com/rest SP 网关地址
timeout.connect int 5000 连接超时,单位毫秒
timeout.read int 15000 请求总超时,单位毫秒
retry.enable bool true 是否启用重试中间件
retry.max_times int 2 最大重试次数,不含首次请求
retry.interval int 200 首次重试间隔,单位毫秒;后续指数退避
retry.non_idempotent bool false 是否允许重试非幂等请求
pool.max_connections int 50 单 Worker 最大连接数,范围 1–1000
pool.max_idle_time int 60 空闲连接保留时间,单位秒;0 表示不按空闲时间淘汰
pool.wait_timeout float 3.0 等待可用连接的超时,单位秒
debug bool false 是否启用 Guzzle 调试输出
user_agent string JdSdk-PHP/1.0 HTTP User-Agent

配置对象支持有限的链式调整:

$sdk->config()
    ->setAccessToken($newAccessToken)
    ->setTimeout(3000, 10000)
    ->setRetryConfig(true, 2, 200, false)
    ->setDebug(false);

应在首次调用 pop()selfOperated() 前完成应用凭证、网关和 SP 配置。已经创建的官方 SP Configuration 对象不会因后续配置变更而自动重建。

异常处理

use JdSdk\Core\Exception\ApiException;
use JdSdk\Core\Exception\ConfigurationException;
use JdSdk\Core\Exception\HttpException;
use JdSdk\Core\Exception\InvalidApiException;
use JdSdk\Api\Pop\V1\Request\PopOrderGetRequest;

try {
    $result = $sdk->pop()->v1()->callApi(
        PopOrderGetRequest::class,
        ['order_id' => '1234567890']
    );
} catch (ApiException $exception) {
    $apiCode = $exception->getApiCode();
    $responseData = $exception->getResponseData();
} catch (HttpException $exception) {
    $statusCode = $exception->getStatusCode();
    $responseBody = $exception->getResponseBody();
} catch (InvalidApiException | ConfigurationException $exception) {
    $message = $exception->getMessage();
}
异常 含义
ApiException V1 error_response 或经 callApi() 转换后的 SP 官方 API 异常
HttpException V1 网络失败、非 2xx HTTP 响应或无法解析的响应
InvalidApiException 类、方法或 POP/自营接口集不匹配
ConfigurationException 凭证、URL、超时、重试或连接池配置无效

不要依赖异常消息解析错误码;应使用 getApiCode()getResponseData()getStatusCode()getResponseBody()

重试语义

默认仅在同时满足以下条件时重试:

  1. 请求方法为 GETHEADOPTIONSDELETE
  2. 发生连接异常,或响应状态为 HTTP 429 / 5xx;
  3. 尚未达到 retry.max_times

V1 和多数写接口使用 POST,因此默认不会自动重试。只有在业务方确认接口及请求具备幂等性,并能接受重复提交风险时,才应设置:

['retry' => ['non_idempotent' => true]]

SDK 不生成业务幂等键,也不能替代订单、发货、退款等业务操作自身的幂等控制。

并发与 Swoole

HTTP 客户端在实际发送请求时检测运行环境,因此 SDK 实例可以在 Worker 启动阶段创建,在后续协程中复用。

运行环境 传输策略
Hyperf PoolHandler 可用 使用 Hyperf 原生连接池
协程 Handler 可用 使用 SDK Worker 级池包装协程 Guzzle Client
原生 Swoole 使用 SDK Worker 级池;非阻塞网络需要应用正确启用 runtime hook 或协程 Handler
PHP-FPM / 普通 CLI 按传输配置复用进程级 Guzzle Client

池化客户端会在同步或异步请求完成后归还客户端。连接池用于控制长生命周期 Worker 内的客户端数量并降低文件描述符耗尽风险,但池大小仍需根据并发量、上游限流和 Worker 数量进行容量规划。

查看运行环境和连接池状态:

$stats = JdSdk::poolStats();

返回值包含:

  • environmentfpmswoole-syncswoole-coroutine
  • standard_clients:当前进程内标准客户端数量
  • native_pools:Hyperf 原生池客户端数量
  • pools:SDK 连接池统计,包括活跃、空闲、等待和累计请求数

Worker 退出、长生命周期进程重载或测试隔离时,应释放静态客户端和连接池:

JdSdk::shutdown();

签名机制

V1 与 SP 均直接使用京东官方下载包中的签名逻辑。当前官方算法为:

  1. 按参数名排序;
  2. 拼接 appSecret + 参数名和值 + appSecret
  3. 计算 MD5;
  4. 将结果转为大写。

该签名不是 HMAC-SHA256。应用密钥不得写入日志、异常上下文或版本库。

安全 SDK

官方下载包中的安全 SDK 通过 ACES 命名空间提供敏感数据加解密能力:

$securityClient = $sdk->security();

也可以为安全 SDK 单独指定 Access Token:

$securityClient = $sdk->security($securityAccessToken);

安全 SDK 会按京东官方逻辑请求并缓存安全凭证,需要相应应用权限、网络访问和 APCu/Yac 缓存。它与 V1/SP 请求签名是两项不同能力。

更新官方 SDK

不要直接修改以下生成目录:

  • src/Api/Jzt
  • src/Api/Pop
  • src/Api/SelfOperated
  • src/Security

这些目录会在下次导入时整体替换。更新官方下载包后执行:

php scripts/import-official-sdk.php \
  --jzt-dir=/path/to/jd-api-sdk-php-jzt \
  --pop-dir=/path/to/jd-api-sdk-php-pop \
  --self-operated-dir=/path/to/jd-api-sdk-php-self-operated

composer dump-autoload -o
composer test

导入器执行以下工作:

  1. 从三个下载目录发现 V1、SP 和安全 SDK 压缩包;
  2. 将京准通、POP、自营的 V1 与 SP 导入独立命名空间;
  3. 校验三份安全 SDK 压缩包哈希相同后只导入一份;
  4. 应用已知且形态受约束的生成器兼容修复;
  5. 原子替换生成目录并重建 manifest。

导入器不会修改官方下载目录,也不会把官方类转换为自定义 REST 定义。若压缩包结构、安全 SDK 哈希或已知缺陷形态发生变化,导入应失败并由维护者审查,而不是静默选择或宽泛改写。

所有兼容修复必须由导入器生成,并记录在 resources/sdk-manifest.json;不要在导入后手工修补生成文件。

项目结构

src/
├── Api/
│   ├── Jzt/{V1,Sp}/
│   ├── Pop/{V1,Sp}/
│   └── SelfOperated/{V1,Sp}/
├── Core/
│   ├── Client/
│   ├── Config/
│   ├── Exception/
│   ├── Http/
│   ├── Support/
│   └── Swoole/
├── Security/
└── JdSdk.php
  • src/Apisrc/Security:由官方下载包生成,不作为手工维护区。
  • src/Coresrc/JdSdk.php:本项目维护的稳定封装层。
  • scripts/import-official-sdk.php:可重复执行的官方 SDK 导入器。
  • resources/sdk-manifest.json:来源和兼容修复审计记录。
  • tests:封装层、官方调用主链和导入结果测试。

项目没有额外的 Official/ 目录。ApiSecurity 已清楚表达上游代码职责,再增加中间层不会改善更新边界。

版本与变更

稳定版本计划遵循 Semantic Versioning。每次发布的新增能力、行为变更、兼容性说明、修复和安全更新记录在 CHANGELOG.md;尚未发布的内容保留在 Unreleased 章节。

更新官方 SDK 时,除更新 Changelog 外,还必须提交重新生成的 resources/sdk-manifest.json,以便审计上游压缩包、文件数量和兼容修复。

CI 与发布

CImain 分支推送、Pull Request 和手动触发时运行,使用 PHP 7.4–8.4 验证 Composer 元数据、依赖安装和 PHPUnit 测试。PHP 7.4 使用最低兼容依赖,其他版本分别解析其最高兼容依赖;代码风格在独立的 PHP 7.4 Job 中检查。

本项目维护的 PHP 代码使用 PHP CS Fixer 统一格式,并添加项目来源头注释。检查或修复代码风格:

composer cs-check
composer cs-fix

格式化范围仅包括 .php-cs-fixer.phpsrc/Coresrc/JdSdk.phpscriptstests。官方下载生成的 src/Apisrc/Security 不纳入格式化,避免修改上游代码和影响后续导入更新。

Release 仅通过 GitHub Actions 手动触发,提供以下参数:

参数 说明
mode auto 自动计算版本;manual 使用手动版本
version 手动版本号,例如 5.0.0;仅 manual 模式必填
publish_release 是否创建 vX.Y.Z Tag 并发布 GitHub Release
source_branch 发布来源分支,默认 main

首次使用 auto 发布时版本为 1.0.0;后续基于最新 vX.Y.Z Tag 自动递增补丁版本。手动版本接受 5.0.0v5.0.0,最终统一创建 v5.0.0 形式的 Tag。

发布工作流会校验 Unreleased、Composer 元数据并运行全部测试,GitHub Release 正文直接取自 Changelog 的 Unreleased 章节,版本号仅用于 Tag 和 Release 名称。publish_release=false 时仅执行发布预检,不创建 Tag 或 GitHub Release;Packagist 应通过 GitHub Webhook 或 Packagist GitHub Service 跟踪正式 Tag。

测试

安装开发依赖并执行默认单元测试:

composer install
composer test

所有测试统一位于 tests/:默认离线测试位于其功能子目录,真实接口测试位于 tests/Integration/。两类测试使用独立 PHPUnit 配置,默认测试会显式排除真实接口目录。

默认测试使用 Mock HTTP 响应,不读取真实应用凭证,也不会访问京东网关。真实接口验收只调用查询类接口:

cp .env.example .env
# 在 .env 中填写测试目标及对应应用凭证
composer test-integration

JD_INTEGRATION_TARGETS 支持以逗号分隔的 jzt-v1jzt-sppop-v1pop-spself-operated-v1self-operated-sp。每个目标仅在显式选中时运行;选中京准通目标需填写 JD_JZT_APP_KEYJD_JZT_APP_SECRETJD_JZT_ACCESS_TOKEN,选中 POP 或自营目标需填写对应前缀的凭证。jzt-sp 还需提供报表 Schema ID 和主体信息。项目的 .env 仅供真实接口测试使用并已被 Git 忽略,凭证不得写入 .env.example 或提交到仓库;也可以直接注入同名进程环境变量,其优先级高于文件。

jzt-v1 调用 jingdong.jzt.findAllSubPins 查询当前授权京准通账号的子账号,jzt-sp 查询指定报表 Schema;pop-v1 调用 jingdong.seller.vender.info.get 获取当前授权店铺信息。V1 测试运行时会打印京东完整响应 JSON;输出不包含 App Secret、Access Token 或请求签名,但可能包含真实账号或店铺信息,请勿粘贴到公开环境。

集成测试不属于默认 composer test 或公开 CI,因为它依赖应用类型、接口授权、有效 Token 和京东网关可用性。未设置测试目标、目标名称无效、所选目标缺少凭证、鉴权失败或接口返回失败时,composer test-integration 都会失败;未选中的接口集显示为跳过,失败信息会脱敏已配置的应用凭证。

使用支持覆盖率的 PHP 运行时生成报告,例如:

phpdbg -qrr vendor/bin/phpunit --coverage-text

当前基线使用 PHP 8.1.31 和 PHPUnit 9.6.35:

  • 47 项测试
  • 150 个断言
  • srcscriptstests 下共 5,147 个 PHP 文件通过语法检查

当前 PHP CLI 未加载覆盖率驱动,因此本次没有沿用变更前的覆盖率百分比。生成覆盖率时只计算 src/Coresrc/JdSdk.php;官方生成的 5,046 个 API 文件不计入覆盖率分母。测试使用代表性 V1/SP 接口验证签名、请求构造、同步/异步调用和异常转换。

贡献

提交 Pull Request 前请遵守以下边界:

  1. 不手工编辑 src/Apisrc/Security;上游兼容变更应修改导入器并重建 manifest。
  2. 京准通、POP、自营及 V1、SP 必须保持独立,除非有官方下载包和测试证明可以安全合并。
  3. 新增或修改封装行为时补充对应测试。
  4. 不提交应用密钥、Access Token、业务数据、日志、缓存或官方下载压缩包。
  5. 提交前运行 composer validate --strictcomposer test

License

本项目维护的封装层在 Composer 元数据中声明为 MIT License。随官方下载包导入的生成代码、安全 SDK、证书及相关资产仍受京东官方适用条款约束;使用和再分发前请自行确认相应授权条件。

“京东”及相关标识归其权利人所有。本项目为社区维护项目,不代表京东官方背书、认证或支持。