## 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** 微信支付相关接口返回错误

```json
{
  "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
```

**请求体**

```json
{
  "openid": "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"
}
```

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `openid` | string | ✅ | 用户在公众号下的 OpenID |

- **THEN** 系统使用配置中的 `oa_app_id`（公众号 AppID）创建支付订单
- **THEN** Payer OpenID 为用户在该公众号下的 OpenID

**成功响应 `200 OK`**（本次留桩，返回结构不变）

```json
{
  "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
```

**请求体**

```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`**

```json
{
  "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** 返回成功响应

**成功响应**

```json
{
  "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 日志，返回失败响应
