Files
huang 817d0d6e04
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 46s
更新openspec
2026-03-17 14:22:01 +08:00

29 KiB
Raw Blame History

ADDED Requirements

Requirement: 微信参数配置 CRUD 管理

系统 SHALL 支持平台用户对微信支付参数配置的完整生命周期管理,包括创建、列表查询、详情查询、更新、删除。每个配置包含完整的支付身份信息(渠道凭证 + 公众号 OAuth 信息 + 小程序 OAuth 信息)。


Scenario: 创建微信直连支付配置

WHEN 平台用户调用 POST /api/admin/wechat-configsprovider_typewechat提供名称、公众号信息、小程序信息、商户号、API V3 密钥、证书内容Base64、私钥内容Base64、证书序列号、回调地址

THEN 系统创建配置记录,is_active 默认为 false,返回完整配置信息(敏感字段脱敏)

请求
POST /api/admin/wechat-configs
Authorization: Bearer {token}
Content-Type: application/json
{
  "name": "微信直连主配置",
  "description": "生产环境微信直连支付配置",
  "provider_type": "wechat",
  "oa_app_id": "wx1234567890abcdef",
  "oa_app_secret": "abcdef1234567890abcdef1234567890",
  "oa_token": "mytoken123",
  "oa_aes_key": "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG",
  "oa_oauth_redirect_url": "https://example.com/oauth/callback",
  "miniapp_app_id": "wx9876543210fedcba",
  "miniapp_app_secret": "fedcba0987654321fedcba0987654321",
  "wx_mch_id": "1234567890",
  "wx_api_v3_key": "your32charv3keyhere1234567890abc",
  "wx_api_v2_key": "your32charv2keyhere1234567890abc",
  "wx_cert_content": "BASE64_ENCODED_CERT_CONTENT_HERE",
  "wx_key_content": "BASE64_ENCODED_KEY_CONTENT_HERE",
  "wx_serial_no": "ABCDEF1234567890ABCDEF1234567890ABCDEF12",
  "wx_notify_url": "https://example.com/api/payment/wechat/notify"
}
请求字段说明
字段 类型 必填 说明
name string 配置名称,最长 100 字符
description string 配置描述,最长 500 字符
provider_type string 渠道类型,枚举值:wechat(微信直连)、fuiou(富友)
oa_app_id string 公众号 AppID
oa_app_secret string 公众号 AppSecret
oa_token string 公众号消息校验 Token
oa_aes_key string 公众号消息加解密 Key
oa_oauth_redirect_url string 公众号 OAuth 回调地址
miniapp_app_id string 小程序 AppID
miniapp_app_secret string 小程序 AppSecret
wx_mch_id string provider_type=wechat 时必填 微信商户号
wx_api_v3_key string provider_type=wechat 时必填 API V3 密钥32字符
wx_api_v2_key string API V2 密钥32字符
wx_cert_content string provider_type=wechat 时必填 商户证书内容Base64 编码)
wx_key_content string provider_type=wechat 时必填 商户私钥内容Base64 编码)
wx_serial_no string provider_type=wechat 时必填 商户证书序列号
wx_notify_url string provider_type=wechat 时必填 微信支付回调地址
成功响应
{
  "code": 0,
  "data": {
    "id": 1,
    "name": "微信直连主配置",
    "description": "生产环境微信直连支付配置",
    "provider_type": "wechat",
    "is_active": false,
    "oa_app_id": "wx1234567890abcdef",
    "oa_app_secret": "abcd***7890",
    "oa_token": "myto***n123",
    "oa_aes_key": "[已配置]",
    "oa_oauth_redirect_url": "https://example.com/oauth/callback",
    "miniapp_app_id": "wx9876543210fedcba",
    "miniapp_app_secret": "fedc***4321",
    "wx_mch_id": "1234567890",
    "wx_api_v3_key": "your***0abc",
    "wx_api_v2_key": "your***0abc",
    "wx_cert_content": "[已配置]",
    "wx_key_content": "[已配置]",
    "wx_serial_no": "ABCD***EF12",
    "wx_notify_url": "https://example.com/api/payment/wechat/notify",
    "fy_ins_cd": "",
    "fy_mchnt_cd": "",
    "fy_term_id": "",
    "fy_private_key": "[未配置]",
    "fy_public_key": "[未配置]",
    "fy_api_url": "",
    "fy_notify_url": "",
    "created_at": "2026-03-16T10:00:00+08:00",
    "updated_at": "2026-03-16T10:00:00+08:00"
  },
  "msg": "success",
  "timestamp": "2026-03-16T10:00:00+08:00"
}
敏感字段脱敏规则
字段 脱敏规则 示例原值 脱敏后
oa_app_secret 前4位 + *** + 后4位 abcdef1234567890abcdef1234567890 abcd***7890
oa_token 前4位 + *** + 后4位 mytoken123 myto***n123
oa_aes_key [已配置] / [未配置] 任意值 [已配置]
miniapp_app_secret 前4位 + *** + 后4位 fedcba0987654321fedcba0987654321 fedc***4321
wx_api_v3_key 前4位 + *** + 后4位 your32charv3keyhere1234567890abc your***0abc
wx_api_v2_key 前4位 + *** + 后4位 your32charv2keyhere1234567890abc your***0abc
wx_cert_content [已配置] / [未配置] Base64 内容 [已配置]
wx_key_content [已配置] / [未配置] Base64 内容 [已配置]
wx_serial_no 前4位 + *** + 后4位 ABCDEF1234567890ABCDEF1234567890ABCDEF12 ABCD***EF12
fy_private_key [已配置] / [未配置] Base64 内容 [已配置]
fy_public_key [已配置] / [未配置] Base64 内容 [已配置]

Scenario: 创建富友支付配置

WHEN 平台用户调用 POST /api/admin/wechat-configsprovider_typefuiou提供名称、公众号信息、小程序信息、机构号、商户号、终端号、商户私钥Base64、富友公钥Base64、API 地址、回调地址

THEN 系统创建配置记录,is_active 默认为 false

请求
POST /api/admin/wechat-configs
Authorization: Bearer {token}
Content-Type: application/json
{
  "name": "富友支付配置",
  "description": "富友聚合支付渠道配置",
  "provider_type": "fuiou",
  "oa_app_id": "wx1234567890abcdef",
  "oa_app_secret": "abcdef1234567890abcdef1234567890",
  "oa_oauth_redirect_url": "https://example.com/oauth/callback",
  "miniapp_app_id": "wx9876543210fedcba",
  "miniapp_app_secret": "fedcba0987654321fedcba0987654321",
  "fy_ins_cd": "0000100",
  "fy_mchnt_cd": "0000100002000001",
  "fy_term_id": "00000001",
  "fy_private_key": "BASE64_ENCODED_MERCHANT_PRIVATE_KEY",
  "fy_public_key": "BASE64_ENCODED_FUIOU_PUBLIC_KEY",
  "fy_api_url": "https://spay.fuiou.com",
  "fy_notify_url": "https://example.com/api/payment/fuiou/notify"
}
请求字段说明
字段 类型 必填 说明
name string 配置名称,最长 100 字符
description string 配置描述,最长 500 字符
provider_type string 渠道类型,此处为 fuiou
oa_app_id string 公众号 AppID
oa_app_secret string 公众号 AppSecret
oa_token string 公众号消息校验 Token
oa_aes_key string 公众号消息加解密 Key
oa_oauth_redirect_url string 公众号 OAuth 回调地址
miniapp_app_id string 小程序 AppID
miniapp_app_secret string 小程序 AppSecret
fy_ins_cd string provider_type=fuiou 时必填 富友机构号
fy_mchnt_cd string provider_type=fuiou 时必填 富友商户号
fy_term_id string provider_type=fuiou 时必填 富友终端号
fy_private_key string provider_type=fuiou 时必填 商户私钥Base64 编码)
fy_public_key string provider_type=fuiou 时必填 富友公钥Base64 编码)
fy_api_url string provider_type=fuiou 时必填 富友 API 地址
fy_notify_url string provider_type=fuiou 时必填 富友支付回调地址
成功响应
{
  "code": 0,
  "data": {
    "id": 2,
    "name": "富友支付配置",
    "description": "富友聚合支付渠道配置",
    "provider_type": "fuiou",
    "is_active": false,
    "oa_app_id": "wx1234567890abcdef",
    "oa_app_secret": "abcd***7890",
    "oa_token": "",
    "oa_aes_key": "[未配置]",
    "oa_oauth_redirect_url": "https://example.com/oauth/callback",
    "miniapp_app_id": "wx9876543210fedcba",
    "miniapp_app_secret": "fedc***4321",
    "wx_mch_id": "",
    "wx_api_v3_key": "",
    "wx_api_v2_key": "",
    "wx_cert_content": "[未配置]",
    "wx_key_content": "[未配置]",
    "wx_serial_no": "",
    "wx_notify_url": "",
    "fy_ins_cd": "0000100",
    "fy_mchnt_cd": "0000100002000001",
    "fy_term_id": "00000001",
    "fy_private_key": "[已配置]",
    "fy_public_key": "[已配置]",
    "fy_api_url": "https://spay.fuiou.com",
    "fy_notify_url": "https://example.com/api/payment/fuiou/notify",
    "created_at": "2026-03-16T10:00:00+08:00",
    "updated_at": "2026-03-16T10:00:00+08:00"
  },
  "msg": "success",
  "timestamp": "2026-03-16T10:00:00+08:00"
}

Scenario: 创建配置参数校验失败

WHEN 平台用户创建配置时缺少必填字段(如 provider_typewechat 但未提供 wx_mch_id

THEN 系统返回错误码 1001,拒绝创建

请求示例(缺少 wx_mch_id
POST /api/admin/wechat-configs
Authorization: Bearer {token}
Content-Type: application/json
{
  "name": "微信直连配置",
  "provider_type": "wechat",
  "wx_api_v3_key": "your32charv3keyhere1234567890abc"
}
错误响应
{
  "code": 1001,
  "data": null,
  "msg": "参数错误",
  "timestamp": "2026-03-16T10:00:00+08:00"
}

Scenario: 查询配置列表

WHEN 平台用户调用 GET /api/admin/wechat-configs,支持按 provider_typeis_active 筛选,支持分页

THEN 系统返回配置列表,敏感字段脱敏

请求
GET /api/admin/wechat-configs?provider_type=wechat&is_active=false&page=1&page_size=20
Authorization: Bearer {token}
查询参数说明
参数 类型 必填 说明
provider_type string 按渠道类型筛选,枚举值:wechatfuiou
is_active boolean 按激活状态筛选,truefalse
page integer 页码,默认 1
page_size integer 每页条数,默认 20最大 100
成功响应
{
  "code": 0,
  "data": {
    "list": [
      {
        "id": 1,
        "name": "微信直连主配置",
        "description": "生产环境微信直连支付配置",
        "provider_type": "wechat",
        "is_active": false,
        "oa_app_id": "wx1234567890abcdef",
        "oa_app_secret": "abcd***7890",
        "oa_token": "myto***n123",
        "oa_aes_key": "[已配置]",
        "oa_oauth_redirect_url": "https://example.com/oauth/callback",
        "miniapp_app_id": "wx9876543210fedcba",
        "miniapp_app_secret": "fedc***4321",
        "wx_mch_id": "1234567890",
        "wx_api_v3_key": "your***0abc",
        "wx_api_v2_key": "your***0abc",
        "wx_cert_content": "[已配置]",
        "wx_key_content": "[已配置]",
        "wx_serial_no": "ABCD***EF12",
        "wx_notify_url": "https://example.com/api/payment/wechat/notify",
        "fy_ins_cd": "",
        "fy_mchnt_cd": "",
        "fy_term_id": "",
        "fy_private_key": "[未配置]",
        "fy_public_key": "[未配置]",
        "fy_api_url": "",
        "fy_notify_url": "",
        "created_at": "2026-03-16T10:00:00+08:00",
        "updated_at": "2026-03-16T10:00:00+08:00"
      }
    ],
    "total": 1,
    "page": 1,
    "page_size": 20
  },
  "msg": "success",
  "timestamp": "2026-03-16T10:00:00+08:00"
}

Scenario: 查询配置详情

WHEN 平台用户调用 GET /api/admin/wechat-configs/:id

THEN 系统返回配置详情,敏感字段脱敏

请求
GET /api/admin/wechat-configs/1
Authorization: Bearer {token}
成功响应
{
  "code": 0,
  "data": {
    "id": 1,
    "name": "微信直连主配置",
    "description": "生产环境微信直连支付配置",
    "provider_type": "wechat",
    "is_active": false,
    "oa_app_id": "wx1234567890abcdef",
    "oa_app_secret": "abcd***7890",
    "oa_token": "myto***n123",
    "oa_aes_key": "[已配置]",
    "oa_oauth_redirect_url": "https://example.com/oauth/callback",
    "miniapp_app_id": "wx9876543210fedcba",
    "miniapp_app_secret": "fedc***4321",
    "wx_mch_id": "1234567890",
    "wx_api_v3_key": "your***0abc",
    "wx_api_v2_key": "your***0abc",
    "wx_cert_content": "[已配置]",
    "wx_key_content": "[已配置]",
    "wx_serial_no": "ABCD***EF12",
    "wx_notify_url": "https://example.com/api/payment/wechat/notify",
    "fy_ins_cd": "",
    "fy_mchnt_cd": "",
    "fy_term_id": "",
    "fy_private_key": "[未配置]",
    "fy_public_key": "[未配置]",
    "fy_api_url": "",
    "fy_notify_url": "",
    "created_at": "2026-03-16T10:00:00+08:00",
    "updated_at": "2026-03-16T10:00:00+08:00"
  },
  "msg": "success",
  "timestamp": "2026-03-16T10:00:00+08:00"
}
配置不存在时的错误响应
{
  "code": 1170,
  "data": null,
  "msg": "微信支付配置不存在",
  "timestamp": "2026-03-16T10:00:00+08:00"
}

Scenario: 更新配置(非敏感字段)

WHEN 平台用户调用 PUT /api/admin/wechat-configs/:id,仅更新名称、描述、回调地址等非敏感字段

THEN 系统更新对应字段,敏感字段保持不变

请求
PUT /api/admin/wechat-configs/1
Authorization: Bearer {token}
Content-Type: application/json
{
  "name": "微信直连主配置(已更新)",
  "description": "更新后的描述",
  "wx_notify_url": "https://new.example.com/api/payment/wechat/notify"
}
请求字段说明
字段 类型 必填 说明
name string 配置名称
description string 配置描述
oa_app_id string 公众号 AppID
oa_app_secret string 公众号 AppSecret空字符串或不传 = 保留原值;传新值 = 替换
oa_token string 公众号消息校验 Token空字符串或不传 = 保留原值;传新值 = 替换
oa_aes_key string 公众号消息加解密 Key空字符串或不传 = 保留原值;传新值 = 替换
oa_oauth_redirect_url string 公众号 OAuth 回调地址
miniapp_app_id string 小程序 AppID
miniapp_app_secret string 小程序 AppSecret空字符串或不传 = 保留原值;传新值 = 替换
wx_mch_id string 微信商户号
wx_api_v3_key string API V3 密钥;空字符串或不传 = 保留原值;传新值 = 替换
wx_api_v2_key string API V2 密钥;空字符串或不传 = 保留原值;传新值 = 替换
wx_cert_content string 商户证书内容Base64空字符串或不传 = 保留原值;传新值 = 替换
wx_key_content string 商户私钥内容Base64空字符串或不传 = 保留原值;传新值 = 替换
wx_serial_no string 商户证书序列号;空字符串或不传 = 保留原值;传新值 = 替换
wx_notify_url string 微信支付回调地址
fy_ins_cd string 富友机构号
fy_mchnt_cd string 富友商户号
fy_term_id string 富友终端号
fy_private_key string 商户私钥Base64空字符串或不传 = 保留原值;传新值 = 替换
fy_public_key string 富友公钥Base64空字符串或不传 = 保留原值;传新值 = 替换
fy_api_url string 富友 API 地址
fy_notify_url string 富友支付回调地址
成功响应
{
  "code": 0,
  "data": {
    "id": 1,
    "name": "微信直连主配置(已更新)",
    "description": "更新后的描述",
    "provider_type": "wechat",
    "is_active": false,
    "oa_app_id": "wx1234567890abcdef",
    "oa_app_secret": "abcd***7890",
    "oa_token": "myto***n123",
    "oa_aes_key": "[已配置]",
    "oa_oauth_redirect_url": "https://example.com/oauth/callback",
    "miniapp_app_id": "wx9876543210fedcba",
    "miniapp_app_secret": "fedc***4321",
    "wx_mch_id": "1234567890",
    "wx_api_v3_key": "your***0abc",
    "wx_api_v2_key": "your***0abc",
    "wx_cert_content": "[已配置]",
    "wx_key_content": "[已配置]",
    "wx_serial_no": "ABCD***EF12",
    "wx_notify_url": "https://new.example.com/api/payment/wechat/notify",
    "fy_ins_cd": "",
    "fy_mchnt_cd": "",
    "fy_term_id": "",
    "fy_private_key": "[未配置]",
    "fy_public_key": "[未配置]",
    "fy_api_url": "",
    "fy_notify_url": "",
    "created_at": "2026-03-16T10:00:00+08:00",
    "updated_at": "2026-03-16T10:30:00+08:00"
  },
  "msg": "success",
  "timestamp": "2026-03-16T10:30:00+08:00"
}

Scenario: 更新当前生效配置时清除 Redis 缓存

WHEN 平台用户更新的配置 is_active=true(当前生效配置)

THEN 系统更新字段后,主动清除 Redis 缓存 wechat:config:active,使变更即时生效

THEN 响应格式与普通更新相同


Scenario: 更新配置时替换敏感字段

WHEN 平台用户更新配置时,对脱敏字段传入新的明文值(非空字符串、非脱敏格式)

THEN 系统将该字段替换为新值

请求示例(替换 API V3 密钥)
{
  "wx_api_v3_key": "newkey32charsnewkey32charsnewkey"
}

THEN 系统将 wx_api_v3_key 更新为新值,响应中该字段显示脱敏后的新值 newk***ekey


Scenario: 删除未激活的配置

WHEN 平台用户调用 DELETE /api/admin/wechat-configs/:id,且该配置 is_active=false

THEN 系统软删除该配置记录,返回成功

请求
DELETE /api/admin/wechat-configs/1
Authorization: Bearer {token}
成功响应
{
  "code": 0,
  "data": null,
  "msg": "success",
  "timestamp": "2026-03-16T10:00:00+08:00"
}

Scenario: 禁止删除激活中的配置

WHEN 平台用户尝试删除 is_active=true 的配置

THEN 系统返回错误码 1171,拒绝删除

错误响应
{
  "code": 1171,
  "data": null,
  "msg": "不能删除当前生效的支付配置,请先停用",
  "timestamp": "2026-03-16T10:00:00+08:00"
}

Scenario: 禁止删除有在途订单的配置

WHEN 平台用户尝试删除某配置,且存在 payment_config_id 指向该配置的待支付订单

THEN 系统返回错误码 1172,拒绝删除

错误响应
{
  "code": 1172,
  "data": null,
  "msg": "该配置存在未完成的支付订单,暂时无法删除",
  "timestamp": "2026-03-16T10:00:00+08:00"
}

Requirement: 全局唯一激活约束

系统 SHALL 保证任意时刻最多一个支付配置处于激活状态。激活新配置时 MUST 自动停用旧配置。


Scenario: 激活配置

WHEN 平台用户调用 POST /api/admin/wechat-configs/:id/activate

THEN 系统在事务中执行:将所有 is_active=true 的配置设为 false,再将目标配置设为 true

THEN 系统清除 Redis 缓存 wechat:config:active

THEN 系统返回成功,新配置即时生效

请求
POST /api/admin/wechat-configs/1/activate
Authorization: Bearer {token}
成功响应
{
  "code": 0,
  "data": {
    "id": 1,
    "name": "微信直连主配置",
    "description": "生产环境微信直连支付配置",
    "provider_type": "wechat",
    "is_active": true,
    "oa_app_id": "wx1234567890abcdef",
    "oa_app_secret": "abcd***7890",
    "oa_token": "myto***n123",
    "oa_aes_key": "[已配置]",
    "oa_oauth_redirect_url": "https://example.com/oauth/callback",
    "miniapp_app_id": "wx9876543210fedcba",
    "miniapp_app_secret": "fedc***4321",
    "wx_mch_id": "1234567890",
    "wx_api_v3_key": "your***0abc",
    "wx_api_v2_key": "your***0abc",
    "wx_cert_content": "[已配置]",
    "wx_key_content": "[已配置]",
    "wx_serial_no": "ABCD***EF12",
    "wx_notify_url": "https://example.com/api/payment/wechat/notify",
    "fy_ins_cd": "",
    "fy_mchnt_cd": "",
    "fy_term_id": "",
    "fy_private_key": "[未配置]",
    "fy_public_key": "[未配置]",
    "fy_api_url": "",
    "fy_notify_url": "",
    "created_at": "2026-03-16T10:00:00+08:00",
    "updated_at": "2026-03-16T10:05:00+08:00"
  },
  "msg": "success",
  "timestamp": "2026-03-16T10:05:00+08:00"
}
配置不存在时的错误响应
{
  "code": 1170,
  "data": null,
  "msg": "微信支付配置不存在",
  "timestamp": "2026-03-16T10:05:00+08:00"
}

Scenario: 停用配置

WHEN 平台用户调用 POST /api/admin/wechat-configs/:id/deactivate

THEN 系统将该配置 is_active 设为 false

THEN 系统清除 Redis 缓存 wechat:config:active

THEN 此后创建订单时仅支持钱包支付或线下支付

请求
POST /api/admin/wechat-configs/1/deactivate
Authorization: Bearer {token}
成功响应
{
  "code": 0,
  "data": {
    "id": 1,
    "name": "微信直连主配置",
    "description": "生产环境微信直连支付配置",
    "provider_type": "wechat",
    "is_active": false,
    "oa_app_id": "wx1234567890abcdef",
    "oa_app_secret": "abcd***7890",
    "oa_token": "myto***n123",
    "oa_aes_key": "[已配置]",
    "oa_oauth_redirect_url": "https://example.com/oauth/callback",
    "miniapp_app_id": "wx9876543210fedcba",
    "miniapp_app_secret": "fedc***4321",
    "wx_mch_id": "1234567890",
    "wx_api_v3_key": "your***0abc",
    "wx_api_v2_key": "your***0abc",
    "wx_cert_content": "[已配置]",
    "wx_key_content": "[已配置]",
    "wx_serial_no": "ABCD***EF12",
    "wx_notify_url": "https://example.com/api/payment/wechat/notify",
    "fy_ins_cd": "",
    "fy_mchnt_cd": "",
    "fy_term_id": "",
    "fy_private_key": "[未配置]",
    "fy_public_key": "[未配置]",
    "fy_api_url": "",
    "fy_notify_url": "",
    "created_at": "2026-03-16T10:00:00+08:00",
    "updated_at": "2026-03-16T10:10:00+08:00"
  },
  "msg": "success",
  "timestamp": "2026-03-16T10:10:00+08:00"
}
配置不存在时的错误响应
{
  "code": 1170,
  "data": null,
  "msg": "微信支付配置不存在",
  "timestamp": "2026-03-16T10:10:00+08:00"
}

Scenario: 查询当前生效配置

WHEN 平台用户调用 GET /api/admin/wechat-configs/active

THEN 若有生效配置,返回该配置详情(脱敏)

THEN 若无生效配置,data 返回 null

请求
GET /api/admin/wechat-configs/active
Authorization: Bearer {token}
有生效配置时的成功响应
{
  "code": 0,
  "data": {
    "id": 1,
    "name": "微信直连主配置",
    "description": "生产环境微信直连支付配置",
    "provider_type": "wechat",
    "is_active": true,
    "oa_app_id": "wx1234567890abcdef",
    "oa_app_secret": "abcd***7890",
    "oa_token": "myto***n123",
    "oa_aes_key": "[已配置]",
    "oa_oauth_redirect_url": "https://example.com/oauth/callback",
    "miniapp_app_id": "wx9876543210fedcba",
    "miniapp_app_secret": "fedc***4321",
    "wx_mch_id": "1234567890",
    "wx_api_v3_key": "your***0abc",
    "wx_api_v2_key": "your***0abc",
    "wx_cert_content": "[已配置]",
    "wx_key_content": "[已配置]",
    "wx_serial_no": "ABCD***EF12",
    "wx_notify_url": "https://example.com/api/payment/wechat/notify",
    "fy_ins_cd": "",
    "fy_mchnt_cd": "",
    "fy_term_id": "",
    "fy_private_key": "[未配置]",
    "fy_public_key": "[未配置]",
    "fy_api_url": "",
    "fy_notify_url": "",
    "created_at": "2026-03-16T10:00:00+08:00",
    "updated_at": "2026-03-16T10:05:00+08:00"
  },
  "msg": "success",
  "timestamp": "2026-03-16T10:15:00+08:00"
}
无生效配置时的响应
{
  "code": 0,
  "data": null,
  "msg": "当前无生效的支付配置,仅支持钱包支付",
  "timestamp": "2026-03-16T10:15:00+08:00"
}

Scenario: 配置切换不取消在途订单

WHEN 管理员激活新配置时,系统中存在使用旧配置创建的待支付订单

THEN 系统不取消这些订单

THEN 旧订单若支付成功,回调按订单关联的 payment_config_id 加载旧配置验签处理

THEN 旧订单若未支付,由现有 30 分钟超时机制自动取消

此场景无独立 API 接口,为激活接口的业务约束。


Requirement: 生效配置 Redis 缓存

系统 SHALL 将当前生效的支付配置缓存在 Redis 中,减少数据库查询。


Scenario: 缓存命中

WHEN 支付流程查询生效配置Redis 缓存 wechat:config:active 存在

THEN 直接返回缓存数据,不查询数据库

此场景为内部实现约束,无独立 API 接口。


Scenario: 缓存未命中

WHEN 支付流程查询生效配置Redis 缓存 wechat:config:active 不存在

THEN 查询数据库获取 is_active=true 的配置

THEN 将结果写入 RedisTTL 为 5 分钟

THEN 返回配置数据

此场景为内部实现约束,无独立 API 接口。


Scenario: 无生效配置时缓存空标记

WHEN 数据库中无 is_active=true 的配置

THEN 在 Redis 写入空标记(值为 "none"TTL 为 1 分钟

THEN 后续请求命中空标记后直接返回无配置,不穿透数据库

此场景为内部实现约束,无独立 API 接口。


Scenario: 配置变更主动清除缓存

WHEN 执行激活、停用、更新生效配置、删除配置操作

THEN 系统主动 DEL Redis 缓存 wechat:config:active

此场景为内部实现约束,体现在激活、停用、更新、删除接口的副作用中。


Requirement: 仅平台用户可操作

系统 SHALL 限制微信参数配置管理接口仅平台用户(user_type=1 超级管理员和 user_type=2 平台用户)可访问。路由层中间件统一拦截,无需在 Service 层重复校验。


Scenario: 平台用户访问成功

WHEN 超级管理员(user_type=1)或平台用户(user_type=2)请求微信参数配置管理接口

THEN 系统正常处理请求


Scenario: 非平台用户拒绝访问

WHEN 代理账号(user_type=3)或企业账号(user_type=4)请求微信参数配置管理接口

THEN 系统返回错误码 1005,消息"无权限访问支付配置管理功能"

错误响应
{
  "code": 1005,
  "data": null,
  "msg": "无权限访问支付配置管理功能",
  "timestamp": "2026-03-16T10:00:00+08:00"
}

Scenario: 未登录用户拒绝访问

WHEN 请求未携带有效 Token 或 Token 已过期

THEN 系统返回 HTTP 401错误码 1002

错误响应
{
  "code": 1002,
  "data": null,
  "msg": "无效或已过期的认证令牌",
  "timestamp": "2026-03-16T10:00:00+08:00"
}

Requirement: 审计日志

系统 SHALL 对所有微信参数配置的写操作(创建、更新、删除、激活、停用)记录操作审计日志,便于追溯配置变更历史。


Scenario: 创建配置时记录审计日志

WHEN 平台用户成功创建微信参数配置

THEN 系统异步写入审计日志,记录以下信息:

字段
operator_id 当前操作人 ID
operator_type 操作人用户类型
operation_type create
operation_desc 创建微信支付配置:{配置名称}
after_data 新建配置的完整数据(敏感字段脱敏后存储)
request_id 当前请求 ID
ip_address 操作人 IP
user_agent 操作人 User-Agent

THEN 审计日志写入失败不影响业务操作,失败时记录 Error 日志


Scenario: 更新配置时记录审计日志

WHEN 平台用户成功更新微信参数配置

THEN 系统异步写入审计日志,记录以下信息:

字段
operator_id 当前操作人 ID
operation_type update
operation_desc 更新微信支付配置:{配置名称}
before_data 更新前的配置数据(敏感字段脱敏后存储)
after_data 更新后的配置数据(敏感字段脱敏后存储)

Scenario: 删除配置时记录审计日志

WHEN 平台用户成功删除微信参数配置

THEN 系统异步写入审计日志,记录以下信息:

字段
operator_id 当前操作人 ID
operation_type delete
operation_desc 删除微信支付配置:{配置名称}
before_data 删除前的配置数据(敏感字段脱敏后存储)

Scenario: 激活配置时记录审计日志

WHEN 平台用户成功激活微信参数配置

THEN 系统异步写入审计日志,记录以下信息:

字段
operator_id 当前操作人 ID
operation_type activate
operation_desc 激活微信支付配置:{配置名称},原生效配置:{旧配置名称或"无"}
before_data 激活前的状态(旧生效配置 ID 和名称)
after_data 激活后的状态(新生效配置 ID 和名称)

Scenario: 停用配置时记录审计日志

WHEN 平台用户成功停用微信参数配置

THEN 系统异步写入审计日志,记录以下信息:

字段
operator_id 当前操作人 ID
operation_type deactivate
operation_desc 停用微信支付配置:{配置名称}
before_data 停用前的配置状态
after_data 停用后的配置状态