背景: 最近做项目, 甲方提出一个需要要求在手机端直接微信注册成功后, 直接登录并发起微信支付. 再三思考后, 才决定使用 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:
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 生成新的支付签名.
以上便是我在做微信支付过程中的总结, 若有描述不当的请评论提出哦!
来源: https://www.cnblogs.com/xmdd/p/10320806.html