【坑爹微信】微信支付相关问题解决
目录
1. 那一抹淡淡的忧伤—–微信开发基础
2. 用纯js是不可能用纯js了,这辈子都不用纯js了 —– 微信JSSDK开发以及问题解答
3. 要你命3000 —— 微信支付开发系列问题解决
导语
为什么要开发微信和微信开发的优势我就不用多说了吧。微信支付的方式分好几种:
1.扫码支付
2.公众号支付
3.APP支付
不管是那种支付方式,都要用到统一下单这个接口,而一般大多数人都会卡在预支付id没有拿到这一步,今天就主要分析预支付id的获取和问题解决
开发前准备
- 一个开通了微信支付的公众号
- 确保将安全授权目录配置好了
- 支付回调地址配置好了
如果不知道怎么配置,请看这里
步骤一:发起支付准备
生成商户订单
先要根据自己的业务逻辑生成自己可读的商户订单号,一般推荐年月日+随机数+用户uid
使用微信统一下单接口,获得微信的预支付信息,对于统一下单接口的详细信息可以看这里
第一步:
我们先实例化微信统一下单接口的类,这个类在微信支付V3demo里有,当然在这里我将微信demo类库再次封装加入命名空间更好的适应Thinkphp。
UnifiedOrder_pub类:
<?phpnamespace Org\Weixinpay; use Org\Weixinpay\Wxpay_client_pub; use Org\Weixinpay\WxPayConf_pub; use Org\Weixinpay\SDKRuntimeException; /*** 统一支付接口类*/class UnifiedOrder_pub extends Wxpay_client_pub{function __construct($appid,$mchid,$key,$appsecret){Common_util_pub::__construct($appid,$mchid,$key,$appsecret);//设置接口链接$this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//设置curl超时时间$this->curl_timeout = 60;}/*** 生成接口参数xml*/function createXml(){try{//检测必填参数if($this->parameters["out_trade_no"] == null){throw new SDKRuntimeException("缺少统一支付接口必填参数out_trade_no!"."<br>");}elseif($this->parameters["body"] == null){throw new SDKRuntimeException("缺少统一支付接口必填参数body!"."<br>");}elseif ($this->parameters["total_fee"] == null ) {throw new SDKRuntimeException("缺少统一支付接口必填参数total_fee!"."<br>");}elseif ($this->parameters["notify_url"] == null) {throw new SDKRuntimeException("缺少统一支付接口必填参数notify_url!"."<br>");}elseif ($this->parameters["trade_type"] == null) {throw new SDKRuntimeException("缺少统一支付接口必填参数trade_type!"."<br>");}elseif ($this->parameters["trade_type"] == "JSAPI" &&$this->parameters["openid"] == NULL){throw new SDKRuntimeException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!"."<br>");}$this->parameters["appid"] = $this->appid;//公众账号ID$this->parameters["mch_id"] = $this->mchid;//商户号//$this->parameters["sub_mch_id"] = "1xxxxxxx2";//子商户号 $this->parameters["spbill_create_ip"] = get_client_ip();//终端ip$this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串$this->parameters["sign"] = $this->getSign($this->parameters);//签名return $this->arrayToXml($this->parameters);}catch (SDKRuntimeException $e){return array('return_code'=>'FAIL','return_msg'=>$e->errorMessage());}}/*** 获取prepay_id*/function getPrepayId(){$this->postXml();$this->result = $this->xmlToArray($this->response);return $this->result;}}我们实例化UnifiedOrder_pub,并依此传入参数,$appid,$mchid,$key,$appsecret
//appid 商家appid //mchid 商家商户号 //key 商家支付秘钥 //appsecret JSAPI获准码//调用统一下单$unifiedOrder = new UnifiedOrder_pub($this->config['pay_weixin_appid'],$this->config['pay_weixin_mchid'],$this->config['pay_weixin_key'],$this->config['pay_weixin_appsecret']);waring:在第一步里面会出的错误就是你的四个参数没有按顺序给对,记住这里面的参数一定要按顺序给,并且你要检查你的四个参数是否是有效的没有过期
在第一步出错的同学都不能吊起微信支付的样式,即下图:
但是如果你写入了调试js的话可以看见具体错误,这里就不提调试js了。
第二步:向统一下单接口中添加所需参数
$unifiedOrder->setParameter("openid",$this->user_info['openid']);//用户微信唯一标识$unifiedOrder->setParameter("body",$this->order_info['order_name']);//商品描述$unifiedOrder->setParameter("out_trade_no",$order_no);//商户订单号$unifiedOrder->setParameter("total_fee",floatval($pay_money*100));//总金额$unifiedOrder->setParameter("notify_url",$notice_url);//通知地址$unifiedOrder->setParameter("trade_type","JSAPI");//交易类型warning: 在第二步中,尤其要注意的就这个通知地址的格式,通知地址一定不能带任何参数的地址,包括你是pathinfo模式也好,只能以www.xxxxx.com/index.php这种模式结尾。
www.xxx.com/index.php?a=index,www.xxx.com/index.php/admin/index 这样的写法全部是错的。
第三步:获取预支付信息
将上述内容提交给接口,正确可返回预支付ID
$prepay_result = $unifiedOrder->getPrepayId();如果错误,我们可以打印来查看是什么错误
var_dump($prepay_result); $prepay_result['return_code'] == 'FAIL'//标志支付失败 $prepay_result['return_msg']//这个角标中有具体错误信息打印看看! //缺少统一支付接口必填参数out_trade_no! //缺少统一支付接口必填参数body //缺少统一支付接口必填参数total_fee! //缺少统一支付接口必填参数notify_url! //...等等一些的错误提示,大家可以打印出来看看,然后对照着修改当我们已经拿到预支付ID的时候,那么支付准备已经完成
调起JSAPI支付
第一步:在前台文件中我们使用注册支付JSAPI
//调起支付必备参数准备 function onBridgeReady(msg_json){WeixinJSBridge.invoke('getBrandWCPayRequest', {"appId":msg_json.appId, //公众号名称,由商户传入"timeStamp":msg_json.timeStamp, //时间戳,自1970年以来的秒数"nonceStr":msg_json.nonceStr, //随机串"package":msg_json.package,"signType":msg_json.signType, //微信签名方式:"paySign":msg_json.paySign //微信签名},function(res){// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。if(res.err_msg == "get_brand_wcpay_request:ok" ) {check_pay_is_ture_ok(); //检测微信支付状态}else{}});}第二步:支付js准备绑定事件(这里就举例按钮)
$('#button_pay_now').on('click',function(){if (typeof WeixinJSBridge == "undefined"){if( document.addEventListener ){document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);}else if (document.attachEvent){document.attachEvent('WeixinJSBridgeReady', onBridgeReady);document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);}}else{onBridgeReady(msg_json);}});到这里我们就可以看到调起微信支付的JS效果了
报错信息分析
微信坑就在你很好的完成以上步骤也不能支付,总会报错,在这里我就把我曾经遇到的错误写下来,与大家一起探讨
1.缺少统一支付接口必填参数total_fee!
这个错造成的原因:
q:你没有传递参数total_fee a:检查是否传递参数,最好一步步打印到日志中查看
q:total_fee 参数格式错误 a:参数的单位是分,也就是一元钱的话就是100,所以建议最后处理的时候都要处理为分,建议最后用floatval处理下
2.缺少统一支付接口必填参数notify_url!
这个错造成的原因:
q:你没有传递参数notify_url a:检查是否传递参数,最好一步步打印到日志中查看
q:notify_url 参数格式错误 a:通知地址一定不能带任何参数的地址,包括你是pathinfo模式也好,只能以www.xxxxx.com/index.php这种模式结尾
3.签名错误
这个错造成的原因:
1.你的四个参数的错误,尤其注意key这个参数,如果你的key是大小写混合的话,一定要在签名前把其转化为统一的大写形式
2.签名中的APPID 和appsecret
appid和商户号
不匹配
3.过期的key,可以支付的公众号可是要一年过期一次,相应的key每年都会有变化。
总结
以上是生活随笔为你收集整理的【坑爹微信】微信支付相关问题解决的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 【坑爹微信】微信JSSDK图片上传问题和
- 下一篇: Git简单使用笔记