背景:最近做项目,甲方提出一个需要要求在手机端直接微信注册成功后,直接登录并发起微信支付。再三思考后,才决定使用jsapi微信支付。
微信支付官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
首先微信普通商户版有NATIVE支付、JSAPI支付、APP支付、H5支付、付款码支付、小程序支付;其中我认为作为web开发的最常用的是native、jsapi、h5支付了。但是jsapi支付在官方微信支付文档中,留下了很多坑,导致在使用过程中无比麻烦,下面具体来说说,希望能对各位看客有点帮助。
1.微信支付最麻烦的便是公众平台和商户平台的配置,将公众号APPID、APPSECRET,商户号appid、秘钥key配置好。
商户平台:(https://pay.weixin.qq.com/)
1)微信商户平台->产品中心->我的产品,查看你要的支付类型是否开通,未开通,则申请开通,按照开通流程走,主要是申请安装证书即可。
2)微信商户平台->产品中心->开发配置,查看支付配置是否已经配置成功。native支付则配置扫码支付回调地址,jsapi支付则配置公众号支付授权目录,该目录最多可添加5个,如发起支付页面为:http://baidu.com/index.html,则目录配置为:http://baidu.com/;如发起支付页面为:http://baidu.com/wxpay/index.html,则目录配置为:http://baidu.com/wxpay/;(这一步很关键,不然会在发起支付时提示注册url无效)
3)微信商户平台->账户中心->账户设置->API安全,查看是否已经设置了商户**key,此**在后面生成签名sign中特别重要,必须设置,设置成功后记住**;
以上是商户平台的配置;
微信公众平台:(https://mp.weixin.qq.com/)
1)微信公众平台->开发->基本配置,查看开发者密码AppSecret是否已经设置;
2)微信公众平台->设置->公众号设置,查看网页回调地址是否已经配置好,在这里我将所有的域名配置都配置好了。需要将MP_verify_MHYOHtHKmJzSkCj0.txt文件放置到项目的根目录下,只要访问域名后可以访问到就可以,如配置域名:baidu.com,则访问http://baidu.com/MP_verify_MHYOHtHKmJzSkCj0.txt时访问得到就表示配置成功。
以上是公众平台需要的配置。
2.配置完后,查看商户平台的jsapi微信支付开发文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1,在微信浏览器内发起支付之前,必须先获得预支付订单号prepay_id,也就是这个订单号,需要大费周折的去拼接各种数据;
1)由于获取prepay_id的必填参数中有openid,所以先获取openid,通过公众平台网页授权来获取。
微信公众平台->开发->接口权限->网页服务->网页授权(网页授权获取用户基本信息 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842)
第一步:用户同意授权,获取code:
参数说明:APPID:微信公众平台AppId;
REDIRECT_URI:回调地址,在配置时需要配置域名,此处的回调地址域名必须与配置的一致否则无效。
SCOPE:默认拥有scope参数中的snsapi_base和snsapi_userinfo,此处是jsapi支付,必须使用snsapi_userinfo,否则会出现“此公众号并没有这些scope的权限,错误码:10005”的提示;
STATE:随机参数,可以用来区分或者携带其他参数到回调地址中;
返回值:code作为换取access_token的临时票据和state随机参数。
第二步:通过code换取网页授权access_token:
参数说明:APPID:微信公众平台AppId;
SECRET:微信公众号**,需要配置;
CODE:第一步获得的code参数;
返回值:access_token和openid,此处只写明这两个较为重要的参数。
到目前为止便得到了openid。可以进行统一下单了。
2).查看API列表->统一下单(调用该接口是为了在微信支付服务后台生成预支付交易单)
接口链接:https://api.mch.weixin.qq.com/pay/unifiedorder
请求参数:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1 查看官方文档,此处重点点名:openid,此次为JSAPI,所以必填;sign签名是整个请求参数中最难生成的。
当返回结果return_code 和result_code都为SUCCESS,可以获得prepay_id.
3)得到预订单号后,就可以在微信内置浏览器中发起支付。将统一下单接口返回的数据中拿到appid、nonce_str、prepay_id,并结合signType、timeStamp、key(商户号)通过MD5加密返回paySign支付签名,将这些数据一并返回前端页面调用微信内置对象WeixinJSBridge,发起支付。(微信内h5调起支付链接:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6 )
整个支付就到此结束了。
在这个过程中,我遇到的最惨痛的难点就是支付签名paySign的生成,因为在微信统一下单接口返回的数据中还包含了sign签名的返回,我一直以为可以使用这个作为支付签名。然而在网上找了很多大佬的总结后,都说统一下单接口返回的sign的签名加密方式不是MD5,然而支付签名必须是MD5加密而造成的。但是我觉得不是,因为我已经明确在下单接口中的参数signType写明就是MD5了,所以表示下单接口返回的sign并不能作为微信发起支付的签名paySign。必须自己重新根据返回的prepay_id生成新的支付签名。
以上便是我在做微信支付过程中的总结,若有描述不当的请评论提出哦!