众所周知,微信提供了APP、公众号、小程序、H5及扫码等支付方式,而本文需要实现微信”扫一扫”自定义二维码支付功能; 而扫码支付中用到的二维码是微信规范的二维码(weixin://),H5需要在非微信浏览器才能打开;因此只剩下了公众号(或小程序),本文基于公众号支付为大家讲解下整个流程

步骤1. 准备appid、appsecret、支付key

进入微信公众平台,可以查到appid、appsecret;进入微信支付平台,可以找到支付key

步骤2. 获取openid

微信下单需要用到openid,因此需要先获取openid,可参考【获取openid 】:

(1)按微信要求实现服务回调接口
(2)用户访问如下地址,获取code
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

PS: scope为snsapi_base可以实现用户免授权,如果是snsapi_userinfo需要用户同意,本需求采用snsapi_base

REDIRECT_URI地址需要在微信公众号配置,可以配置根路径

(3)微信校验通过后,调用我们服务的redirect_uri/?code=CODE&state=STATE
(4)通过code换取openid
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

PS:通过上述接口,微信服务会返回openid

步骤3. 下单,获取prepay_id

调用微信公众号的统一下单接口

POST https://api.mch.weixin.qq.com/pay/unifiedorder
<xml>
<appid>wxbbe68ee8fadsf</appid>
<attach>test</attach>
<body>腾讯充值中心-QQ会员充值</body>
<mch_id>1435628102</mch_id>
<nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
<notify_url>http://www.weixin.qq.com/wxpay/pay.php</notify_url>
<out_trade_no>1415659999</out_trade_no>
<spbill_create_ip>110.90.119.97</spbill_create_ip>
<scene_info>{"h5_info": {"type":"Wap","wap_url": "https://pay.qq.com","wap_name": "腾讯充值"}}</scene_info>
<total_fee>1</total_fee>
<openid>ouytHt3crrPI1s2LHAs</openid>
<trade_type>JSAPI</trade_type>
<sign>2B753269B6A69A46615D54AFD047AB2A</sign>
</xml>

PS: total_fee是按分计算,sign按微信定义计算,可以通过微信提供的 sign校验工具 校验

如果成功会返回prepay_id

步骤4. 支付

function onBridgeReady(){
   WeixinJSBridge.invoke(
       'getBrandWCPayRequest', {
           "appId":"wxbbe68ee8fadsf",     //公众号名称,由商户传入
           "timeStamp": '',         //时间戳,自1970年以来的秒数
           "nonceStr":'', //随机串
           "package": '',
           "signType":"MD5",         //微信签名方式:
           "paySign":'' //微信签名
       },
       function(res){
           alert(res.err_msg);
           if(res.err_msg == "get_brand_wcpay_request:ok" ) {}     // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。
       }
   );
}

PS: prepayID填入上一步的prepay_id,paySign也是利用微信sign算法

上述过程完成后,即可弹出支付界面,用户输入支付密码确认支付后,即可完成,我们服务端根据回调接口notify_url进行后续的业务

总结

通过以上过程,我们可以自定义链接(即二维码),微信扫描我们二维码,跳转至我们自己的H5界面,我们在H5展现商品信息,并包含”去支付”按钮,用户点击支付后,我们重定向至获取code接口;之后在我们自己服务端完成下单、并返回带支付信息的H5,用户点击确认支付按钮,JS调用微信公众号的WeixinJSBridge.invoke接口,弹出微信自身的支付界面,用户输入密码并支付,我们根据支付回调,调用后续业务。

以上过程,用户不需要关注公众号,非常便捷,适用于停车场等场景。