Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 40s
feat(pay): 添加支付API基础结构 feat(miniapp): 创建支付测试小程序页面与配置 feat(wechatpay): 配置微信支付参数与证书 fix(guild): 修复成员列表查询条件 docs: 更新代码规范文档与需求文档 style: 统一前后端枚举显示与注释格式 refactor(admin): 重构用户奖励发放接口参数处理 test(title): 添加称号效果参数验证测试
3.5 KiB
3.5 KiB
审计结论摘要
- 金额统一“分”,积分统一“元等值整数(1元=1积分)”;现有退款登记复用积分流水记录“金额/100”,语义混用。
- 退款恢复积分在多次部分退款时可能重复恢复导致超恢复;预下单未持久化;前端金额展示直用“分”,体验不佳;订单积分抵扣落账缺失。
整改目标
- 明确并统一金额/积分口径:分↔积分换算唯一、无混用。
- 完善退款与积分恢复逻辑:部分退款按比例恢复、全额退款一次性恢复;幂等保护。
- 持久化支付域关键数据:预下单/交易/退款/通知;订单详情展示真实字段。
- 前端金额展示统一为“元”且格式化,枚举与文案一致。
具体改造项
- 数据结构与落账
- 新增“货币退款流水”独立记录(或新增表
payment_refunds并在订单详情聚合展示),将每笔退款金额以“分”记录;保留user_points_ledger仅记录“积分”类动作(如refund_restore)。 - 在支付阶段补充“订单积分扣减流水”(action=
order_deduct),并回填orders.points_ledger_id,与实际抵扣金额对应(分→积分换算)。
- 退款恢复与幂等
- 部分退款按比例恢复积分:
恢复积分 = 订单积分抵扣(分) × 本次退款金额(分) / 实付金额(分) ÷ 100(四舍五入),累计不超过订单抵扣积分总额。 - 全额退款一次性恢复剩余积分;为
refund_restore增加去重幂等:唯一键(order_no, action='refund_restore')或累计校验。 - 订单置“已退款”的条件与部分退款展示:保持
2已支付,在详情中清晰展示“累计已退款金额(分)”和每笔明细。
- 预下单与交易持久化
- 引入并使用
payment_preorders/payment_transactions/payment_refunds/payment_notify_events表:- 预下单:落库
out_trade_no=order_no与prepay_id,回填orders.pay_preorder_id。 - 交易:回调落库
transaction_id/amount/success_time/raw,订单推进。 - 退款:真实调用后落库
refund_no/amount/status/success_time/raw,并通过回调/查询推进状态。 - 通知事件:记录
notify_id/event_type/raw/processed作审计与去重。
- 预下单:落库
- 前端展示统一
- 列表与详情金额展示统一格式化为“元”(保留两位小数),并保留原始分用于导出或接口。
- 详情页展示:交易号
transaction_id、退款号refund_no、渠道/支付方式;“可退余额(分/元)”与“累计已退款(分/元)”。
- 安全与幂等
- 业务幂等键:
order_no(预下单/订单推进)、notify_id(回调)、refund_no(退款)。 - 数据库唯一索引:
orders.order_no、payment_preorders.out_trade_no、payment_transactions.transaction_id、payment_refunds.refund_no、payment_notify_events.notify_id。
验收与测试
- 单元:分↔积分换算正确;部分/全额退款恢复积分计算;幂等重复请求不重复落账。
- 集成:真实预下单→回调验证→管理端主动退款→退款落库与恢复积分→订单详情展示一致;账单对账拉取与差异比对基础验证。
执行顺序
- 数据表与DAO:新增支付域表与唯一索引;迁移脚本。
- 业务与服务:预下单持久化、回调入库、退款入库与恢复积分比例算法、幂等保护。
- 前端统一金额展示与详情字段扩展;导出口径对齐。
- 测试与联调:场景覆盖与灰度验证,文案与枚举一致。