9.0 KiB
9.0 KiB
小程序接口文档:在线支付(旺铺网关 JSAPI)
门店端在线支付:选择本店未支付账单合并付款,后端经旺铺支付网关(统一下单B-JSAPI)下单, 小程序调起
wx.requestPayment完成支付;支付结果由网关后台通知自动结账, 小程序端也可主动查询同步结果(回调延迟/丢失时的兜底)。结账效果与线下凭证审核一致:关联账单批量置「已支付」、累加门店总采购金额、门店收到支付成功通知。
整体流程
小程序 后端 旺铺网关 微信
│ wx.login → code │ │ │
│ POST /mini/payment/online (bill_ids, code) │ │
│────────────────────▶│ code2session 换 openid │──────────────────▶│
│ │ 创建支付单+锁定账单 │ │
│ │ 统一下单(mer_order_id=支付单号) ──────────▶│
│ 返回 pay_params │◀──────── order_id + 调起参数 ────────────│
│◀────────────────────│ │ │
│ wx.requestPayment(pay_params) ─────────────────────────────────▶│
│ │ POST /mini/payment/notify(支付成功通知) │
│ │◀───────────────────────│ │
│ │ 验签 → 幂等结账 → 应答 {"code":"00"} │
│ GET .../query 主动同步(兜底) │ │
│────────────────────▶│ 交易查询 → 已支付则结账 │ │
通用约定
| 项 | 值 |
|---|---|
| 鉴权 | 门店 token:Authorization: Bearer <token>(登录见 /mini/auth/login) |
| 响应格式 | `{ "success": true |
| 金额单位 | 元,字符串/数字两位小数(如 150.50) |
1. 发起在线支付(合并账单下单)
| 项 | 值 |
|---|---|
| 请求方式 | POST |
| 路径 | /mini/payment/online |
| 鉴权 | 门店 token |
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
bill_ids |
int[] | 是 | 要合并付款的账单 ID 数组(GET /mini/bill?payable=1 返回的 id),至少 1 个 |
code |
string | 是 | 小程序 wx.login() 返回的登录凭证(后端用它换付款人 openid) |
remark |
string | 否 | 付款备注,最长 255 字 |
校验规则(失败均返回 success:false)
- 账单必须全部属于当前门店,且为「未支付」且未被其他支付单锁定;
- 任一账单已支付 / 正在支付中(含凭证审核中)→ 拒绝并提示对应账单号;
- 合计金额必须大于 0;
- 微信
code无效(code2session 失败)→ 报错,不产生支付单; - 网关下单失败 → 支付单自动作废、账单释放,可重新发起。
响应示例
{
"success": true,
"msg": "下单成功,请调起支付",
"data": {
"id": 12,
"payment_no": "ZF202608270001",
"amount": "150.50",
"pay_params": {
"order_id": "202608271201444525348059",
"tradeNo": "2021082722001407831438768160",
"user_openid": "oXxx123"
}
}
}
字段说明
| 字段 | 说明 |
|---|---|
payment_no |
本系统支付单号(即上送网关的商户订单号 mer_order_id),后续查询/对账用 |
amount |
应付金额(= 所选账单总额合计,元) |
pay_params |
旺铺网关 data 节点原样透传。调起支付所需参数以网关返回为准(服务商配置后通常包含 timeStamp/nonceStr/package/signType/paySign 等),直接透传给 wx.requestPayment 即可 |
小程序端调用示例
// 1. 获取登录凭证
const { code } = await wx.login();
// 2. 后端下单
const res = await request.post('/mini/payment/online', { bill_ids: [101, 102], code });
const { payment_no, pay_params } = res.data;
// 3. 调起微信支付(pay_params 以旺铺网关实际返回的调起参数为准)
await wx.requestPayment({
timeStamp: pay_params.timeStamp,
nonceStr: pay_params.nonceStr,
package: pay_params.package,
signType: pay_params.signType || 'RSA',
paySign: pay_params.paySign,
});
// 4. 支付完成后主动同步结果(回调兜底)
const q = await request.get(`/mini/payment/online/${payment_no}/query`);
// q.data.status === 1 → 支付成功,刷新账单列表
2. 查询支付结果(主动同步)
| 项 | 值 |
|---|---|
| 请求方式 | GET |
| 路径 | /mini/payment/online/{payment_no}/query |
| 鉴权 | 门店 token(仅可查询本店支付单) |
路径参数
| 参数 | 说明 |
|---|---|
payment_no |
下单返回的支付单号(如 ZF202608270001) |
行为说明
- 本地已是「支付成功」→ 直接返回,不再请求网关;
- 否则向旺铺网关发起「交易查询」,网关返回已支付(
order_status=1)则立即结账(与后台通知同一幂等逻辑); - 建议在
wx.requestPayment成功回调后、以及付款页onShow时各调一次; - 用户中途取消支付时本接口返回
status: 0,账单仍处于锁定中,可稍后重试或联系客服释放。
响应示例
{
"success": true,
"msg": "支付成功",
"data": {
"payment_no": "ZF202608270001",
"status": 1,
"status_name": "支付成功",
"paid_at": "2026-08-27 10:00:00",
"trade_no": "2021082722001407831438768160"
}
}
status 取值
| 值 | 含义 |
|---|---|
0 |
待支付(网关未确认) |
1 |
支付成功(账单已置已支付) |
2 |
支付失败(网关下单失败作废,账单已释放,可重新下单) |
3. 支付结果后台通知(服务端对接,无需小程序调用)
| 项 | 值 |
|---|---|
| 请求方式 | POST(表单) |
| 路径 | /mini/payment/notify |
| 鉴权 | 无(公开路由,以报文 sign 验签) |
| 来源 | 旺铺网关(下单时上送的 notifyurl,由后端自动生成:{APP_URL}/mini/payment/notify) |
处理逻辑
- 按旺铺加签规则验签(参数 ASCII 升序
key=value以&拼接 +&key=SignKey,MD5 大写); - 验签失败 → 应答
{"code":"01"}; - 按
mer_order_id定位支付单,校验order_status=1且order_amt与支付单金额一致(防篡改); - 幂等结账:支付单置成功(记录
trade_no/order_id/支付时间)→ 关联账单批量置已支付 → 累加门店总采购金额(只统计商品金额)→ 站内通知门店; - 重复通知直接应答成功,不重复结账。
应答报文(网关约定格式)
{ "code": "00", "msg": "成功", "timestamp": "20260827100000123" }
网关收到 code=00 才认为通知成功,否则按 2ⁿ 分钟重试 7 次。
后台配置(上线前必配)
配置优先级:后台「系统设置 → 支付配置」> .env。
后台支付配置(site_config pay 组,已内置配置项)
| 配置项 | 说明 |
|---|---|
wangpu_base_url |
旺铺网关域名(接口地址前缀) |
wangpu_organiz_no |
合作机构渠道号 organiz_no |
wangpu_mer_no |
旺铺内部商户号 mer_no(进件入网后返回) |
wangpu_mer_code |
商户号 mer_code |
wangpu_term_code |
终端号 term_code |
wangpu_sign_key |
加签专用 Key(SignKey) |
wangpu_sub_appid |
下单微信子 appid,留空取小程序自身 appid |
wangpu_payway_code |
支付方式代码(默认 WECHAT_MINI,以旺铺数据词典为准) |
.env 备选配置
WECHAT_MINI_APPID= # 小程序 AppID(code2session 必需)
WECHAT_MINI_SECRET= # 小程序 Secret(code2session 必需)
WANGPU_BASE_URL=
WANGPU_ORGANIZ_NO=
WANGPU_MER_NO=
WANGPU_MER_CODE=
WANGPU_TERM_CODE=
WANGPU_SIGN_KEY=
WANGPU_SUB_APPID=
WANGPU_PAYWAY_CODE=WECHAT_MINI
注意:
APP_URL必须是网关可访问的公网 HTTPS 地址,否则支付成功通知无法送达(此时依赖小程序主动查询兜底结账)。
与线下凭证支付的关系
两种付款方式并存,同一张账单同一时刻只能处于一条支付链路:
| 在线支付(本档) | 线下凭证支付 | |
|---|---|---|
| 入口 | POST /mini/payment/online |
POST /mini/payment |
支付单 pay_type |
2 |
1 |
支付单 pay_method |
4 旺铺支付 |
1 微信 / 2 支付宝 / 3 对公汇款 |
| 结账方式 | 网关通知/主动查询自动结账 | 后台审核通过 |
| 失败/拒绝 | 账单自动释放可重新付款 | 审核拒绝后释放 |
账单被任一支付单锁定期间(payment_id ≠ 0),两种入口均会拒绝重复提交。