Date: 2026-09-11 | Spec: spec.md | Data Model: data-model.md
所有接口遵守项目 Controller 规范:token 用 @RequestHeader String token,POST 业务参数用 @RequestBody DTO,GET 查询参数逐个 @RequestParam;DTO 字段不加 Bean Validation 注解,校验在 Service,错误信息走 MessageUtils.message。
单一校验入口,唯一闸门实现(spec FR-004)。
/** 校验支付方式可用,不可用抛 ServiceException(国际化);三下单入口统一下单时调用。 */
void assertUsable(String payType, GateScope scope, Long payeeUserId)
/** 列出某维度对收款方可用的支付方式(结算页可选项、骑手列表过滤共用)。 */
List<PayMethodOption> listAvailable(GateScope scope, Long payeeUserId)
enum GateScope { MERCHANT, RIDER_FLASH }
调用点(仅此三处 + bankInfo 一处,禁止新增重复实现):
| 调用方 | 位置 | 参数 |
|---|---|---|
| 用户餐饮下单 | UserOrderController.createOrder(setPayType 前后) |
payType=input.paymentMethod, MERCHANT, 商家主账号 userId |
| 商家建单 | PosOrderController /addorder |
payType 固定 "1"(COD), MERCHANT —— COD 默认开,校验保持对称 |
| 闪送下单 | FlashDeliveryApplicationService.create(normalizePayType 处) |
payType, RIDER_FLASH, 无收款方(抢单前,只校验平台开关) |
| 027 bankInfo | ChantingStoreController.bankInfo |
OFFLINE_TRANSFER, MERCHANT, 商家 userId |
错误 key(6 语言文件全配):pay.method.not.available(该支付方式当前不可用,请更换支付方式)。
pay:method:config,操作记 @Log)GET /system/payMethodConfig/list
返回:方式×维度全矩阵(含缺行按"开"补齐的虚拟行),每项 {methodCode, methodName(i18n key), scope, enabled, sort}。
PUT /system/payMethodConfig
Body: { items: [ { methodCode, scope, enabled } ] }
批量 upsert;@Log(title="支付方式设置");@PreAuthorize("@ss.hasPermi('pay:method:config')")。
GET /system/merchantPayMethods
返回:{ available: [ {methodCode, methodName, ready} ], selected: ["COD", ...] }——available = 平台商家维度开放集合(附就绪度标记),selected = 商家当前选择(NULL 视为全部,返回时展开为全部可用项)。
PUT /system/merchantPayMethods
Body: { methodCodes: ["COD", "CARD_OMG"] } // 空数组=清空=回落全部
写 info_user.pay_methods(主账号行;子账号可编辑,写其主账号——与 022 子账号权限体系一致)。
GET /system/bankCard // 本人卡列表(含启用标记)
POST /system/bankCard // 新增 {bankName, accountNo, accountName}
PUT /system/bankCard // 修改 {id, bankName, accountNo, accountName}
DELETE /system/bankCard/{id} // 删除(启用卡删除后无启用卡→线下转账不就绪)
PUT /system/bankCard/activate/{id} // 启用某卡(同事务停旧卡)
校验:bankName ∈ 字典 taiwan_bank_list;条数上限 10;只能操作本人卡。
GET /system/riderFlashPayMethods // 返回同 2.1 结构(scope=RIDER_FLASH)
PUT /system/riderFlashPayMethods // { methodCodes: [...] },空=回落全部
写入 info_user.flash_pay_methods;要求 token userType=2。
FlashDeliveryQuoteRequest / FlashDeliveryCreateRequest 增加可选 payType;下单时经闸门校验(RIDER_FLASH,仅平台开关层);缺省=现金 4(现状不变)。listAvailable(RIDER_FLASH, null))。pickupDistanceMeters 等既有行为不变。骑手确认收款(新):
POST /system/flashDelivery/rider/orders/{id}/confirmPayment
条件:本人中单 + 状态已达已送达或之后;效果:payment_status 0→1 + 日志(RIDER);幂等:已确认再调返回成功。
GET /chanting/store/bankInfo?id={storeId} —— 路径、匿名、返回结构(bankAccountName/bankName/bankAccountNo 三字段或 data=null)完全不变:
info_bank_card 该商家 is_active=1 的卡后端 messages*.properties ×6:pay.method.not.available、银行卡校验类 key(pay.bankcard.*)。前端:admin-vue 支付方式设置页、foodie-store 支付设置页全部 key 四语言(vi/zh/tw/en),命名驼峰有意义(项目规范)。
GET /system/storePayMethods?storeId={storeId}
@Anonymous,同 bankInfo 风格);App 结算页进入时调用,按返回渲染支付方式列表。pos_store.id → user_id(商家主账号)→ listAvailable(MERCHANT, 主账号)。data: [ { methodCode, payType, ready } ]——methodCode 组代码 / payType 对应数值(CARD_OMG 展开 2 与 5 两项)/ ready 就绪度。线下转账 ready=false 时不渲染(替代 027 时代"bankInfo!=null 才显示"的判断,App 可统一按本接口渲染)。