8.9 KiB
8.9 KiB
Payment Merchant Pool Management Specification
ADDED Requirements
Requirement: 平台专属的商户池管理入口
系统 SHALL 仅向超级管理员和平台用户开放支付商户、商户池及微信授权配置的管理入口和操作。
Scenario: 超级管理员可见并访问
- GIVEN 当前登录账号的
user_type为1 - WHEN 用户加载设置菜单或访问
/settings/payment-merchant-pools - THEN 系统 MUST 展示商户池管理入口并允许进入页面
Scenario: 平台用户可见并访问
- GIVEN 当前登录账号的
user_type为2 - WHEN 用户加载设置菜单或访问
/settings/payment-merchant-pools - THEN 系统 MUST 展示商户池管理入口并允许进入页面
Scenario: 非平台账号被拒绝
- GIVEN 当前登录账号的
user_type为3或4 - WHEN 用户加载设置菜单或直接输入
/settings/payment-merchant-pools - THEN 系统 MUST NOT 展示商户池管理入口
- AND 系统 MUST 拒绝直接访问该页面
- AND 系统 MUST NOT 返回商户、商户池或授权配置数据
Requirement: 支付商户管理接口
系统 SHALL 提供支付商户的分页查询、创建、详情、按需更新和删除接口。
Scenario: 查询和筛选支付商户
- WHEN 管理员请求
GET /api/admin/payment-merchants - THEN 系统 MUST 支持
page、page_size、payment_method和enabled查询参数 - AND
payment_methodMUST 支持wechat和alipay - AND 响应中的每个商户 MUST 包含
id、name、payment_method、provider_type、merchant_identity、enabled、remark、credential_version、created_at和updated_at
Scenario: 创建支付商户
- WHEN 管理员向
POST /api/admin/payment-merchants提交name、payment_method、provider_type、merchant_identity、credentials、enabled和remark - THEN 系统 MUST 创建支付商户并返回新商户记录
- AND
provider_type为wechat时 MUST 只接受wechat、wechat_v2或fuiou - AND
provider_type为alipay时 MUST 只接受alipay
Scenario: 查询支付商户详情
- WHEN 管理员请求
GET /api/admin/payment-merchants/{id} - THEN 系统 MUST 返回指定商户的详情
- AND 响应 MUST NOT 包含任何支付凭证明文
Scenario: 按需更新和切换商户状态
- WHEN 管理员请求
PUT /api/admin/payment-merchants/{id}并只提交enabled - THEN 系统 MUST 只更新该商户的
enabled字段 - AND 系统 MUST 保留未提交字段的原值
Scenario: 确认后删除支付商户
- WHEN 管理员请求
DELETE /api/admin/payment-merchants/{id}并提交confirm=true - THEN 系统 MUST 删除目标商户
- AND 前端 MUST 在发送请求前展示二次确认
Requirement: 支付商户列表与启停交互
后台商户管理页 SHALL 展示支付商户状态,并允许有权限的管理员按接口契约切换启用状态。
Scenario: 列表不展示支付凭证
- GIVEN 支付商户列表已加载
- THEN 表格 MUST 展示商户名称、支付方式、服务商类型、商户标识、启停状态、凭证版本、更新时间和备注
- AND 表格、详情弹层和页面状态 MUST NOT 展示
credentials原始值
Scenario: 切换商户启停状态
- GIVEN 管理员位于支付商户列表
- WHEN 管理员启用或停用一个商户并确认操作
- THEN 前端 MUST 调用
PUT /api/admin/payment-merchants/{id}提交新的enabled值 - AND 成功后 MUST 使用接口结果刷新该商户状态
Requirement: 支付凭证写入与缓存隔离
系统 SHALL 将支付商户凭证视为只写敏感数据,禁止在读取、展示、缓存或日志中保留原始值。
Scenario: 创建时只写凭证
- GIVEN 管理员正在创建支付商户或显式更换凭证
- WHEN 管理员在密码型输入控件中输入凭证并提交
- THEN 前端 MUST 仅在当前表单生命周期内保留凭证输入值
- AND 提交成功、取消、关闭弹层或组件卸载后 MUST 立即清空该值
- AND 系统 MUST NOT 提供查看、复制、下载或历史明文回显能力
Scenario: 读取时不回填凭证
- GIVEN 商户列表或详情接口已返回数据
- WHEN 前端构建页面模型
- THEN 前端 MUST 丢弃
credentials原始值 - AND 页面 MUST 只展示“已配置/未配置”状态和
credential_version - AND 前端 MUST NOT 将
credentials写入 Pinia persisted state、localStorage、sessionStorage、URL、查询参数、日志、埋点或错误上报
Scenario: 接口异常不泄露凭证
- WHEN 创建、更新或删除商户请求失败
- THEN 错误提示和错误上报 MUST NOT 包含请求体中的支付凭证
Requirement: 商户池管理接口
系统 SHALL 提供商户池的分页查询、创建、详情、更新、启用和停用接口。
Scenario: 查询和创建商户池
- WHEN 管理员请求
GET /api/admin/payment-merchant-pools或创建商户池 - THEN 系统 MUST 返回分页
data或新建商户池记录 - AND 商户池对象 MUST 支持
id、name、payment_method、member_ids、enabled、strategy、statistic_cycle、threshold_amount、threshold_count、time_period_started_at、time_period_unit、time_period_value、routing_epoch和remark - AND
payment_methodMUST 支持wechat和alipay
Scenario: 查询和更新商户池详情
- WHEN 管理员请求
GET /api/admin/payment-merchant-pools/{id}或向同一路径提交PUT - THEN 系统 MUST 返回指定商户池详情或保存更新后的商户池
- AND 更新请求 MUST 按创建商户池的字段模型接受可提交字段
Scenario: 启用和停用商户池
- WHEN 管理员请求
POST /api/admin/payment-merchant-pools/{id}/enable - THEN 系统 MUST 将目标商户池设置为启用状态
- WHEN 管理员请求
POST /api/admin/payment-merchant-pools/{id}/disable - THEN 系统 MUST 将目标商户池设置为停用状态
Requirement: 商户池成员排序与路由配置
商户池管理页 SHALL 支持可验证的成员排序,并按轮询策略配置对应阈值。
Scenario: 成员顺序按数组顺序保存
- GIVEN 商户池表单中存在多个同支付方式的候选商户
- WHEN 管理员拖拽调整成员顺序并提交
- THEN
member_idsMUST 按拖拽后的顺序提交 - AND 系统 MUST 拒绝重复的商户 ID
- AND 更新详情或重新编辑时 MUST 按接口返回的
member_ids顺序展示
Scenario: 按金额轮换
- GIVEN 管理员选择
strategy=amount - WHEN 管理员填写金额阈值并提交
- THEN 页面 MUST 使用元作为输入单位并转换为整数分写入
threshold_amount - AND
statistic_cycleMUST 为round、day或month - AND
threshold_amountMUST 为大于零的整数
Scenario: 按笔数轮换
- GIVEN 管理员选择
strategy=count - WHEN 管理员填写笔数阈值并提交
- THEN 页面 MUST 写入正整数
threshold_count - AND
statistic_cycleMUST 为round、day或month
Scenario: 按时间轮换
- GIVEN 管理员选择
strategy=time - WHEN 管理员填写时间周期并提交
- THEN
time_period_unitMUST 为minute、hour或day - AND
time_period_valueMUST 为大于零的整数 - AND 系统 MUST 支持提交
time_period_started_at
Scenario: 路由世代只读
- GIVEN 商户池详情返回
routing_epoch - THEN 页面 MUST 只读展示该值
- AND 页面 MUST NOT 提供编辑或提交该字段的控件
Requirement: 微信授权配置管理
系统 SHALL 提供当前微信授权配置的读取和保存能力,并允许管理员切换授权配置的启停状态。
Scenario: 读取当前微信授权配置状态
- WHEN 管理员请求
GET /api/admin/wechat-authorizations - THEN 页面 MUST 展示
enabled、miniapp_app_id、oa_app_id和oa_oauth_redirect_url等非敏感字段 - AND 页面 MUST NOT 回填或展示
miniapp_app_secret、oa_app_secret、oa_token或oa_aes_key的原始值
Scenario: 保存或切换微信授权启停状态
- WHEN 管理员向
PUT /api/admin/wechat-authorizations/current保存配置 - THEN 请求 MUST 支持
enabled、miniapp_app_id、miniapp_app_secret、oa_app_id、oa_app_secret、oa_token、oa_aes_key和oa_oauth_redirect_url - AND 保存成功后页面 MUST 使用接口结果刷新启停状态
- AND 敏感字段 MUST 只在当前编辑会话内存在,并在保存、取消、关闭或卸载后清空
Scenario: 未更换敏感字段时保留后端原值
- GIVEN 页面只修改
enabled或其他非敏感字段 - WHEN 管理员提交微信授权配置
- THEN 请求 MUST NOT 使用脱敏占位值覆盖后端已有敏感字段
- AND 页面 MUST NOT 在提交后缓存敏感字段值