写在前面
付款人可能从 H5 全量收银台(uni-app-casher)进,也可能从 小程序精简收银台(uniapp-casher-applet)进。
两端工程独立、AppID 不同、页面量差一个数量级,但业务上应共用同一套订单终态。
商户在商户端看单退款;运营在商服后台 / 运管台查单补单——入账只能进同一扇幂等门。
总览图
双收银台:代码里看见的差异
H5 全量 uni-app-casher |
小程序精简 uniapp-casher-applet |
|
|---|---|---|
| 注册页量级 | pages.json 二十余 path(收银/大额/全支付/转账/绑卡/PC…) |
仅 2 页:mini-pay + paystatus |
| 标题印象 | 「曲靖市商业银行收银台」「动态码付款」「网上支付」等 | 「收银台」「支付结果」 |
| 渠道常量 | 页面内 scene 多样:QRCODE / cashier / miniapp |
请求层固定 channelId = "WECHAT";支付 scene 如 miniapp、cashier、WEB |
| 前端该做的 | 拉起支付、展示结果、失败引导 | 轻量确认与结果 |
| 不该做的 | 自创成功态、跳过验签入账 | 在小程序里复制整套 H5 多入口 |
磁盘上小程序工程里也许还能看到 casher、bindcard 等目录——产品主路径以 pages.json 注册为准,别把未注册页写成已交付能力。
flowchart LR
subgraph entries [付款入口]
H5[H5 全量收银台]
MP[小程序收银台]
end
H5 --> Ord[订单服务]
MP --> Ord
Ord --> Notify[异步通知]
Notify --> Idem[幂等入账]
Idem --> MchtUI[商户端订单可见]
Idem --> Ops[商服后台/运管台可查]
channel / scene 可以分叉;订单状态机不要分叉。
推荐订单状态
| 状态 | 含义 | 谁先看见 |
|---|---|---|
CREATED |
本地已建单 | 收银台提交瞬间 |
PAYING |
已调通道 / 已出码 | 结果页「处理中」 |
SUCCESS |
通道确认成功 | 商户端订单列表 |
CLOSED |
关单、超时、取消 | 收银台失败态 |
REFUNDING / REFUNDED |
退款中 / 退完 | 商户端退款详情 |
stateDiagram-v2
[*] --> CREATED
CREATED --> PAYING: H5或小程序调下单
PAYING --> SUCCESS: 验签成功 notify
PAYING --> CLOSED: 关单/超时
SUCCESS --> REFUNDING: 商户端发起退款
REFUNDING --> REFUNDED: 全额退
REFUNDING --> SUCCESS: 部分退完成
硬规则:禁止 SUCCESS → PAYING;重复成功通知只 ACK;退款必须关联原支付单号。
幂等:所有入账只进一扇门
| 来源 | 说明 |
|---|---|
| 通道异步回调 | 主路径 |
| 超时查单补单 | 防丢通知 |
| PC 人工补单 | 商服后台或运管台,同一入账 API |
text
验签 → 找本地单 → 校验金额/商户号 →
已 SUCCESS:记重复日志,返回 success →
否则:事务内改状态 + 写支付流水 → 再驱动下游
商户端退款挂原支付单;部分退总额不超过原支付。
(状态机是收单通用设计;具体后端表名以服务端为准,本专栏不臆造库表细节。)
本篇小结
- 双收银台是入口与容器差异:全量多页 vs 两页确认支付。
- 差异留在 channel/scene;账本终态与幂等门必须合一。
- 下一篇:对账差分 + 商户可见结算 + 两套 PC 的资金分工。
专栏导航
| 序号 | 主题 |
|---|---|
| 01 | 六端全景 |
| 02 | 双收银台与幂等(本篇) |
| 03 | 对账结算:商户可见与运营日切 |
| 04 | 进件、巡检与客户经理作业 |
| 05 | 六端为何这样拆、合并怎么取舍 |
| 06 | 收单运管台 bmp-manage-vue |

全部评论(0)