<?php
namespace app\common\model;
use \think\Db;
/*
 *处理支付结果 接受服务器和服务器之间的通知
 */
class Paymentdo
{


    //接受服务器的通知
    public function receive($orderId)
    {

        filePut('[payment][receive]异步回调开始'.$orderId);
        if (!$orderId)
        {
            filePut('[payment][receive]支付号未匹配');
            return false;
        }

        $where = array();
        $where['pay_no'] = $orderId;
        $info = Db::name('pay_order')->where($where)->find();
        if ($info)
        {
            if($info['status'])
            {
                filePut('[payment][receive]本支付号已处理过 '.$orderId);
                return true;
            }
            else
            {
                filePut('[payment][receive]开始支付 '.$orderId);
            }
            
            if (1 === 1)
            {
                $this->touchEvent('success', $orderId);
                filePut('[payment][receive]支付完成,结果 success, '.$orderId);
                return true;
            }
            else
            {
                $this->touchEvent('failed', $orderId);
                filePut('[payment][receive]支付完成,结果 failed, '.$orderId);
            }
            //filePut('[payment][receive]支付完成,结果  '.json_encode($rs).', '.$orderId);
        }
        else
        {
            filePut('[payment][receive]无效支付号 '.$orderId);
            return false;
        }

        return false;
        //1.服务器发回处理结果
        //2.这里交给核心类处理
        //3.核心类交给支付接口判断支付成功还是失败
        //4.根据支付接口的返回结果,核心类调用之前绑定好的事件.
    }

    /**
     * 执行绑定事件
     * @param  string     $event   事件名称
     * @param  string     $order_id 订单号
     */
    public function touchEvent($event, $orderId)
    {
        //检查该订单是否已绑定事件
        $where = [];
        $where['pay_no'] = $orderId;
        $where['event'] = $event;
        $info = Db::name('pay_event')->where($where)->find();
        if(!$info||!isset($info['class']))
        {return;}

        $class = new $info['class'];

        Db::startTrans();
        $orderInfo = Db::name('pay_order')->where(['pay_no' => $orderId])->lock(true)->find();
        filePut("[PAY][touchEvent] STRAT" . $orderId);

        //如果找到了绑定的事件
        if ($info) {
            $args = json_decode($info['args'], true); //强制转换为数组格式
            //$args['moneynumber'] = $orderInfo['money'];//兼容以前的设计,追加money
            if ($event === 'success') {
                if($orderInfo['status'] === 0)//成功事件只触发1次
                {
                    Db::name('pay_order')->where(['pay_no' => $orderId])->update(['status'=>2]);
                    Db::commit();
                    filePut('[PAY][touchEvent] success start'.$orderId);//.$info['args']
                    call_user_func_array([$class, $info['method']], [$orderId, $args]);
                    //得到事件模型类
                    filePut('[PAY][touchEvent] success end '.$orderId);
                }
            }
            else
            {
                call_user_func_array([$class, $info['method']], [$orderId, $args]);
                filePut('[PAY][touchEvent] '.$event.' fail'.$orderId);
            }
        }
    }

    //接受浏览器的同步通知
    public function callback()
    {
        filePut('[payment][callback]同步回调开始');
        $orderId = Pay::getOrderId();
        if (!$orderId)
        {
            filePut('[payment][callback]无法分析到支付号未匹配');
            $this->error('无效支付!');
        }

        $where = array();
        $where['pay_no'] = $orderId;
        $info = Db::name('pay_order')->where($where)->find();
        if ($info)
        {
            //获取到它使用的支付接口
            $pay = new Pay($info['payment_class']);
            $rs = $pay->callback();
            if (!$info['status'])
            {
                filePut('[payment][callback]开始支付 '.$orderId);
                //Db::startTrans(); 修改为:充值+扣款,防止扣款失败时充值也回滚
                if ($rs)
                {
                    $pay->touchEvent('success', $orderId);
                    $pay->printMessage('success', 'callback结果 success, '.$orderId);
                    filePut('[payment][callback]支付完成,结果 success, '.$orderId);
                    filePut('[payment][callback]支付完成,结果  '.json_encode($rs).', '.$orderId);
                }
                else
                {
                    $pay->touchEvent('failed', $orderId);
                    $pay->printMessage('failed', 'callback结果 failed, '.$orderId);
                    filePut('[payment][callback]支付完成,结果 failed, '.$orderId);
                    filePut('[payment][callback]支付完成,结果  '.json_encode($rs).', '.$orderId);
                    /*if (IS_MOBILE)
                    {
                        $url = session('redirect_fail_uri', '','user')?:'/wap/';
                        session('redirect_fail_uri', null,'user');
                        $this->redirect($url);
                    }
                    else
                    {*/
                        $this->error('支付失败!');
                    /*}*/
                }
            }
        }
        else
        {
            filePut('[payment][callback]无效支付号 '.$orderId);
            /*if (IS_MOBILE)
            {
                $url = session('redirect_fail_uri', '','user')?:'/wap/';
                session('redirect_fail_uri', null,'user');
                $this->redirect($url);
            }
            else
            {*/
                $this->error('无效支付订单号!');
           /* }*/
        }

        //以下代码用于同步支付成功后回跳,请定制
        /*$pays = Pay::getInstalled();
        $pinfo = $pays[Pay::$payname];*/
        $pinfo = ['type'=>'pc'];
        filePut('[payment][callback]回调地址 '.json_encode(session('redirect_uri','','user')));
        //同步通知处理完进行回跳转
        if ('app'==$pinfo['type']||request()->isAjax())
        {
            //app同步请求
            if($rs)
                $pay->printMessage('success', 'app callback结果 success, '.$orderId);
            else
                $pay->printMessage('failed', 'app callback结果 failed, '.$orderId);
        }
        else
        {
            if (session('redirect_uri','','user'))
            {
                $url = str_replace('.html', '', session('redirect_uri','','user'));
                session('redirect_uri', null, 'user');
                $this->redirect($url);
            }
            elseif('wap'==$pinfo['type'])
                $this->redirect('/wap/');
            else
                $this->redirect('/index/user/walletcenter');
        }
        exit();
        //1.服务器发回处理结果
        //2.这里交给核心类处理
        //3.核心类交给支付接口判断支付成功还是失败
        //4.根据支付接口的返回结果,核心类调用之前绑定好的事件.
    }


}
?>