research.md 5.2 KB

Research: 線下轉賬支付(payType=6)

日期:2026-09-03 | 状态:定稿(对话讨论 + 代码核实,无未决项)

决策清单

D1 支付方式值 = 6

  • 决策PosOrder.payType = "6" 表示線下轉賬。
  • 依据:现有值域 1=外送到付、2=信用卡(OMG)、3=LINE Pay、4=现金、5=Apple Pay(specs/023 已定);6 为空闲新值。常量加 OrderLifecycleService.PAY_TYPE_TRANSFER(现有 PAY_TYPE_CASH="4" 同文件)。
  • 备选:复用 4(现金)加标记位——拒绝,语义混淆且破坏现金确认逻辑。

D2 收款账户查询接口放门店控制器,商家级数据

  • 决策GET /chanting/store/bankInfo?id={storeId}(匿名),路径:门店 → pos_store.user_id(商家主账号)→ info_user 三字段(bankAccountName/bankName/bankAccountNo,026 已加);任一为空返回 data=null
  • 依据:审核资料银行字段挂在商家主账号上,连锁店共用;App 拿 null 隐藏「線下支付」选项(spec FR-001)。
  • 备选:挂到订单接口按 orderId 查——拒绝,选项在选择支付方式时(下单前)就需要,只有 storeId 可用。

D3 下单链路零改动

  • 决策UserOrderController.createOrderpaymentMethod 直接透传为 payType(第259行),无白名单校验;6 天然可下单(state=0、payStatus=0、collectPayment 不设)。
  • 依据:代码核实;与线上支付单未付态完全同构。

D4 确认收款镜像现金版 + 挂骑手通知钩子

  • 决策:新增 GET /system/orderShOprate/confirmTransferPayment,结构照抄 confirmCashPayment(PosOrderShOprateController:397):校验 payType=6、state≠4(已取消拒绝)、payStatus 0→1、orderLogHelper 记「商家XX确认转账收款」;外送单(type=0)确认后调用 deliveryOrderNotificationService.notifyOrderAvailable(order) 通知附近骑手。
  • 依据notifyOrderAvailable = "支付完成且仍待骑手接单时通知附近骑手",OMG 支付成功后正是这样调(OmgPaymentNotifyService:189);转账单确认收款 = 它的"支付完成"时刻,不挂钩子则订单进骑手池但无人被通知。
  • 备选:复用 confirmCashPayment 放宽校验到 4 和 6——拒绝,错误提示与日志语义会混(现金/转账),App 端也不好区分埋点。

D5 骑手可见性:零改动(天然满足)

  • 决策:骑手抢单列表(orderList tab=newTask)现有查询已含 eq(PosOrder::getPayStatus, 1L)(PosOrderQsOprateController:347),payStatus=0 的转账单自动不可见。
  • 依据:代码核实;这也是线上未支付单不进骑手池的同一机制。
  • 推送排除:同样天然满足——骑手新单推送只由"支付完成"钩子触发(OMG/LINE 回调),下单时不推。

D6 骑手接单门禁:防绕过的显式校验

  • 决策PosOrderQsOprateController.acceptOrder 增加校验:payType=6 && payStatus≠1 → 拒绝,提示 key no.order.transfer.not.paid(「商家确认收款后骑手才能接单」,五份 properties)。
  • 依据:列表过滤挡不住直接调接口(App 抢单页刷新时差、越权调用);spec FR-004 要求接口级拒绝。
  • 备选:不加(信任列表过滤)——拒绝,spec 明确要求接口拒绝且成本一行。

D7 后端国际化资源:五份 properties

  • 决策:新 key 加到 ruoyi-admin/src/main/resources/i18n/ 下 messages.properties(默认,内容为 vi)、messages_zh_CN、messages_zh_TW、messages_en_US、messages_vi 全部五份。
  • 依据:现金单的 key(no.order.paytype.not.cash 等)在五份文件中均有先例,直接对齐。
  • 新增 keyno.order.paytype.not.transfer(非转账单)、no.order.transfer.cancelled(已取消不可确认)、no.order.transfer.already.paid(已收款)、no.order.transfer.not.paid(骑手门禁提示)。

D8 商家 Web 标签

  • 决策:foodie-store index.vuepaymentTypeLabel 映射加 6: 'OfflineTransfer';i18n key 加 index 命名空间四语言(zh 线下转账 / tw 轉賬支付 / en Transfer Payment / vi Chuyển khoản)。列表列与详情弹窗共用该函数,一处改两处生效。
  • 依据:现有 1-4 映射同型(index.vue:388-396)。

D9 明确不做

  • App 端 UI(客户收银台、商家 App 确认按钮、骑手 App):不在工作区,交付接口+交互说明。
  • Web 商家端「确认收款」按钮:本期只做接口,按钮后续按需。
  • 运费代收/结算、凭证上传、转账单超时取消:纯线下,spec 已排除。
  • 零 DDL:复用 payType/payStatus 现有字段。

风险与注意

  • confirmTransferPayment 需注入 DeliveryOrderNotificationService:PosOrderShOprateController 目前未注入(PosOrderController 有),照 PosOrderController:130 的方式补。
  • notifyOrderAvailable 的时机:其内部有事务同步(afterCommit);确认收款方法不加 @Transactional(对齐现金版),保存后直接调用即可。
  • 自取/堂食转账单:完成时现有 completeOrder 自动置 payStatus=1(state 2→3 时),无需特殊处理;确认收款按钮同样可用。