thinkphp3.2微信公众号支付(jsapi支付)开发过程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u014391889/article/details/83147307

第一次做微信支付(网页版本的),折腾了两天,记录一下方便下次自己再次使用,也希望能帮和我一样初次接触的朋友踩一下坑。

前期准备

1.开通微信认证服务号,并且开通商户平台

2.下载微信支付dome,下载地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1,解压php版本如图

a.doc文件夹说明文档     b.example一些dome示例    c.lib最重要的文件接口文件     d.logs日志文件

第一步dome文件处理

1.解压后获得php_sdk_v3.0.9这个文件夹改名为WxPay整个复制到核心框架ThinkPHP\Library\Vendor中方便调用

2.打开lib文件夹下的WxPay.Api.php文件,在537行有一段curl网络请求配置代码:

curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
改为:
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
为了禁止 cURL 验证证书

3.打开example中的WxPay.Config.php配置GetAppId函数和GetMerchantId两项(一个是公众号APPID,一个是商户号) 

第二步配置公众号后台授权路径

1.网页授权路径,公众号设置->功能设置->网页授权域名(这个是为了获取用户openid的),直接填你的根目录就OK

2.配置商户授权路径,登陆商户->产品中心->开发配置

 第三步前端代码

<script type="text/javascript">
    $('.btns').click(function(){
        var moneys = ($('.moneys').val());
        var openids = "<?php echo I('openid')?>";
        $.ajax({
            url: "{:U('wxpay')}",    //请求的url地址
            dataType: "json",   //返回格式为json
            async: true, //请求是否异步,默认为异步,这也是ajax重要特性
            data: { 
                'moneys': moneys,
                'openids': openids
            },//参数值
            type: "POST",   //请求方式
            success: function(req) {
                //console.log(req);
                function jsApiCall(){
                    var data = eval("("+req+")");
                    WeixinJSBridge.invoke(
                        'getBrandWCPayRequest',
                        data,
                        function(res){
                            WeixinJSBridge.log(res.err_msg);
                            //alert(res.err_code+res.err_desc+res.err_msg);
                            if(res.err_msg == "get_brand_wcpay_request:ok"){              
                                window.location.reload();
                            }
                        }
                    );
                }
                function callpay(){
                    if (typeof WeixinJSBridge == "undefined"){
                    if( document.addEventListener ){
                        document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
                    }else if (document.attachEvent){
                        document.attachEvent('WeixinJSBridgeReady', jsApiCall); 
                        document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
                    }
                    }else{
                        jsApiCall();
                    }
                }
                callpay();
            },
            error: function() {
                alert('请求错误');
            }
        });
    })
    </script>

第四步后端代码

    //付款调用
    public function wxpay(){
        $money = abs(I('moneys'))*100;  //单位为分
        $openid = I('openids');
        if(empty($money)){
            return 0;
        }
        if(empty($openid)){
            return 0;
        }
        //echo $money;
        Vendor('WxPayAPI.lib.WxPay#Api');
        Vendor('WxPayAPI.example.WxPay#Config');
        Vendor('WxPayAPI.example.WxPay#JsApiPay');
        //②、统一下单
        $tools = new \JsApiPay();
        $input = new \WxPayUnifiedOrder();
        $input->SetBody("微信还款");    //这里是支付内容
        $input->SetAttach(I('fq'));    //此处可传值,待支付成功后可取这部分的值
        $input->SetOut_trade_no("3".date("YmdHis"));  //订单编号
        $input->SetTotal_fee($money);  //金额
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 600));
        $input->SetGoods_tag("test");
        $input->SetNotify_url("https://wechat.labao168.com/fukuan/payment.php"); 
        $input->SetTrade_type("JSAPI");
        $input->SetOpenid($openid);

        $config = new \WxPayConfig();
        $order = \WxPayApi::unifiedOrder($config, $input);
        $jsApiParameters = $tools->GetJsApiParameters($order);
        echo $jsApiParameters;
    }

这里有一个大坑要注意一下,SetNotify_url他这个配置不支持pathinfo模式,比如

https://www.xxx.com/fukuan/index.php/Home/wxpay/notify

这种模式是不支持的,解决方法如下

根目录(fukuan)中创建payment.php作为入口文件,然后跳转到相应页面

 https://www.xxx.com/fukuan/payment.php

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用入口文件

// 检测PHP环境
if(version_compare(PHP_VERSION,'5.3.0','<'))  die('require PHP > 5.3.0 !');

// 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false
define('APP_DEBUG',True);

//指定模块控制器和方法 
$_GET['m']='Home'; 
$_GET['c']='Wxpay'; 
$_GET['a']='notify'; 

// 定义应用目录
define('APP_PATH','./Application/');

// 引入ThinkPHP入口文件
require './ThinkPHP/ThinkPHP.php';

// 亲^_^ 后面不需要任何代码了 就是如此简单

 

第五步支付成功后入库处理(这里真的是操碎了心),回调地址就是上面在商户号上配置地址,支付成功后微信服务器会访问这个地址

a.坑1这个地址是不允许有权限管理的,就是说你在网页上能直接访问,否则微信服务器无法传值到这个地址

b.坑2微信服务器为了将消息准确送到我们的服务器,会对这个地址请求多次,频率从高到低(导致一条数据被插入很多次数据库),我的解决方法比较笨,就是插入数据库之前检测一下订单是否存在,存在的话就直接跳过插入数据

c.坑3由于是服务器与服务器间的请求,无法在页面上显示,就是说你丫没办法在页面上调试,解决办法将接受到的数据写入文本中,然后查看文本是否有问题

d.传值问题,支付后端中$input->SetAttach(I('fq'));是可以传值的

<?php
namespace Home\Controller;
use Think\Controller;
class WxpayController extends Controller{
    public function notify(){

        
        //获取返回的xml
        $testxml = file_get_contents("php://input");

        //将xml转化为json格式
        $jsonxml = json_encode(simplexml_load_string($testxml, 'SimpleXMLElement', LIBXML_NOCDATA));

        //转成数组
        $result = json_decode($jsonxml,true);

        //file_put_contents('test.txt',$jsonxml);   --这里是调试方法根目录中test.txt中可查看数据情况

        if($result){
            //如果成功返回了
            if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){

                //file_put_contents('test.txt',$data);

                //获取服务器返回的数据
                $order_sn = $result['transaction_id']; //订单单号
                $openid = $result['openid'];   //付款人openID 
                $total_fee = ($result['total_fee']/100); //付款金额 
                $fq = $result['attach'];    //分期数

                //判断订单是否已经入库
                $results = M('zhangdan')->where(array('tranid'=>$order_sn))->find();
                if($results){
                    exit();
                }

                //更新数据库 
                $uid = M('user')->where(array('openid'=>$openid))->getField('id');

                //判断是否满足分期
                M('fqjl')->where(array('uid'=>$uid,'fq'=>$fq))->setInc('yhk',$total_fee); // 用户的积分加3
                //file_put_contents('test.txt',$datast['yhk']);

                $sj['money'] = $total_fee;
                $sj['ztime'] = strtotime(date('Y-m-d'));
                $sj['contents'] = "微信还款";
                $sj['uid'] = $uid;
                $sj['tranid'] = $order_sn;

                //file_put_contents('test.txt',$sj);
                $res = M('zhangdan')->add($sj);

                echo exit('<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>');
            }
        }
    }

}



至此支付就完成了,希望有一点对第一次接触的朋友有一点小小的帮助 

 

 

 

 

 

 

 

展开阅读全文

没有更多推荐了,返回首页