在用JSAPI开发微信支付的时候,遇到了不少坑,我也对朋友说过,一步一坑。最后终于算是走出来了。期间翻阅过不少网友写的教程,可是都不实用,JAVA,Python都有看过,大多数都是复制粘贴,倍感失望。php
thinkphp5.0
php
前端
(开始使用JSAPI须要一个概念,就是在整个JSAPI的逻辑里面,只存在一个随机字符串
和一个 时间戳
。至关于JSAPI类里的全局。)git
注意:因为我这里用的http_build_query()
body里面的中文会被格式化,因此这里先建议body使用非中文,至于中文解决,能够用正则去替换,或者不用http_build_query()
github
public function __construct($total_fee, $body, $openid) { $rand = rand(11, 99); $mp_info = get_mpid_info();//获取微信信息 $this->appid = $mp_info['appid']; $this->nonce_str = nonceStr(32); $this->spbill_create_ip = Request::instance()->ip(); $this->mch_id = $mp_info['mch_id']; $this->key = $mp_info['paykey']; $this->timestamp = time(); $this->sign;//一次签名 $this->total_fee = $total_fee; $this->out_trade_no = time() . $rand; $this->notify_url = 'http://uedream.cn/index.php'; $this->body = $body; $this->openid = $openid; $this->sign_type = 'MD5'; $this->createsign(); //生成签名方法,须要结合createsign方法 }
以上是初始化签名结构体thinkphp
文档: https://pay.weixin.qq.com/wik...
public function createsign() { $build = [ 'appid' => $this->appid, 'body' => $this->body, 'mch_id' => $this->mch_id, 'nonce_str' => $this->nonce_str, 'notify_url' => $this->notify_url, 'openid' => $this->openid, 'out_trade_no' => $this->out_trade_no, 'sign_type' => $this->sign_type, 'spbill_create_ip' => $this->spbill_create_ip, 'timeStamp' => $this->timestamp, 'total_fee' => $this->total_fee, 'trade_type' => $this->trade_type, 'key' => $this->key, ]; $string = http_build_query($build); $string = str_replace('%2F', '/', $string); //格式化网址 $string = str_replace('%3A', ':', $string); //格式化网址 $md5 = md5($string); $this->sign = strtoupper($md5); }
文档: https://pay.weixin.qq.com/wik...
public function unifiedorder() { $data = [ 'appid' => $this->appid, 'body' => $this->body, 'mch_id' => $this->mch_id, 'nonce_str' => $this->nonce_str, 'notify_url' => $this->notify_url, 'openid' => $this->openid, 'out_trade_no' => $this->out_trade_no, 'sign' => $this->sign, 'sign_type' => 'MD5', 'spbill_create_ip' => $this->spbill_create_ip, 'timeStamp' => $this->timestamp, 'total_fee' => $this->total_fee * 1, 'trade_type' => $this->trade_type, ]; $xml = arrayToXml($data); $result = http_post(self::UNIFIEDORDER, $xml); $return = xmlToArray($result); $this->package = 'prepay_id=' . $return['prepay_id']; $this->renCreatesign();//这是二次签名。文档里面我是没有看到,反正我是卡到这里了。 $returns = [ 'appid' => $this->appid, 'noncestr' => $this->nonce_str, 'signtype' => $this->sign_type, 'package' => $this->package, 'sign' => $this->resign, 'timestamp' => $this->timestamp, ]; return $returns; }
统一下单请忽略的全部的回调参数,只要prepay_id
,其它的参数暂时看作障眼法,获取到了统一下单,还须要进行二次签名,上面代码里面有一个$this->renCreatesign()
,就是调用的二次签名方法api
文档: https://pay.weixin.qq.com/wik...
所谓的二次签名就是,appId
,nonceStr
,package
,signType
,timeStamp
,key
的加密。同样的签名方式,能够参考签名文档,进行签名。(上面参数已经按照ASCII进行排序,大小写也请按照给出的进行加密)
注意: package
格式为prepay_id=xxxxxxxxxxxx
。xxxx部分为统一下单获取的prepay_id
微信
代码参考:app
public function renCreatesign() { $build_data = [ 'appId' => $this->appid, 'nonceStr' => $this->nonce_str, 'package' => $this->package, 'signType' => $this->sign_type, 'timeStamp' => $this->timestamp, 'key' => $this->key, ]; $result = http_build_query($build_data); $put_data = str_replace('%3D', '=', $result); //格式化网址 $signatrue = md5($put_data); $this->resign = strtoupper($signatrue); }
至此,全部的签名应经完成,控制器使用unifiedorder()
进行参数获取。composer
这里开始使用jsapi作支付动做thinkphp5
WeixinJSBridge.invoke( "getBrandWCPayRequest", { appId: res.appid, //公众号名称,由商户传入 timeStamp: res.timeStamp, //时间戳,自1970年以来的秒数 nonceStr: res.nonce_str, //随机串 package: res.package, signType: res.signType, //微信签名方式: paySign: res.sign //微信签名 }, function(res) { alert(JSON.stringify(res)); if (res.err_msg == "get_brand_wcpay_request:ok") { // 使用以上方式判断前端返回,微信团队郑重提示: //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 } } );
前端全部须要调用的参数均在unifiedorder()
能够获取到。
这里提一下WeixinJSBridge.invoke
与wx.chooseWXPay
的区别。WeixinJSBridge.invoke
能够不用引用weixinjs即可使用,也不须要config。在安卓手机上也能回调出错误信息。wx.chooseWXPay
须要引用weixinjs,也须要使用config,并且在安卓手机上面的提示特别不友好。
微信支付文档说实话真的很坑 很坑。貌似写文档的小哥这天情绪很差。写出来的让人也感受到了情绪很差。以上为本人切身操做写出的教程。如还有补充的地方能够随时留言评论。
文档: https://github.com/datalinkag...
下载地址:
composer require datalinkage/wxpay