【坑爹微信】微信支付相关问题解决

目录

1. 那一抹淡淡的忧伤—–微信开发基础
2. 用纯js是不可能用纯js了,这辈子都不用纯js了 —– 微信JSSDK开发以及问题解答
3. 要你命3000 —— 微信支付开发系列问题解决

导语

为什么要开发微信和微信开发的优势我就不用多说了吧。微信支付的方式分好几种:
1.扫码支付
2.公众号支付
3.APP支付
不管是那种支付方式,都要用到统一下单这个接口,而一般大多数人都会卡在预支付id没有拿到这一步,今天就主要分析预支付id的获取和问题解决

开发前准备


  • 一个开通了微信支付的公众号
  • 确保将安全授权目录配置好了
  • 支付回调地址配置好了

如果不知道怎么配置,请看这里


步骤一:发起支付准备

  1. 生成商户订单

    先要根据自己的业务逻辑生成自己可读的商户订单号,一般推荐年月日+随机数+用户uid

$order_no = date('YmdHis').rand(1000,9999).$uid;
  1. 使用同一下单接口下单

使用微信统一下单接口,获得微信的预支付信息,对于统一下单接口的详细信息可以看这里

第一步:
我们先实例化微信统一下单接口的类,这个类在微信支付V3demo里有,当然在这里我将微信demo类库再次封装加入命名空间更好的适应Thinkphp。

UnifiedOrder_pub类:

<?php

namespace 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每年都会有变化。

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值