读一读

例如第四方支付时,一般都有两个回调地址,一个是post请求发起的校验数据,处理数据的,一个是成功的回调,显示给用户看的

当第四方使用post请求访问我们laravel的方法时,注意laravel是有csrf防护功能的,第四方请求没有携带上csrf_token肯定是不能通过的

所有,要排除post请求的路由不使用csrf防护功能,在中间件VerifyCsrfToken里面的except里面排除相应的路由,具体参考笔记


  1. 下载到Demo,主要用到jubaopay.ini(配置),jubaopay.php(加密解密类),RSA.php(功能类),DempPost.php(调用发起支付),notify.php(post通知文件)

  2. 移动聚宝云后台下载的配置文件到public文件夹目录下,加密和功能类移动到App下的文件夹里,修改文件加入namespace,添加控制器,引入use这些功能加密类,将DemoPost.php视图外的代码复制到控制器的方法里面,替换里面的$parterid为后台的商家号,修改$returnUrl $callbackUrl,其中callbackUrl是post通知校对的链接,returnUrl是提示用户成功的链接,jubaopay对象的生成需要提供配置文件,将参数改成对应的路径,其他参数根据实际情况修改,算出视图页面需要的参数,调用视图发起post请求,然后支付。

  3. 支付完成后,聚宝云以post访问callbackUrl,获取对应的参数,解密,校验,参考notify.php文件。

  4. 注意,mcrypt早php7.1被弃用了,解决办法参考笔记。jubaopay和RSA在同一个命名空间下时还是不能引用到对方,直接赋值一方到另一方里面去。


Laravel框架的设计为我们做好了错误和异常处理,如果没有出现,可以检查一下日志文件laravel.log,如果日志文件内容很少,网站又蹦了

那么就应该是storage/logs/laravel.log文件没有权限打开写入,卡住了laravel的运行,结果整个网站就显示500了,一片空白

修改storage文件夹的用户控制权限,新加IIS两个用户的写入修改控制权限


共享到所有视图,在提供者的boot方法里面调用共享数据方法,例如在AppServiceProvider调用

view()->share('name','value');

这样就可以在所有的视图里面使用这个name变量了


共享到指定的视图,同样的需要在提供者的boot放法里面调用

view()->composer(['view1','view2'],function($view){
    $view->with('name','value');
})

这样就可以在view1和view2里面使用name变量了


@yield('title')  标志可填充区域填充变量  @section('title',"我是标题")

@yield('content')  标记可填充区域填充内容  @section('content')  内容  @endsection()

@section('par')父内容@show  标记有内容的可填充区域  @section('par') 内容 @endsection


$first = DB::table('db_data')->where('id',5);
$results = DB::table('db_data')->where('id',6)->union($first)->get();

通过union()方法联合指定了查询但是没有最终使用末尾方法的模型$first,使用get()等末尾方法会转换数据为集合或是数组

使用联合操作的两个集的列数必须相同


$result = DB::table('db_data')->join('db_data2','db_data,id','=','db_data2.id')->get();
$result = DB::table('db_data')->leftJoin('db_data2','db_data,id','=','db_data2.id')->get();

join和leftJoin方法

第一个表示通过两个表的id号相同来连接数据,相同的id连接在一起,没有相同的抛弃掉

第二个leftJoin表示在保证第一个表的数据完整的条件下,合并id相同的数据项,所有会出现一些左边表有的id行而右边没有对用id的行,其右边表的字段值为null


使用laravel直接return 一个字符串时,浏览器直接显示这个字符串,但是按F12查看源码,发现有基本的html和head和body标签。

新建一个文件html,就只输入一个字符串,其他标签都没有,用浏览器打开,发现也是有html,head,body这些标签。

事实证明,这些标签是浏览器加上的,就是返回的就是一个字符串。


签名都是按照参数的键值字母排序组成字符串,经过md5加密再转成大写字母

发起支付时传递的签名

$arr = array('dingdan'=>time(),'userid'=>$userid,'money'=>$money);

$data =  json_encode($arr);
$data = base64_encode($data);

$appid = "lalalalalalalallalalala";
$body = $money."元金币充值";
$callback_url = "http://123456.cn/pay/success";
$channel_id = "default";
$out_trade_no = $data;
$total_fee = $money;
$version = "2.0";

$sign_prep = "app_id=".$appid."&body=".$body."&callback_url=".$callback_url."&channel_id=".$channel_id."&out_trade_no=".$out_trade_no."&total_fee=".$total_fee."&version=".$version.$this->key;
$sign = strtoupper( md5($sign_prep) );


中间回调的签名验证,第四方post传递过来的参数,除了sign,其它参与排序计算签名再和sign对比,一样返回success

$cpparam = $request->get('cpparam');
$orderNo = $request->get('orderNo');
$price =$request->get('price');
$status = $request->get('status');
$synType = $request->get('synType');
$time = $request->get('time');
$sign = $request->get('sign');

$str = "cpparam=".$cpparam."&orderNo=".$orderNo."&price=".$price."&status=".$status."&synType=".$synType."&time=".$time.$this->key;
$str = strtoupper( md5($str) );
if($sign == $str){
    if($status == "success"){
        //获取参数,发送命令给服务端
        $data = $request->get('cpparam');
        $dingdan = $request->get('orderNo');
        $data = base64_decode($data);
        $data = json_decode($data,true);
        $result = "1";

        if(PFGameCommand::recharge($data['userid'],$data['money'],$dingdan,$result)){
            return "success";
        }

    }else{
        PFGameCommand::recharge("0000","0","0","0");
    }
}else{
    PFGameCommand::recharge("0000","0","0","0");
    return "";
}



实例文件h5中有一个参数out_trade_no,它是我们商家自定义的订单号。

可以用来传递参数,它会原样的传递到接受校验签名的地方

不过out_trade_no如果要用来传递参数时,必须使用json格式,再用base64加密json字符串

到中间接受结果的url,第四方会传递一个叫cpparam的,就是out_trade_no的原样

通过base64解密,再通过json解析获取到要传递的参数