# 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.createOrder` 的 `paymentMethod` 直接透传为 `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 等)在五份文件中均有先例,直接对齐。 - **新增 key**:`no.order.paytype.not.transfer`(非转账单)、`no.order.transfer.cancelled`(已取消不可确认)、`no.order.transfer.already.paid`(已收款)、`no.order.transfer.not.paid`(骑手门禁提示)。 ### D8 商家 Web 标签 - **决策**:foodie-store `index.vue` 的 `paymentTypeLabel` 映射加 `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 时),无需特殊处理;确认收款按钮同样可用。