发起支付
创建支付单,拿到支付页地址:
参数
返回:
Node SDK 的入参出参是 camelCase(如 outTradeNo),Python 与 HTTP 报文一致用 snake_case。
支付页形态(按渠道)
支付宝 qrcode:页面内嵌二维码。 适合充值页,用户不离开商户网站,手机支付宝扫码支付:
支付宝 redirect:跳转收银台。 服务端 302 或前端 location.href 跳转到 pay_url,
用户在支付宝收银台扫码或登录支付。
银商聚合码(channel: "chinaums" + pay_mode: "qrcode"):自己渲染二维码。
这个形态的 pay_url 是二维码的内容(银商账单地址),不是可打开的网页——不能放
iframe,普通浏览器也打不开(只能在微信、支付宝、云闪付内打开),前端用任意二维码库
把它渲染成码图即可:
用户拿微信、支付宝、云闪付任意一个 App 扫码,进银商收银台付款,用哪个钱包由用户 扫码的 App 决定。回调、查单、退款与支付宝渠道完全一致,不需要任何额外处理。
公众号支付(微信内打开的页面)
用户在微信里打开你的 H5 页面时(公众号菜单、聊天里分享的链接都算),页面里
展示二维码是没法付的——同一台手机扫不了自己屏幕上的码。这个场景用
channel: "chinaums" + pay_mode: "redirect":下单拿到的 pay_url 是银商收银台
的跳转地址,把用户整页跳过去,收银台自动唤起微信支付弹层,付完原路回跳。
你不需要有自己的微信公众号,也不需要接微信 OAuth 拿 openid——这些由银商收银台
用它自己的公众号主体完成,你只管跳转。同一个 pay_url 在支付宝、云闪付 App 里
打开也能付,收银台按环境自动适配。
前端在充值页按环境分流即可(微信内跳转、PC 出码),一个判断搞定:
几个要点:
- 拿到
pay_url后立即跳转——链接带时效签名,别缓存起来慢慢用。同单号重复下单 (幂等)返回的是同一条链接;用户中途退出再点支付,直接再跳原链接即可,若已临近expire_at或跳转被银商拒绝,换新单号重新下单 return_url的回跳页只做展示:页面加载后轮询你自己的订单状态接口确认到账。 微信渠道的回跳受微信「点金计划」策略影响可能不自动发生,用户手动返回你的页面时 轮询同样能兜住,所以回跳页和充值页都要能查单- 入账只认 webhook 回调(兜底查单),和其他形态完全一致
银商渠道需要顽兔侧为你的商户号开通后才可用(未开通时下单返回 50002);聚合码与
公众号支付在银商侧是两个产品,需要分别开通。是否已开通、何时开通,问顽兔运营即可;
代码侧只是下单参数的差别。
前端配合
扫码支付完成时,PC 页面不会收到任何事件。前端做两件事:
- 展示二维码后,轮询商户自己的订单状态接口(后端状态由回调驱动),到账后刷新页面
- 订单过期后引导用户重新下单。支付宝内嵌二维码约 2 分钟自动刷新,无需处理;
银商聚合码在
expire_at前一直有效
redirect 模式(含公众号支付)同理:回跳不可靠也不可信,结果页一律轮询自己的
订单状态接口,以后端(回调驱动)的状态为准。
重复下单
同一 out_trade_no:
- 参数完全相同,返回原单,不会重复创建
- 参数不同,返回错误码
40901,需要更换订单号
网络超时后用原参数重试是安全的。