在使用JSAPI开发微信支付的时候,遇到了很多坑。我还告诉我的朋友,每一步都是陷阱。它终于出来了。期间看了很多网友写的教程,但都不实用。JAVA和Python我都看过,但是大部分都是复制粘贴,很扫兴。开发环境thinkphp5.0php(开始使用JSAPI需要一个概念,就是在整个JSAPI的逻辑中,只有一个随机字符串和一个时间戳。相当于JSAPI类中的global。)注意:由于我这里使用的http_build_query()body中的中文会被格式化,所以建议body使用非中文。至于中文的方案,可以用正则表达式代替,或者开始开发全局初始化public函数不用http_build_query()__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()。$兰特;$this->notify_url='http://uedream.cn/index.php';$this->body=$body;$this->openid=$openid;$this->sign_type='MD5';$this->createsign();//生成签名方法需要结合createsign方法}以上是初始化签名结构获取签名文档:https://pay.weixin.qq.com/wik...publicfunctioncreatesign(){$构建=['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...publicfunctionunifiedorder(){$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($数据);$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,];返回$返回;}统一下单请忽略所有回调参数,只有prepay_id,其他参数暂时当蒙眼,get到统一下单时需要二次签名。上面代码中有个$this->renCreatesign(),就是调用的第二个签名方法。二次签名文档:https://pay.weixin.qq.com/wik...所谓二次签名就是对appId、nonceStr、package、signType、timeStamp、key进行加密。同样的签名方式,可以参考签名文档进行签名。(以上参数已按ASCII码排序,请加密大小写)注:包格式为prepay_id=xxxxxxxxxxxx。xxxx部分是统一命令获取的prepay_id代码参考:publicfunctionrenCreatesign(){$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);//格式化URL$signatrue=md5($put_data);$this->resign=strtoupper($signatrue);至此,所有签名都应该完成后,controller使用unifiedorder()进行参数获取。前端开始使用jsapi做支付动作WeixinJSBridge.invoke("getBrandWCPayRequest",{appId:res.appid,//公众号name,商家传入timeStamp:res.timeStamp,//Timestamp,since1970SecondsnonceStr: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的情况下使用,不需要配置。错误消息也可以在Android手机上回调。wx.chooseWXPay需要引用weixinjs,还需要使用config,安卓手机提示特别不友好。结语说实话,微信支付单据真的很坑爹。看来写文档的小哥那天心情不好。我写的东西让我感觉很糟糕。以上是我自己写的教程。如果您有任何补充,请随时发表评论。彩蛋文档:https://github.com/datalinkag...下载地址:composerrequiredatalinkage/wxpay
