背景:最近作项目,甲方提出一个须要要求在手机端直接微信注册成功后,直接登陆并发起微信支付。再三思考后,才决定使用jsapi微信支付。php
微信支付官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1html
首先微信普通商户版有NATIVE支付、JSAPI支付、APP支付、H5支付、付款码支付、小程序支付;其中我认为做为web开发的最经常使用的是native、jsapi、h5支付了。可是jsapi支付在官方微信支付文档中,留下了不少坑,致使在使用过程当中无比麻烦,下面具体来讲说,但愿能对各位看客有点帮助。前端
1.微信支付最麻烦的即是公众平台和商户平台的配置,将公众号APPID、APPSECRET,商户号appid、秘钥key配置好。web
商户平台:(https://pay.weixin.qq.com/)小程序
1)微信商户平台->产品中心->个人产品,查看你要的支付类型是否开通,未开通,则申请开通,按照开通流程走,主要是申请安装证书便可。api
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:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
参数说明:APPID:微信公众平台AppId;
REDIRECT_URI:回调地址,在配置时须要配置域名,此处的回调地址域名必须与配置的一致不然无效。
SCOPE:默认拥有scope参数中的snsapi_base和snsapi_userinfo,此处是jsapi支付,必须使用snsapi_userinfo,不然会出现“此公众号并无这些scope的权限,错误码:10005”的提示;
STATE:随机参数,能够用来区分或者携带其余参数到回调地址中;
返回值:code做为换取access_token的临时票据和state随机参数。
第二步:经过code换取网页受权access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
参数说明: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生成新的支付签名。
以上即是我在作微信支付过程当中的总结,如有描述不当的请评论提出哦!