2026-10-10。仅提供接口契约,App 代码由前端人员实现。普通外卖仍支付给商家,本功能不改变外卖配送费结算。
updatesql/sql.md 中「2026-10-10 019 骑手 LINE Pay 与闪送 Online」迁移和菜单,给平台角色分配权限。userType=2 账号;接单仍受原骑手审核、容量、车型等规则约束。LINE_PAY_ENVIRONMENT 与 LINE_PAY_BASE_URL 必须匹配:sandbox 对应 https://sandbox-api-pay.line.me,production 对应 https://api-pay.line.me;不能混用。骑手凭证探测、付款、历史核实及退款调用前都会校验,错配时不调用网关。凭证环境来自服务端,不由页面或 App 选择。LINE_PAY_FLASH_CONFIRM_URL=https://<API域名>/pay/line/flash/confirm 和 LINE_PAY_FLASH_CANCEL_URL=https://<API域名>/pay/line/flash/cancel。默认留空,未配置时不允许发起闪送支付;外卖回跳配置不变。反向代理需放行这两个匿名 GET 入口。payType="3"。此时仅创建配送订单,不发起扣款。ACCEPTED 后显示付款入口,调用下面的 create。WAITING_AUTH 和 paymentUrl 时打开链接进行 LINE 认证。认证/浏览器返回不等于已付款。status=PAID 且没有退款阻断才可取件。paymentStatus=1 而没有可信流水,也不能取件。沿用用户/骑手 JWT token 请求头,不是平台 Authorization。返回仍为项目 AjaxResult,HTTP 200 不代表业务成功,须检查业务 code。
POST /system/flashDelivery/orders/{id}/linePay/create
显式 JSON 请求体:
{}
id 为闪送订单数字 ID,仅寄件付款人可发起。不要提交 riderId、channelId、channelSecret、金额或币种;服务端从订单及凭证读取。未接单、取消/已取件、不是 LINE 单或收款凭证未就绪时拒绝。
示例(虚构订单及地址):
{
"code": 200,
"msg": "操作成功",
"data": {
"orderId": 101,
"paymentId": 202,
"status": "WAITING_AUTH",
"refundStatus": null,
"paymentUrl": "https://<LINE付款域名>/<付款路径>"
}
}
重复 create 返回现有活跃尝试,不重复扣款。REQUEST_UNKNOWN、CONFIRM_UNKNOWN、MANUAL_REVIEW 不可当成支付失败后重新支付。已发送的未知尝试保留资金阻断;CREATED 尚未发送的意图因凭证禁用/轮换而取消,不代表已发生扣款。
GET /system/flashDelivery/orders/{id}/linePay/status
寄件付款人及本单接单骑手可查询;他人拒绝。字段与 create 一致,骑手不返回 paymentUrl。无尝试时 status=NOT_STARTED、paymentId/paymentUrl/refundStatus 为空。
| status | 前端处理 |
|---|---|
| NOT_STARTED / CREATED | 尚未完成付款请求,仅在服务器允许时发起/继续当前尝试 |
| REQUESTING / CONFIRMING | 请求处理中,查询当前尝试,不重复付款 |
| WAITING_AUTH | 待用户认证/付款;寄件人可打开当前 paymentUrl |
| REQUEST_UNKNOWN / CONFIRM_UNKNOWN | 结果待核实,查询并等待,禁止第二次扣款 |
| PAID | 服务端已核实到账;如 refundStatus 非空则不能据此继续取件 |
| FAILED / CANCELLED / EXPIRED | 此尝试结束,不等于配送订单已取消;只有有效 ACCEPTED 订单才能按服务端规则重试 |
| MANUAL_REVIEW | 资金需要人工核对,不能伪造成功或自动重新支付 |
refundStatus:空=无退款意图;CREATED=待退款,PROCESSING=退款请求中,UNKNOWN=退款结果待核实,REFUNDED=已证实全额退款,FAILED/MANUAL_REVIEW=失败/人工核对。支付 PAID 历史事实不会被退款擦除。
订单原 paymentStatus:LINE 单 0=未核实到账、1=已到账、2=已证实全额退款;现金/转账沿用 0/1。不要只按此汇总标记放行取件;最终由取件接口校验。
服务器专属回跳 /pay/line/flash/confirm、/cancel 根据已保存 LINE 订单号及字符串交易号定位尝试,仅排队核实,不根据浏览器参数写支付成功。
App 深链:com.twanmsdyh.app://payment/result?orderSource=FLASH&orderId=<闪送数字ID>。前端依据 orderSource=FLASH 调用本文件的 status,不要调用外卖查询,不要信任深链判定成功。不含有效绑定的浏览器回跳显示通用提示;定时任务仍会核实资金。浏览器取消认证不取消配送订单。
返回页有 CSP/no-store;手机浏览器自动唤起可能受限,提供手工打开入口。iOS/Android Scheme 注册和真实 LINE WebView 联调由 App 人员验证。
canAdminCancel;按钮只在严格为 true 时展示,缺字段安全隐藏。平台打开弹窗时再读取详情,接口最终在订单锁内复核站点。line-pay.reconcile 批量、间隔、租约及截止配置,独立任务锁 lock:flash-line-pay:reconcile。租约至少 120 秒覆盖现有 HTTP 超时;到期不等于网关未扣款,人工核对保留活跃阻断。confirmPayment 手工把 LINE 单标记已收款;现金及线下转账原送达后确认收款不变。平台使用既有后台登录 Authorization。GET /system/riderLinePay/list(分页/userName)、GET /{riderId}、PUT /saveCredentials(riderId/channelId/channelSecret)、PUT /toggleEnable(riderId/enabled)。
分别需要 infouser:riderLinePay:list/query/saveCredentials/toggleEnable 权限。列表不查询 Secret;授权详情可用于回显当前凭证;保存时只读随机不存在订单探测,验证失败不替换原版本。Secret 不进操作审计、App 响应或浏览器持久缓存;凭证保存请求专门绕过通用重复提交 sessionStorage 缓存,页面 saving 仍防重复点击。本文不提供真实密钥。
本地测试覆盖签名/请求契约、可信事实、重复/未知保护、退款补偿、权限归属和取件/取消门禁。SQL 本次未执行;真实 MySQL 多连接竞态、LINE Sandbox/正式骑手收款和退款、部署、App/浏览器联调须另行验证,不能用 mock 测试代替真实资金验收。
2026-10-10 最终本地回归:164 个后端测试类、1140 项测试,0 失败/错误/跳过;JDK 21 模块 package 成功;平台三组行为测试 16/16,全部现有测试 25/25,build:stage 成功。独立审查的 5 项重要发现已用失败→通过回归修复。当前读仅验证 Mapper 实际生成的锁定 SQL 和旧快照行为模型,不代表已运行真实 MySQL 多连接测试。未提交/推送。