spec.md 5.8 KB

易宝支付与满减活动代码质量治理 Spec

Why

易宝支付回调和满减活动计算代码存在多处严重缺陷:验签逻辑反转、双 @RequestBody 致回调失效、验签密钥硬编码、限购功能被注释失效、积分用 double 违反整数约定、满减档位未排序导致匹配错误等。这些问题直接威胁资金安全、计算准确性与功能正确性,违反项目"代码严谨规范、高可用、计算准确"的工程约定。

What Changes

  • 修复验签逻辑反转PayUtil.isSgin 方法在签名匹配时返回 false、不匹配时返回 true,逻辑完全反转
  • 修复双 @RequestBody 致回调 NPEPayScrmController.ybPayNotifyYbPayController.payNotify 使用两个 @RequestBody,第二个参数恒为 null 导致 NPE
  • 统一验签密钥来源PayScrmController.ybPayNotify 改用从 DB 配置读取密钥,不再使用硬编码 PayConfig.Key
  • 清理 TestYb.java 硬编码敏感信息:删除生产源码目录中的硬编码商户号、Token、身份证号
  • 补全回调 null 校验与数组越界校验:所有易宝回调方法的 params.get("sign")order[] 访问增加校验
  • 统一回调返回值:成功统一返回 SUCCESS,失败统一返回 FAIL,不再大小写混用
  • YbPayController.payNotify 验签失败改返回字符串:不再抛异常导致易宝重试
  • 修复满减限购失效:取消 resolveDisabledReason 中限购判断的注释,并修改 countEffectiveByActivityAndUser 将待支付(status=0)也计入限购统计
  • 修复制单改价满减重复应用applyPromotionFields 增加 skip 判断,与 computedOrder 一致
  • 修复满减档位未排序saveTiersthresholdAmount 排序后再设置 sortOrder
  • 满减 usage 记录增加幂等保护fs_store_promotion_usage 表增加 (order_id, activity_id) 唯一索引校验
  • 修复 enableActivity 并发竞态:改用数据库唯一约束或 SELECT FOR UPDATE 防止并发启用冲突

Impact

  • Affected specs: 积分发放规则、多门店积分按比例分配、满减活动计算、支付回调幂等性
  • Affected code:
    • fs-service/.../ybPay/util/PayUtil.java(验签逻辑修复)
    • fs-service/.../pay/pay/util/PayUtil.java(验签逻辑修复)
    • fs-user-app/.../store/PayScrmController.java(双 @RequestBody 修复、密钥来源统一、null 校验)
    • fs-user-app/.../YbPayController.java(双 @RequestBody 修复、验签失败不抛异常、System.out 替换)
    • fs-admin/.../hisStore/TestYb.java(删除或迁移硬编码敏感信息)
    • fs-service/.../hisStore/service/impl/FsStorePromotionComputeServiceImpl.java(限购恢复、usage 幂等)
    • fs-service/.../hisStore/service/impl/FsStorePromotionServiceImpl.java(saveTiers 排序、enableActivity 并发)
    • fs-service/.../hisStore/service/impl/FsStoreOrderScrmServiceImpl.java(applyPromotionFields skip 判断)
    • fs-service/.../hisStore/support/FsStorePromotionTierCalculator.java(档位匹配防御性排序)
    • fs-service/.../resources/mapper/hisStore/FsStorePromotionUsageMapper.xml(限购统计含待支付)

ADDED Requirements

Requirement: 支付回调验签正确性

系统 SHALL 正确实现易宝支付回调的验签逻辑,验签通过返回 true,验签失败返回 false。

Scenario: 合法签名回调

  • WHEN 易宝发送签名正确的支付回调
  • THEN 验签方法返回 true,回调正常处理

Scenario: 非法签名回调

  • WHEN 攻击者发送签名错误的回调
  • THEN 验签方法返回 false,回调被拒绝并记录日志

Requirement: 支付回调参数绑定

系统 SHALL 使用单一 @RequestBody 接收回调请求体,确保参数正确绑定。

Scenario: 易宝回调请求

  • WHEN 易宝发送支付回调 POST 请求
  • THEN 回调方法能正确解析请求体中的订单信息,不发生 NPE

Requirement: 满减限购次数生效

系统 SHALL 正确执行满减活动的限购次数校验,待支付订单也计入已参与次数。

Scenario: 用户达到限购次数

  • WHEN 用户已参与满减活动次数(含待支付)达到 limitPerUser 上限
  • THEN 该活动对该用户显示为"已超过参与次数限制",不可再次使用

Requirement: 满减档位匹配准确性

系统 SHALL 按 thresholdAmount 升序排列满减档位后再匹配,确保返回正确的优惠档位。

Scenario: 档位配置顺序混乱

  • WHEN 管理员配置档位时未按金额升序录入
  • THEN 系统自动排序后匹配,返回符合门槛的最高档位

MODIFIED Requirements

Requirement: 支付回调返回值规范

所有易宝支付回调方法 SHALL 统一返回值:处理成功返回 SUCCESS,处理失败返回 FAIL,不再大小写混用。

Scenario: 回调处理成功

  • WHEN 支付回调处理成功
  • THEN 返回字符串 SUCCESS(全大写)

Scenario: 回调处理失败

  • WHEN 支付回调处理失败(验签失败、业务异常)
  • THEN 返回字符串 FAIL(全大写),让易宝平台重试

Requirement: 制单改价满减应用

制单改价场景下,applyPromotionFields SHALL 跳过满减计算,与 computedOrderskipPromotion 逻辑保持一致。

Scenario: 制单改价创建订单

  • WHEN 制单改价场景创建订单时调用 applyPromotionFields
  • THEN 不重新计算满减优惠,promotionDiscountAmount 保持试算时的值或为 0

REMOVED Requirements

Requirement: TestYb.java 中的硬编码敏感信息

Reason: 生产源码目录中硬编码真实商户号、Token、身份证号,存在泄露风险 Migration: 将测试代码移至 src/test/java 或直接删除,敏感参数从配置文件或环境变量读取