Skip to content

feat(alipay): 支付宝 OpenAPI V3 支持(阶段一) - #1191

Open
yansongda wants to merge 6 commits into
masterfrom
feat/alipay-v3
Open

feat(alipay): 支付宝 OpenAPI V3 支持(阶段一)#1191
yansongda wants to merge 6 commits into
masterfrom
feat/alipay-v3

Conversation

@yansongda

Copy link
Copy Markdown
Owner

背景

新增支付宝 OpenAPI V3 API 支持:租户配置 version: v3 后,pos/scan/query/refund/cancel/close 六个服务端接口与 callback() 走 V3 管道(RESTful /v3/ 路径 + JSON 报文 + HTTP 头签名),支持公钥/证书双模式。复用仓库内微信 V3 已验证的「头签名 + JSON + Shortcut 管道」架构,V2/V3 通过 Provider 入口按配置分流共存,存量 V2 用户零影响、调用代码零改动

交付物(6 commits)

  • feat(alipay): V3 配置与 Provider 版本分流脚手架AlipayConfig 新增 version(默认 v2,值域校验)与 alipay_public_key,validateRequired() v2/v3 双模式分支;Provider\Alipay 新增 V3_URL/V3_SHORTCUTS 常量与 __call()/appCallback() 版本分流;AlipayTrait 新增 V3 URL/签名/验签/毫秒时间戳方法;测试密钥与双租户
  • feat(alipay): V3 请求签名与雷达构造插件AddPayloadSignaturePlugin(Authorization: ALIPAY-SHA256withRSA,组串顺序 app_id → app_cert_sn → nonce → timestamp,毫秒时间戳)+ AddRadarPlugin(alipay-request-id 无条件携带、alipay-app-auth-token 按需)
  • feat(alipay): V3 响应验签回调验签与 Provider 回调分流VerifySignaturePlugin(HTTP 200 强制验签/其余有签才验,毫秒 ±300s,证书模式 alipay-sn 严格匹配)+ ResponsePlugin + CallbackPlugin + getV3CallbackParams();回调验签无条件强制、无跳过口子
  • feat(alipay): V3 查询退款撤销关单链路 — Query/Refund/Cancel/Close 四组插件与 Shortcut
  • feat(alipay): V3 付款码与扫码支付链路 — Pos/Precreate 插件与 Shortcut(notify_url per-plugin 注入)
  • docs(alipay): V3 使用文档与变更日志web/docs/v3/alipay/v3/ 7 页(配置/六接口/回调/逃生通道/事件差异/encrypt_key 提示/升级注意)+ sidebar + CHANGELOG Unreleased

契约依据

核心契约对照官方 SDK 一手源码(alipay-sdk-php-all v3/src/)逐项核实:authString 组串顺序与格式(逐字符)、毫秒时间戳(请求/响应头)、alipay-request-id、无 root-cert-sn、错误响应体(OAS CommonErrorType)、沙箱域名。

重要契约裁决:支付宝 trade 异步通知(notify_url)经官方文档与 SDK 源码双源互证,确认仍为 V2 form 参数格式(非 V3 header 签名),故 V3\CallbackPlugin 按 V2 参数格式验签(除 sign/sign_type 字典序组串 + RSA2,不校验 SN),应答为字面量 success

测试

  • 全量 composer test:1458 tests, 3499 assertions 全绿(基线 1374,存量测试行零修改)
  • composer analyse(PHPStan)0 errors;composer cs-fix 0 files
  • 端到端(mock HTTP):V3 租户 scan()/v3/alipay/trade/precreate 且响应验签通过(公钥/证书双模式);回调对合法签名验签通过,篡改后/时间戳超窗后抛 InvalidSignException
  • 未覆盖:真实商户/沙箱联调(需线上凭证,属发布前人工步骤)

已知限制(阶段一范围)

  • 页面类接口(web/h5/app/mini)V3 版不支持(V3 租户调用抛明确异常,提示 _config 指向 V2 租户)
  • 不含 AES-128-CBC 通知加解密(encrypt_key,文档已提示勿配置)、transfer、证书自动轮换
  • 不修改任何 V2 现有行为;零新 Composer 依赖

注:本 PR 与历史 PR #1133(旧尝试)无关联。

- AlipayConfig 新增 version/alipayPublicKey 字段及 v2/v3 双模式校验(证书模式五件套/公钥模式三要素),version 非法值抛 InvalidConfigException
- Provider/Alipay 新增 V3_URL(沙箱 http://openapi.sandbox.dl.alipaydev.com)与 V3_SHORTCUTS 白名单,__call 按 _config 租户 version 分流(shortcut 大小写归一化,白名单外抛 InvalidParamsException),appCallback V3 暂不支持
- AlipayTrait 追加 V3 方法:getAlipayV3Url/getAlipayV3Authorization(authString 顺序 app_id→app_cert_sn→nonce→timestamp,毫秒时间戳)/verifyAlipayV3Sign(公钥 PEM 包装/证书模式)/verifyAlipayV3Timestamp(毫秒换算 ±300s)
- 复用 Exception::PARAMS_METHOD_NOT_SUPPORTED(9211),Exception.php 零改动
- 测试材料 tests/Cert/alipay-v3/(测试密钥对+自签证书),TestCase 追加 alipay-v3/alipay-v3-cert 租户,新增 21 个用例
- 机械性修正:cs-fixer 按 ordered_class_elements 将既有 loadAlipayServiceProvider 移至 protected 区(方法体零改动);getAlipayV3Timestamp 毫秒计算显式类型转换(对齐官方 getCurrentMilis 语义)
- VerifySignaturePlugin:V3 同步响应验签(200 强制/其余有签才验、毫秒时间戳 ±300s、证书模式 alipay-sn 严格匹配)
- ResponsePlugin:非 2xx 抛 InvalidResponseException,错误体 code/message 并入消息
- CallbackPlugin:异步通知按 V2 form 参数格式验签(除 sign/sign_type 字典序组串,不校验 SN、无时间戳环节),payload/destination 为完整通知参数
- Provider callback():v3 分流 + getV3CallbackParams(),CallbackReceived 事件分发 ServerRequest
@netlify

netlify Bot commented Sep 2, 2026

Copy link
Copy Markdown

Deploy Preview for pay-yansongda ready!

Name Link
🔨 Latest commit bbab584
🔍 Latest deploy log https://app.netlify.com/projects/pay-yansongda/deploys/6a97e19a5d1487000871f4a4
😎 Deploy Preview https://deploy-preview-1191--pay-yansongda.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying pay with  Cloudflare Pages  Cloudflare Pages

Latest commit: bbab584
Status: ✅  Deploy successful!
Preview URL: https://fd746048.pay-1bj.pages.dev
Branch Preview URL: https://feat-alipay-v3.pay-1bj.pages.dev

View logs

@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.41691% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.29%. Comparing base (f453cce) to head (bbab584).

Files with missing lines Patch % Lines
src/Plugin/Alipay/V3/VerifySignaturePlugin.php 96.42% 1 Missing ⚠️
src/Provider/Alipay.php 95.83% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1191      +/-   ##
============================================
+ Coverage     97.17%   97.29%   +0.11%     
- Complexity     1717     1801      +84     
============================================
  Files           475      492      +17     
  Lines          8789     9128     +339     
============================================
+ Hits           8541     8881     +340     
+ Misses          248      247       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant