|
|
@@ -0,0 +1,226 @@
|
|
|
+# LINE Pay 商家扫码支付前端接入说明
|
|
|
+
|
|
|
+> 适用端:Foodie 商家 App(uni-app)
|
|
|
+>
|
|
|
+> 场景:客户出示 LINE Pay My Code,商家 App 扫码收款
|
|
|
+
|
|
|
+## 1. 前端整体流程
|
|
|
+
|
|
|
+按以下顺序接入:
|
|
|
+
|
|
|
+1. 商家端创建订单,支付方式传 `paymentMethod="3"`。
|
|
|
+2. 订单必须只有一个门店。
|
|
|
+3. 商家点击“LINE Pay 扫码收款”。
|
|
|
+4. 前端调用 `uni.scanCode` 扫描客户出示的 LINE Pay My Code。
|
|
|
+5. 扫码结果必须是 18 位数字,即 `oneTimeKey`。
|
|
|
+6. 前端把订单号 `ddId` 和 `oneTimeKey` 提交给扫码付款接口。
|
|
|
+7. 根据付款接口返回的 `status` 展示当前状态。
|
|
|
+8. 如果状态是处理中,定时调用状态查询接口。
|
|
|
+9. 只有后端返回 `PAID`,才能提示商家“收款成功”。
|
|
|
+
|
|
|
+## 2. 商家创建订单
|
|
|
+
|
|
|
+调用现有接口:
|
|
|
+
|
|
|
+```http
|
|
|
+POST /system/orderShOprate/createOrder
|
|
|
+Header: token
|
|
|
+```
|
|
|
+
|
|
|
+前端只需注意:
|
|
|
+
|
|
|
+- `paymentMethod` 必须传字符串 `"3"`。
|
|
|
+- `items` 只能有一个门店。
|
|
|
+- 创建成功后取得订单号 `ddId`。
|
|
|
+- 只有这个接口创建的商家订单可以使用扫码付款。
|
|
|
+
|
|
|
+商品、金额、备注、发票等字段继续使用商家端现有下单格式,不需要为 LINE Pay 新增字段。
|
|
|
+
|
|
|
+## 3. 扫描客户付款码
|
|
|
+
|
|
|
+前端调用 uni-app 扫码方法:
|
|
|
+
|
|
|
+```text
|
|
|
+uni.scanCode
|
|
|
+```
|
|
|
+
|
|
|
+需要支持:
|
|
|
+
|
|
|
+- 条形码。
|
|
|
+- 二维码。
|
|
|
+- 扫码结果必须匹配 18 位数字。
|
|
|
+
|
|
|
+扫码得到的内容作为 `oneTimeKey`。
|
|
|
+
|
|
|
+注意:
|
|
|
+
|
|
|
+- 不要打印 `oneTimeKey`。
|
|
|
+- 不要保存到本地缓存或数据库。
|
|
|
+- 不要把它放到页面 URL。
|
|
|
+- 每次客户重新生成 My Code 后,都要重新扫码。
|
|
|
+
|
|
|
+## 4. 提交扫码付款
|
|
|
+
|
|
|
+```http
|
|
|
+POST /system/orderShOprate/linePay/offline/pay
|
|
|
+Header: token
|
|
|
+Content-Type: application/json
|
|
|
+```
|
|
|
+
|
|
|
+请求参数:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "ddId": "202608180001",
|
|
|
+ "oneTimeKey": "123456789012345678"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+| 字段 | 类型 | 说明 |
|
|
|
+|---|---|---|
|
|
|
+| `ddId` | string | 商家端创建的订单号 |
|
|
|
+| `oneTimeKey` | string | 扫描得到的 18 位 LINE Pay My Code |
|
|
|
+
|
|
|
+成功响应:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": 200,
|
|
|
+ "msg": "操作成功",
|
|
|
+ "data": {
|
|
|
+ "ddId": "202608180001",
|
|
|
+ "paymentId": 84,
|
|
|
+ "lineOrderId": "LPOFF123456789",
|
|
|
+ "transactionId": "2026081800000000001",
|
|
|
+ "status": "AUTH_REQUIRED",
|
|
|
+ "reusedAttempt": false,
|
|
|
+ "updatedAt": "2026-08-18T12:34:56+08:00"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+前端主要使用:
|
|
|
+
|
|
|
+- `status`:判断付款状态。
|
|
|
+- `reusedAttempt`:判断后端是否复用了已有支付记录。
|
|
|
+- `transactionId`:仅用于展示或排查,必须作为字符串处理。
|
|
|
+
|
|
|
+`reusedAttempt=true` 表示订单已经有一笔付款正在处理。本次新扫描的付款码没有再次发送给 LINE,前端直接查询原付款状态,不要再次扫码或提交付款。
|
|
|
+
|
|
|
+## 5. 查询付款状态
|
|
|
+
|
|
|
+```http
|
|
|
+GET /system/orderShOprate/linePay/offline/status?ddId=202608180001
|
|
|
+Header: token
|
|
|
+```
|
|
|
+
|
|
|
+响应 `data` 与付款接口基本相同,前端继续读取 `data.status`。
|
|
|
+
|
|
|
+查询时机:
|
|
|
+
|
|
|
+- 付款接口返回 `AUTH_REQUIRED`。
|
|
|
+- 付款接口返回 `PROCESSING`。
|
|
|
+- App 从后台回到前台。
|
|
|
+- 商家重新打开订单详情。
|
|
|
+- 付款接口发生网络超时。
|
|
|
+
|
|
|
+建议处理中每 5 秒查询一次。页面退出后停止轮询;重新进入页面时再查询一次。
|
|
|
+
|
|
|
+## 6. 状态处理
|
|
|
+
|
|
|
+| `status` | 含义 | 前端操作 |
|
|
|
+|---|---|---|
|
|
|
+| `AUTH_REQUIRED` | 客户需要在 LINE Pay 完成选择付款方式或认证 | 提示客户在 LINE Pay 完成操作,继续查询状态,不允许重新扫码 |
|
|
|
+| `PROCESSING` | 后端正在确认付款结果 | 显示“支付结果确认中”,继续查询状态,不允许重新扫码 |
|
|
|
+| `PAID` | 付款成功 | 停止查询,提示商家收款成功,刷新订单 |
|
|
|
+| `CANCELLED` | 客户取消或付款码过期 | 停止查询,允许客户生成新的 My Code 后重新扫码 |
|
|
|
+| `FAILED` | 付款明确失败 | 停止查询,允许客户生成新的 My Code 后重新扫码 |
|
|
|
+| `MANUAL_REVIEW` | 金额异常或付款结果需要人工核对 | 停止查询,提示联系平台处理,不允许重新扫码 |
|
|
|
+
|
|
|
+前端必须遵守:
|
|
|
+
|
|
|
+- 扫码成功不等于付款成功。
|
|
|
+- HTTP 请求成功不等于付款成功。
|
|
|
+- 存在 `transactionId` 不等于付款成功。
|
|
|
+- 只有 `status="PAID"` 才是收款成功。
|
|
|
+
|
|
|
+## 7. 网络异常处理
|
|
|
+
|
|
|
+### 付款接口超时
|
|
|
+
|
|
|
+如果 `/offline/pay` 超时或断网:
|
|
|
+
|
|
|
+1. 不要自动重发付款接口。
|
|
|
+2. 不要重新使用刚才的 `oneTimeKey`。
|
|
|
+3. 网络恢复后调用 `/offline/status` 查询订单状态。
|
|
|
+4. 根据状态查询结果继续处理。
|
|
|
+
|
|
|
+原因是 LINE 可能已经收到付款请求,重复提交可能造成重复付款风险。
|
|
|
+
|
|
|
+### 状态查询失败
|
|
|
+
|
|
|
+- 提示“支付结果暂时无法确认,请稍后查询”。
|
|
|
+- 不要直接显示付款失败。
|
|
|
+- 不要自动重新扫码。
|
|
|
+- 商家重新进入订单页面后再次查询。
|
|
|
+
|
|
|
+## 8. 接口错误处理
|
|
|
+
|
|
|
+项目接口统一返回:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": 500,
|
|
|
+ "msg": "业务错误信息"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+- `code === 200`:读取 `data`。
|
|
|
+- `code !== 200`:展示后端返回的 `msg`。
|
|
|
+- 不要根据中文 `msg` 判断付款状态。
|
|
|
+- 付款状态只根据成功响应中的 `data.status` 判断。
|
|
|
+
|
|
|
+## 9. Sandbox 联调步骤
|
|
|
+
|
|
|
+Online API v4 和 Offline API v4 共用现有 Channel ID / Channel Secret,不需要重新注册 Sandbox。
|
|
|
+
|
|
|
+测试步骤:
|
|
|
+
|
|
|
+1. 后端使用 Sandbox 环境。
|
|
|
+2. 测试门店已经录入并启用 Channel ID / Channel Secret。
|
|
|
+3. 商家端创建 `paymentMethod="3"` 的单门店订单。
|
|
|
+4. 打开台湾 Sandbox My Code 生成器:
|
|
|
+
|
|
|
+```text
|
|
|
+https://sandbox-web-pay.line.me/web/sandbox/payment/oneTimeKey?countryCode=TW&paymentMethod=balance
|
|
|
+```
|
|
|
+
|
|
|
+5. 商家 App 扫描生成的测试付款码。
|
|
|
+6. 调用 `/offline/pay`。
|
|
|
+7. 如果返回处理中,继续调用 `/offline/status`。
|
|
|
+8. 最终返回 `PAID` 后提示收款成功。
|
|
|
+
|
|
|
+Sandbox 环境不能使用客户真实 LINE App 生成的 My Code。
|
|
|
+
|
|
|
+## 10. 前端验收清单
|
|
|
+
|
|
|
+- [ ] 商家下单时 `paymentMethod="3"`。
|
|
|
+- [ ] 一笔订单只有一个门店。
|
|
|
+- [ ] 使用 `uni.scanCode` 扫描条形码和二维码。
|
|
|
+- [ ] 扫码结果必须为 18 位数字。
|
|
|
+- [ ] `oneTimeKey` 不记录、不缓存、不打印。
|
|
|
+- [ ] 提交付款期间禁用重复扫码。
|
|
|
+- [ ] `AUTH_REQUIRED` 和 `PROCESSING` 会继续查询状态。
|
|
|
+- [ ] 只有 `PAID` 提示收款成功。
|
|
|
+- [ ] `CANCELLED` 和 `FAILED` 才允许重新扫码。
|
|
|
+- [ ] `MANUAL_REVIEW` 不允许重新扫码。
|
|
|
+- [ ] 付款接口超时后不自动重发,只查询状态。
|
|
|
+- [ ] App 回到前台或重新进入订单页面时重新查询状态。
|
|
|
+
|
|
|
+## 11. 接口汇总
|
|
|
+
|
|
|
+| 操作 | 方法 | 接口 |
|
|
|
+|---|---|---|
|
|
|
+| 商家创建订单 | POST | `/system/orderShOprate/createOrder` |
|
|
|
+| 提交扫码付款 | POST | `/system/orderShOprate/linePay/offline/pay` |
|
|
|
+| 查询付款状态 | GET | `/system/orderShOprate/linePay/offline/status?ddId={ddId}` |
|