Search by

wop-platform / wop-php-sdk

im47cn

WOP merchant PHP SDK: protocol core (sign/digest/digital envelope) + pluggable HTTP transport adapters

Package info

github.com/wop-platform/wop-php-sdk

Language:Python

pkg:composer/wop-platform/wop-php-sdk

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.2.0 2026-08-31 06:43 UTC

This package is auto-updated.

Last update: 2026-09-16 07:46:51 UTC


README

Packagist PHP 8.2+ Release CI License: MIT Coverage Gherkin CodeRabbit Pull Request Reviews

WOP · 万联易达开放平台 官方 PHP SDK —— 协议与黄金向量真源:wop-specs

WOP 网关商户侧官方 PHP 客户端库:封装协议核心(结构化签名 / 内容摘要 / L2 数字信封 / 验签解密), 商户无需理解 canonicalRequest、套件推导与线上字节格式即可安全对接。

快速开始

composer require wop-platform/wop-php-sdk
use Wop\Sdk\WopClient;
use Wop\Sdk\WopConfig;
use Wop\Sdk\Transport\CurlTransport;

$client = new WopClient(new WopConfig(
    appKey:         'app_10012481831',
    securityReq:    'WOP-RSA3072-SHA256',
    privateKey:     $merchantPrivateKeyPemOrBase64,   // 己方私钥(出向加签 / 入向 DEK 解包)
    peerPublicKey:  $platformPublicKeyPemOrBase64,    // 平台公钥(响应/回调验签 / DEK 包装)
));

// 1. 构造请求(L0 明文 / L2 数字信封),得到可直接发送的 RequestDraft
$draft = $client->buildRequest('POST', '/gateway/logistics.order.query', $jsonBody, 'L2');

// 2. 任选 Transport 发送(curl 扩展适配器 / Guzzle peer 适配器,或自带 HTTP 栈)
$transport = new CurlTransport();
$response  = $transport->send($draft->method, 'https://gateway.example.com' . $draft->path,
                              $this->toHeaderLines($draft->headers), $draft->wireBody);

// 3. 验证平台响应(验签 → digest 复核 → DEK 解包 → alg 族比对 → 解密,顺序固定)
$result = $client->verifyResponse(
    $this->toArray($response->headers), $response->body, '/gateway/logistics.order.query');
if ($result->ok) {
    $plaintext = $result->plaintext;
}

RequestDraft::headers 为 name => value 关联数组;curl 需要 "$name: $value" 头行、 Guzzle 适配器直接接受数组——GuzzleTransport::send() 内部完成转换。

密钥准备(D12 分发契约)

用途 格式
RSA 公钥(SPKI) X.509 SubjectPublicKeyInfo DER 的 Base64 单行,或等价 PEM(-----BEGIN PUBLIC KEY----- 包装)
RSA 私钥(PKCS8) PKCS#8 DER 的 Base64 单行,或等价 PEM(-----BEGIN PRIVATE KEY----- 包装)
  • SDK 对 PEM / Base64 单行两种入参等价接受(内部 phpseclib 解析并缓存);
  • 签名算法族:WOP-RSA3072-SHA256 / WOP-RSA4096-SHA256(SHA256withRSA,PKCS#1 v1.5);
  • SM2 公钥(04‖X‖Y 65B)与 d 32B 标量属国密套件,本版不支持(见下方路线图)。

L0 + L2 示例

L0(明文 + 摘要 + 签名):buildRequest(method, path, $body, 'L0') —— 有 body 时自动生成 x-wop-content-digest: sha-256 <小写hex>(恰一空格),无 body(GET)则该头缺席; digest 与 x-wop-appkey/x-wop-nonce/x-wop-timestamp 一并进入 signedHeaders(协议不变式 I1)。

L2(全文数字信封):buildRequest(method, path, $body, 'L2') —— CSPRNG 生成 32B DEK + 12B IV,AES-256-GCM 加密 body(密文 = ciphertext||tag 尾拼), DEK 载荷 AES-256-GCM$b64url(key)$b64url(iv) 经 RSA-OAEP(显式双 SHA-256 + 空 label)包装后 置于 x-wop-encrypt: L2;dek=<b64url>;digest 改为对密文载体字节计算(D2)。 L2 wire body 恒为 JSON 信封 {"encrypted":"<base64url 密文>"}(与网关 CryptoFilter 线上契约一致); 入向解密时提取 encrypted 字段(容忍未知字段),非法结构/缺字段按协议类错误明确拒绝。

回调验证:verifyCallback($headers, $body, $callbackUrl) —— canonical URI 取回调 URL 的 path。

// 商户回调接收端(POST)
$result = $client->verifyCallback($headers, $body, 'https://merchant.example.com/callback/notify');

向量自测(conformance)

composer install
vendor/bin/phpunit                  # 139 项断言全绿(含黄金向量套件)
  • tests/fixtures/crypto-vectors.json 与网关真源逐字节一致(CI 校验);
  • RSA 签名(3072/4096)、OAEP 解包(含 mgf1-sha1 陷阱密文必须拒)、AES-256-GCM、 digest 头组装均为字节级断言;formatRules 负向量(双空格/大写 hex/跨族标签/带 = base64url)全量消费;
  • 覆盖率(xdebug --path-coverage):行 100.00% / 分支 100.00%(CI 门禁 ≥98%)。

错误处理与模糊化(I7)

  • 配置/解析/格式/一致性类错误:抛 Wop\Sdk\WopException,消息语义明确(帮助集成自查);
  • 验签失败与解密失败(GCM tag / DEK 解包):对外文案固定为「签名验证失败」「解密失败」, 不区分原因细节,防 padding-oracle 式信息泄露;调用方仅见 VerifyResult::reason。

依赖说明

依赖 角色
phpseclib/phpseclib ^3.0 唯一运行时密码库:RSA 签名 + OAEP(必须走它——openssl 扩展 OAEP 的 MGF1 写死 SHA-1,不满足 F2 钉子)
ext-openssl(suggest) L2 信封 AES-256-GCM bulk 加解密(tag 独立出参,本 SDK 完成尾拼)
ext-curl(suggest) CurlTransport 默认适配器
guzzlehttp/guzzle(suggest) GuzzleTransport peer 适配器(不污染核心依赖面)

国密路线图(SM2-SM3 套件)

本版(0.1.0)按 SDK spec §1.2(裁决 Q7)仅支持 RSA 套件;WOP-SM2-SM3 配置与报文 将明确抛出 WopException("SM2-SM3 套件暂未支持,见 README 路线图")。

计划中的国密支持(SM3withSM2 裸 r‖s 64B / SM4-GCM / SM2 C1C3C2)将以纯 PHP 实现交付, 黄金向量 fixture 已全量就位(tests/fixtures/crypto-vectors.json 的 SM 段当前作为 "必须拒"负测试消费),届时无需变更协议层。欢迎在 issue 中反馈需求优先级。

🧩 WOP 生态导航 | Ecosystem

类别 组件
协议与向量真源 wop-specs —— crypto-strategy-spec · wop-sdk-spec · 黄金测试向量
官方 SDK(六语言) Java · Go · Python · PHP · .NET · TypeScript
浏览器工作台 wop-web-tools —— 密钥生成 · 报文联调 · 国密 · 六语言代码片段
Agent 技能包 wop-skills —— 零代码调用 · 联调对拍 · 62 错误码排错
平台服务(企业内部) 统一接入网关 · 核心逻辑服务 · 回调服务 · 开发者门户 · 文档中心

License

MIT(见 LICENSE)。