All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 46s
5.2 KiB
5.2 KiB
MODIFIED Requirements
Requirement: 微信支付配置动态加载
微信支付配置 MUST 从数据库动态加载(通过 tb_wechat_config 表),替代原有的环境变量静态配置。Payment 实例按需创建,支持请求级 AppID 覆盖(区分公众号和小程序)。
Scenario: 从数据库加载配置创建 Payment 实例
- WHEN 支付流程需要使用微信支付
- THEN 系统从 Redis 缓存或数据库加载当前生效的微信参数配置(
is_active=true且provider_type=wechat) - THEN 系统使用配置中的
wx_mch_id、wx_api_v3_key、wx_cert_content、wx_key_content、wx_serial_no创建payment.Payment实例 - THEN 证书内容从 Base64 解码后写入临时文件供 PowerWeChat SDK 使用
本次留桩:WechatPayJSAPI 和 WechatPayH5 方法保留现有 wechatPayment 单例调用,添加 TODO 注释标记后续替换点。
Scenario: 无生效微信支付配置时拒绝支付
- WHEN 系统查询不到
is_active=true的微信参数配置,或生效配置的provider_type非wechat - THEN 微信支付相关接口返回错误
{
"code": 1175,
"data": null,
"msg": "当前无可用的支付渠道",
"timestamp": "2026-03-16T10:00:00+08:00"
}
Scenario: 公众号 JSAPI 支付使用公众号 AppID
POST /api/h5/orders/:id/wechat-pay/jsapi
Authorization: Bearer {token}
Content-Type: application/json
请求体
{
"openid": "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
openid |
string | ✅ | 用户在公众号下的 OpenID |
- THEN 系统使用配置中的
oa_app_id(公众号 AppID)创建支付订单 - THEN Payer OpenID 为用户在该公众号下的 OpenID
成功响应 200 OK(本次留桩,返回结构不变)
{
"code": 0,
"data": {
"prepay_id": "wx26112221580621e9b071c00d9e093b0000",
"pay_config": {
"appId": "wx1234567890abcdef",
"timeStamp": "1711411341",
"nonceStr": "abc123",
"package": "prepay_id=wx26112221580621e9b071c00d9e093b0000",
"signType": "RSA",
"paySign": "..."
}
},
"msg": "success",
"timestamp": "2026-03-16T10:00:00+08:00"
}
Scenario: 小程序支付使用小程序 AppID
- WHEN 用户在小程序中发起支付
- THEN 系统在调用
JSAPITransaction时将 AppID 覆盖为配置中的miniapp_app_id - THEN Payer OpenID 为用户在该小程序下的 OpenID
Scenario: 微信 H5 支付
POST /api/h5/orders/:id/wechat-pay/h5
Authorization: Bearer {token}
Content-Type: application/json
请求体
{
"scene_info": {
"payer_client_ip": "14.23.150.211",
"h5_info": {
"type": "Wap"
}
}
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
scene_info.payer_client_ip |
string | ✅ | 用户终端 IP |
scene_info.h5_info.type |
string | ❌ | 场景类型:iOS / Android / Wap |
成功响应 200 OK
{
"code": 0,
"data": {
"h5_url": "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx..."
},
"msg": "success",
"timestamp": "2026-03-16T10:00:00+08:00"
}
Scenario: 配置缺失时系统正常启动
- WHEN 系统启动时数据库中无微信参数配置或配置不完整
- THEN 系统正常启动,支付功能降级为仅支持钱包/线下
- THEN 系统记录 WARN 日志"无可用微信参数配置,第三方支付功能不可用"
Requirement: 微信支付回调按配置验签
系统 SHALL 接收并处理微信支付成功通知。回调验签 MUST 使用订单关联的支付配置(而非当前生效配置)。
Scenario: 接收到合法的支付成功通知
POST /api/callback/wechat-pay
Content-Type: 由微信服务器决定
无需认证
- WHEN 微信回调端点收到支付成功通知
- THEN 系统解析通知中的商户订单号(
out_trade_no) - THEN 按订单号前缀分发(
ORD→ 套餐订单,CRCH→ 资产充值,ARCH→ 代理充值) - THEN 查询对应表记录,通过
payment_config_id加载对应的微信参数配置 - THEN 使用该配置的凭证通过 PowerWeChat SDK 验证回调签名
- THEN 调用对应 Service 的 HandlePaymentCallback
- THEN 返回成功响应
成功响应
{
"code": 0,
"data": {
"return_code": "SUCCESS"
},
"msg": "success",
"timestamp": "2026-03-16T10:00:00+08:00"
}
Scenario: 订单关联的配置已被软删除
- WHEN 回调到达,但
payment_config_id对应的配置已被软删除 - THEN 系统使用
GetByIDUnscoped加载该配置(软删除不影响回调处理) - THEN 正常完成验签和订单处理
Scenario: 重复回调幂等处理
- WHEN 微信多次发送同一订单的支付成功通知
- THEN 系统通过幂等检查识别已支付,直接返回成功响应
Scenario: 回调签名验证失败
- WHEN 签名无效或被篡改
- THEN PowerWeChat SDK 自动拒绝,系统记录 ERROR 日志,返回 HTTP 400
Scenario: 订单号不存在
- WHEN 回调中的商户订单号在系统中不存在
- THEN 系统记录 ERROR 日志,返回失败响应