## Purpose 补齐商户池在原始需求(`111.md` §6.2、§6.4)中要求、当前实现未提供的列表投影字段,并把金额/笔数「全部成员达标」语义按统计周期分开定义、明确单成员池与时间轮询起点的行为,消除主 Spec 文字与实现之间的张力。 ## MODIFIED Requirements ### Requirement: 商户池唯一性与轮询配置 系统 SHALL 为每种支付方式最多启用一个商户池;停用历史池可保留,但不得同时启用多个同支付方式池。商户池成员支付方式 MUST 与池一致,成员按明确顺序排列;金额/笔数方式必须配置 `每轮累计`、`自然日累计` 或 `自然月累计` 统计周期,时间方式必须配置最小为 1 分钟的数值、单位和起始时间。 金额和笔数轮询只统计已确认支付成功结果,不在预下单时预占,也不因退款回冲。支付创建时 MUST 冻结本次路由所属的统计世代;首次成功只按支付 ID 一次性计入冻结商户和冻结统计世代,当前选路只读取当前统计世代;金额与笔数累计 MUST 只统计与当前统计世代匹配的成功事实(自然日与自然月方式另加支付时间不早于当期窗口起点)。达到阈值的成员在当前周期跳过;全部成员均达到阈值时的行为按统计周期区分:`每轮累计` MUST 视为当轮结束,以保存成功时间为新起点开启新一轮并从零重新累计,MUST NOT 因当轮全部达标而拒绝创建,开启新一轮 MUST 以条件更新递增统计世代,仅在当前世代未被并发改变时成功,更新冲突 MUST 按并发冲突拒绝创建本次支付且 MUST NOT 在旧世代上重复累计;`自然日累计` 与 `自然月累计` MUST 拒绝创建新支付单并提示当前周期暂无可用商户。池内只有一个启用成员时该成员 MUST 被固定选中:MUST NOT 因达到阈值而在当前周期被跳过,也 MUST NOT 因「全部成员达标」而拒绝创建,该规则优先于上句的自然周期拒绝语义。时间轮询自起始时间按固定时段和成员顺序选择,成员停用即时跳下一个可用成员但不重置时段;修改时间周期数值、单位、起始时间或成员顺序并保存成功后,系统 MUST 以保存成功时间为新起点并从前述成员列表第一项重新计算时段,MUST NOT 沿用请求提交前的起点。预下单失败不得自动切换或重试,失败单不计入统计;客户再次发起时重新选择。修改阈值保留当前统计,修改统计周期、金额/笔数方式、时间周期、起始时间或每轮排序按 PRD 规则开启新周期;自然周期排序调整保留未移除成员累计。 #### Scenario: 并发预下单未预占额度 - **WHEN** 多个客户并发创建金额或笔数轮询支付单且当前成员尚未达到阈值 - **THEN** 系统可使这些支付单均命中当前成员,只有后续确认成功的支付才计入累计,已创建支付单不因轮询切换改挂商户 #### Scenario: 迟到首次成功归属冻结统计世代 - **GIVEN** 支付已创建但尚未成功,之后商户池切换统计周期、成员或排序 - **WHEN** 该支付首次确认成功 - **THEN** 系统仅将金额或笔数写入该支付创建时冻结的商户和统计世代,不得改写当前选路统计或重复累计 #### Scenario: 每轮累计全部达标开启新一轮 - **GIVEN** 启用商户池统计周期为每轮累计,且本轮全部成员均已达到阈值 - **WHEN** 客户创建新的支付单 - **THEN** 系统开启新一轮、各成员从零累计,并选中成员顺序第一项,不返回暂无可用商户 #### Scenario: 当期没有可用商户 - **WHEN** 启用商户池中不存在启用且未达阈值的成员,或商户池已停用 - **THEN** 系统拒绝创建新支付单并提示暂无可用商户,不回退到旧综合支付配置 #### Scenario: 自然周期全部达标拒绝创建 - **GIVEN** 启用商户池统计周期为自然日累计或自然月累计,且当前周期全部成员均已达到阈值 - **WHEN** 客户创建新的支付单 - **THEN** 系统拒绝创建并提示当前周期暂无可用商户,不回退到旧综合支付配置 #### Scenario: 单成员池达标后仍可收款 - **GIVEN** 启用商户池只有一个启用成员,且该成员在当前自然日或自然月周期内已达到阈值 - **WHEN** 客户创建新的支付单 - **THEN** 系统仍选中该成员,不返回暂无可用商户 #### Scenario: 修改时间轮询配置后起点重算 - **GIVEN** 时间轮询商户池已存在起始时间与成员顺序 - **WHEN** 授权账号修改周期数值、单位、起始时间或成员顺序并保存成功 - **THEN** 系统以保存成功时间作为新起点,后续时段从成员列表第一项重新计算,不沿用请求提交前的时段 ## ADDED Requirements ### Requirement: 商户池列表投影 商户池列表与详情 SHALL 在既有配置字段之外返回:启用成员数量与成员总数量、当前命中成员、最近配置更新时间。当前命中成员 MUST 以与支付创建相同的选择规则只读计算:金额/笔数方式取成员顺序中第一个未达阈值的成员,「每轮累计」全部达标时取成员顺序第一项;时间方式按当前时段计算结果。该计算 MUST 为只读,MUST NOT 创建支付单、MUST NOT 推进统计世代、MUST NOT 计入成功累计。商户池停用或没有可用成员时当前命中成员 SHALL 返回空值 MUST NOT 阻断列表响应。成员数量与当前命中成员 MUST 按该页池集合批量计算,MUST NOT 逐池放大查询次数。 #### Scenario: 列表展示商户数量与更新时间 - **WHEN** 授权账号查询商户池列表 - **THEN** 每行返回启用成员数、成员总数与最近配置更新时间 #### Scenario: 当前命中成员按顺序计算 - **GIVEN** 金额轮询商户池的成员顺序为 A、B,且 A 尚未达到阈值 - **WHEN** 查询商户池列表 - **THEN** 当前命中成员返回 A,且查询本身不产生支付单、不推进统计世代 #### Scenario: 停用池无当前成员 - **WHEN** 查询一个已停用且无可用成员的商户池 - **THEN** 当前命中成员为空值,其余字段正常返回 #### Scenario: 批量计算不放大查询 - **GIVEN** 一页返回多个商户池 - **WHEN** 查询该页列表 - **THEN** 系统以批量方式读取成员与成功累计,查询次数不随池数量线性增长