微信jspai支付是在微信浏览器执行的一种支付方式,用于微信公众号某个页面支付、微信打开的H5网页支付等
首先要有认证的微信服务号,并且开通微信支付。或者在微信商户平台开通jsapi支付,绑定认证过的服务号,在服务号后台确认绑定即可(双向)
登录微信支付平台,下载支付证书
在微信公众平台设置回调域名,在商户平台绑定支付域名
在微信内部浏览器支付,需要做微信登录,因为微信要求用户openid为必传项(它可能要知道谁在支付)
支付步骤简单来说可分以下几步:
1、获取code
2、获取openid
3、拉起微信支付
4、回调告诉微信支付完成
使用方法:
在WxPay.Config.php中填写支付配置
appid:公众号appid
appsecret:公众号appsecret
mch_id:微信商户平台,商户id
key:微信商户平台,商户支付密钥
还有支付证书的路径,下载证书后,根据自己服务器的路径填写,具体到文件名
在WxPay.JsApiPay.php文件的GetOpenid()方法中,$baseUrl为获取openid后跳转的页面,当前Demo中默认跳转回原先的页面,可以在此方法中判断openid是否为空,不为空时,把openid存储到cookie中,再执行自己的代码
Demo介绍:
index.php包含支付的获取openid方法、统一下单方法,回调方法
wx_pay.html为获取openid后跳转的页面,如果参数无误,可以直接拉起微信支付收银台
其余文件为微信jsapi支付官方sdk文件
常见错误:
1、用ajax获取支付参数时,微信报错:支付缺少参数:appId
这是因为WeixinJSBridge.invoke()方法要求传入的是一个对象,而ajax拿到的参数是字符串,将字符串转移为对象即可:JSON.parse()
2、提示 Notice: “Undefined property: JsApiPay::$curl_timeout in
打开WxPay.JsApiPay.php,将curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout)修改为curl_setopt($ch, CURLOPT_TIMEOUT, 30),指30s
3、需要注意的一点,在获取用户openid时,微信会有验证code合法性的操作,所以要来回跳转几次,这种需要直接跳转的,ajax是不能直接操作的,一但openid拿不到,直接下单可能会报“参数错误”或者直接走error方法
对于openid,我暂且想到两种解决方法:
⑴ 在进入下单页面时,同时请求openid,拿到后存到页面的js变量中或其它地方;
⑵ 做一个中转页面,这个页面负责获取openid,页面后加回调地址redirect_url参数,拿到openid后跳转回调地址,可把openid加到地址中,也可以存cookie等
请仔细思考上面的四个支付步骤,通过code验证合法后,再获取openid,这是必须的,第一步就是获取code,所以这个很重要!
我的博客中有专门写过微信登录,此处不明白的可以找一下那篇文章详细了解。
需要注意:回调中一定要告诉微信,支付完成,否则微信不知道支付结果,会在24小时内不停请求回调接口。
加密sign时,目前有HMAC-SHA256和MD5两种方式,如果选择HMAC-SHA256,加密时需要多加一个字符串,这也意味着回调验证sign时,需要相同的字符串做HMAC-SHA256(这里可以考虑使用微信提供的key),虽然安全性提升,但代码简易度稍高于md5,主要问题在于做HMAC-SHA256加密的字符串要保持一致性,若jsapi下单的sdk和回调程序,可使用相同的配置文件,这段文字可以忽略。
下单成功后返回的参数(微信内alert弹出):
后端收到的参数,更直观一些(json格式和参数数量均为原版,可以参考):
支付成功,微信请求回调时的参数
PHP后端代码:
前端代码:
上面的代码中,正确步骤是:先访问wx_pay方法,拿到openid后,再跳转到前端页面