<?php
namespace app\open\controller;
use think\facade\Db;
use think\facade\Cache;
use Alipay\EasySDK\Kernel\Factory;
use Alipay\EasySDK\Kernel\Util\ResponseChecker;
use Alipay\EasySDK\Kernel\Config as AliConfig;
use app\common\model\NotifyAlipay as NotifyAlipayModel;
use app\common\model\NotifyToutiao as NotifyToutiaoModel;
use app\common\model\NotifyBaidu as NotifyBaiduModel;
use app\common\model\NotifyWxpay as NotifyWxpayModel;
use app\common\model\Orders as OrdersModel;
use app\common\model\PushTask as PushTaskModel;
use app\common\model\UserWx as UserWxModel;
use helper\BaiduPay;
class Results extends Base
{
	public function aliPayNotify()
	{
        $D=request()->post();
        if(!request()->isPost()) return response("error",201);
        if(empty($D['sign'])) return response("error",201);
        // p($D);die;

		/**
		 * 验证支付宝回调数据
		 */
    	$alipayConfig=config('alipay');
        $options = new AliConfig();
        $options->protocol              = 'https';
        $options->gatewayHost           = 'openapi.alipay.com';
        $options->signType              = $alipayConfig['sign_type'];
        $options->appId                 = $alipayConfig['appid'];
        $options->merchantPrivateKey    = $alipayConfig['rsaPrivateKey'];
        $options->alipayPublicKey       = $alipayConfig['alipayPublicKey'];
        $options->notifyUrl             = $alipayConfig['notify_url'];
        $options->encryptKey            = $alipayConfig['encryptKey'];
        Factory::setOptions($options);
		$ret=Factory::payment()->common()->verifyNotify($D);
        $path=runtime_path().'/aliPayNotify/';
        $payInfo=$path.'/payInfo/'.date('Ymd').'/';
        $orderHandleInfo=$path.'/orderHandleInfo/'.date('Ymd').'/';
        $illegalData=$path.'/illegalData/';
        if (!file_exists($path))
            mkdir($path, 0777, true);
        if (!file_exists($payInfo))
            mkdir($payInfo, 0777, true);
        if (!file_exists($illegalData))
            mkdir($illegalData, 0777, true);
        if (!file_exists($orderHandleInfo))
            mkdir($orderHandleInfo, 0777, true);

		if (!$ret){
        	file_put_contents($illegalData.date('Ymd').'.log',json_encode($D,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
            return response("error",201);
		}

        file_put_contents($payInfo.date('Ymd').'.log',json_encode($D,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
        file_put_contents($orderHandleInfo.$D['out_trade_no'].'.log',json_encode($D,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
        if(NotifyAlipayModel::where(['out_trade_no'=>$D['out_trade_no']])->count()){
            file_put_contents($orderHandleInfo.$D['out_trade_no'].'.log',"重复推送，已拦截\n",FILE_APPEND);
            return 'success';
        }
        file_put_contents($orderHandleInfo.$D['out_trade_no'].'.log',"开始处理\r\n",FILE_APPEND);
        $NotifyAlipayModel=new NotifyAlipayModel;
        $NotifyAlipayModel->gmt_create		=	$D['gmt_create'];
		$NotifyAlipayModel->charset			=	$D['charset'];
		$NotifyAlipayModel->seller_email	=	$D['seller_email'];
		$NotifyAlipayModel->subject			=	$D['subject'];
		$NotifyAlipayModel->sign			=	$D['sign'];
		$NotifyAlipayModel->buyer_id		=	$D['buyer_id'];
		$NotifyAlipayModel->invoice_amount	=	$D['invoice_amount'];
		$NotifyAlipayModel->notify_id		=	$D['notify_id'];
		$NotifyAlipayModel->fund_bill_list	=	$D['fund_bill_list'];
		$NotifyAlipayModel->notify_type		=	$D['notify_type'];
		$NotifyAlipayModel->trade_status	=	$D['trade_status'];
		$NotifyAlipayModel->receipt_amount	=	$D['receipt_amount'];
		$NotifyAlipayModel->app_id			=	$D['app_id'];
		$NotifyAlipayModel->buyer_pay_amount=	$D['buyer_pay_amount'];
		$NotifyAlipayModel->sign_type		=	$D['sign_type'];
		$NotifyAlipayModel->seller_id		=	$D['seller_id'];
		$NotifyAlipayModel->gmt_payment		=	$D['gmt_payment'];
		$NotifyAlipayModel->notify_time		=	$D['notify_time'];
		$NotifyAlipayModel->version			=	$D['version'];
		$NotifyAlipayModel->out_trade_no	=	$D['out_trade_no'];
		$NotifyAlipayModel->total_amount	=	$D['total_amount'];
		$NotifyAlipayModel->trade_no		=	$D['trade_no'];
		$NotifyAlipayModel->auth_app_id		=	$D['auth_app_id'];
		$NotifyAlipayModel->buyer_logon_id	=	$D['buyer_logon_id'];
		$NotifyAlipayModel->point_amount	=	$D['point_amount'];
		$OrdersModel=OrdersModel::where(['otrade'=>$D['out_trade_no']])->find();
		if (!$OrdersModel) {
        	file_put_contents($orderHandleInfo.$D['out_trade_no'].'.log',"订单不存在\r\n",FILE_APPEND);
            return response("error",201);
		}
		$OrdersModel->status 		=	1;
		$OrdersModel->pay_type 		=	1;
		$OrdersModel->pay_time 		=	time();
        $PushTaskModel=new PushTaskModel;
        $PushTaskModel->event       =   'orderPaySuccess';
        $PushTaskModel->uid         =   $OrdersModel->uid;
        $PushTaskModel->data        =   json_encode($OrdersModel,JSON_UNESCAPED_UNICODE);

        $AdminPushTaskModel=new PushTaskModel;
        $AdminPushTaskModel->event       =   'SystemWarning';
        $PushData=[
            'tpl'       =>'pay',
            'level'     =>'订单支付',
            'range'     =>'后台',
            'time'      =>date('Y-m-d H:i:s'),
            'msg'       =>'支付宝支付，订单号:'.$OrdersModel->otrade
        ];
        $AdminPushTaskModel->data        =   json_encode($PushData,JSON_UNESCAPED_UNICODE);
        //启动事务
        Db::startTrans();
        try {
            file_put_contents($orderHandleInfo.$D['out_trade_no'].'.log',"订单信息入库\n",FILE_APPEND);
            $NotifyAlipayModel->save();
            $OrdersModel->save();
            $PushTaskModel->save();
            $AdminPushTaskModel->save();
            // 提交事务
            Db::commit();
            return "success";
        } catch (Exception $e) {
            //回滚事务
            Db::rollback();
            file_put_contents($orderHandleInfo.$D['out_trade_no'].'.log',"插入数据库失败\n",FILE_APPEND);
            return response("error",201);
        }
	}
	public function wxPayNotify()
	{
        $D = file_get_contents("php://input");
        //接收参数
        if(!$D)
        	return "<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[非法请求]]></return_msg> </xml>";
        $postObj = simplexml_load_string($D, 'SimpleXMLElement', LIBXML_NOCDATA);
        $data = json_decode(json_encode($postObj),true);
        $path=runtime_path().'/wxPayNotify/';
        $payInfo=$path.'/payInfo/'.date('Ymd').'/';
        $orderHandleInfo=$path.'/orderHandleInfo/'.date('Ymd').'/';
        $illegalData=$path.'/illegalData/';
        if (!file_exists($path))
            mkdir($path, 0777, true);
        if (!file_exists($payInfo))
            mkdir($payInfo, 0777, true);
        if (!file_exists($illegalData))
            mkdir($illegalData, 0777, true);
        if (!file_exists($orderHandleInfo))
            mkdir($orderHandleInfo, 0777, true);
        $xmlObj=$data;
        //判断是否成功
        if (!empty($data['return_code']) && $data['return_code'] == 'SUCCESS')
        {
            foreach( $xmlObj as $k=>$v) {
                if($k == 'sign') {
                    $xmlSign = $xmlObj[$k];
                    unset($xmlObj[$k]);
                };
            }
 
            $sign = http_build_query($xmlObj);
            //md5处理
            $sign = md5($sign.'&key='.config('wxpay.key'));
            //转大写
            $sign = strtoupper($sign);
 
            //验签名。默认支持MD5
            if ( $sign === $xmlSign) {
        		file_put_contents($payInfo.date('Ymd').'.log',json_encode($data,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
        		file_put_contents($orderHandleInfo.$data['out_trade_no'].'.log',json_encode($data,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
		        if(NotifyWxpayModel::where(['out_trade_no'=>$data['out_trade_no']])->count()){
		            file_put_contents($orderHandleInfo.$data['out_trade_no'].'.log',"重复推送，已拦截\n",FILE_APPEND);
		            return "<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> </xml>";
		        }
                //参数实例
                $ordersn = $data['out_trade_no'];
                $NotifyWxpayModel=new NotifyWxpayModel;
                $NotifyWxpayModel->appid 			=	$data['appid'];
				$NotifyWxpayModel->bank_type		=	$data['bank_type'];
				$NotifyWxpayModel->cash_fee			=	$data['cash_fee'];
				$NotifyWxpayModel->fee_type			=	$data['fee_type'];
				$NotifyWxpayModel->is_subscribe		=	$data['is_subscribe'];
				$NotifyWxpayModel->mch_id			=	$data['mch_id'];
				$NotifyWxpayModel->nonce_str		=	$data['nonce_str'];
				$NotifyWxpayModel->openid			=	$data['openid'];
				$NotifyWxpayModel->out_trade_no		=	$data['out_trade_no'];
				$NotifyWxpayModel->result_code		=	$data['result_code'];
				$NotifyWxpayModel->return_code		=	$data['return_code'];
				$NotifyWxpayModel->sign				=	$data['sign'];
				$NotifyWxpayModel->time_end			=	$data['time_end'];
				$NotifyWxpayModel->total_fee		=	$data['total_fee'];
				$NotifyWxpayModel->trade_type		=	$data['trade_type'];
				$NotifyWxpayModel->transaction_id	=	$data['transaction_id'];
				$OrdersModel=OrdersModel::where(['otrade'=>$data['out_trade_no']])->find();
				if (!$OrdersModel) {
		        	file_put_contents($orderHandleInfo.$data['out_trade_no'].'.log',"订单不存在\r\n",FILE_APPEND);
            		return "<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[订单不存在]]></return_msg> </xml>";
				}
				$OrdersModel->status 		=	1;
				$OrdersModel->pay_type 		=	2;
				$OrdersModel->pay_time 		=	time();
                $PushTaskModel=new PushTaskModel;
                $PushTaskModel->event       =   'orderPaySuccess';
                $PushTaskModel->uid         =   $OrdersModel->uid;
                $PushTaskModel->data        =   json_encode($OrdersModel,JSON_UNESCAPED_UNICODE);

                $AdminPushTaskModel=new PushTaskModel;
                $AdminPushTaskModel->event       =   'SystemWarning';
                $PushData=[
                    'tpl'       =>'pay',
                    'level'     =>'订单支付',
                    'range'     =>'后台',
                    'time'      =>date('Y-m-d H:i:s'),
                    'msg'       =>'微信支付，订单号:'.$OrdersModel->otrade
                ];
                $AdminPushTaskModel->data        =   json_encode($PushData,JSON_UNESCAPED_UNICODE);
                //启动事务
                Db::startTrans();
                try {
            		file_put_contents($orderHandleInfo.$data['out_trade_no'].'.log',"订单信息入库\n",FILE_APPEND);
                    $NotifyWxpayModel->save();
                    $OrdersModel->save();
                    $PushTaskModel->save();
                    $AdminPushTaskModel->save();
                    // 提交事务
                    Db::commit();
                    echo "<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> </xml>";
                } catch (Exception $e) {
                    //回滚事务
                    Db::rollback();
                    file_put_contents($orderHandleInfo.$data['out_trade_no'].'.log',"插入数据库失败\n",FILE_APPEND);
            		return "<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[数据解析出错]]></return_msg> </xml>";
                }
            }else{
        		file_put_contents($illegalData.date('Ymd').'.log',json_encode($data,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
            	return "<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[数据解析出错]]></return_msg> </xml>";
            }
        }else{
        	file_put_contents($illegalData.date('Ymd').'.log',json_encode($data,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
            return "<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[数据解析出错]]></return_msg> </xml>";
        }
	}
    public function toutiaoPayNotify()
    {
        $D=request()->post();
        $path=runtime_path().'/toutiaoPayNotify/';
        $payInfo=$path.'/payInfo/'.date('Ymd').'/';
        $orderHandleInfo=$path.'/orderHandleInfo/'.date('Ymd').'/';
        $illegalData=$path.'/illegalData/';
        if (!file_exists($path))
            mkdir($path, 0777, true);
        if (!file_exists($payInfo))
            mkdir($payInfo, 0777, true);
        if (!file_exists($illegalData))
            mkdir($illegalData, 0777, true);
        if (!file_exists($orderHandleInfo))
            mkdir($orderHandleInfo, 0777, true);
        $signData=[];
        $signData['token']=config('xy_toutiaopay.token');
        $signData['timestamp']=$D['timestamp'];
        $signData['nonce']=$D['nonce'];
        $signData['msg']=$D['msg'];
        sort($signData,2);
        $sign=sha1(implode('', $signData));
        if ($sign===$D['msg_signature']) {
            $order=json_decode($D['msg'],true);
            file_put_contents($payInfo.date('Ymd').'.log',json_encode($D,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
            file_put_contents($orderHandleInfo.$order['cp_orderno'].'.log',json_encode($D,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
            if(NotifyToutiaoModel::where(['cp_orderno'=>$order['cp_orderno']])->count()){
                file_put_contents($orderHandleInfo.$order['cp_orderno'].'.log',"重复推送，已拦截\n",FILE_APPEND);
                return json(['err_no'=>0,'err_tips'=>'success']);
            }
            file_put_contents($orderHandleInfo.$order['cp_orderno'].'.log',"开始处理\r\n",FILE_APPEND);
            $NotifyToutiaoModel=new NotifyToutiaoModel;
            $NotifyToutiaoModel->appid       =   $order['appid'];
            $NotifyToutiaoModel->cp_orderno  =   $order['cp_orderno'];
            $NotifyToutiaoModel->cp_extra    =   $order['cp_extra'];
            $NotifyToutiaoModel->way         =   $order['way'];
            $NotifyToutiaoModel->channel_no  =   $order['channel_no'];
            $NotifyToutiaoModel->channel_gateway_no=   $order['channel_gateway_no'];
            $NotifyToutiaoModel->payment_order_no  =   $order['payment_order_no'];
            $NotifyToutiaoModel->out_channel_order_no       =   $order['out_channel_order_no'];
            $NotifyToutiaoModel->total_amount  =   $order['total_amount'];
            $OrdersModel=OrdersModel::where(['otrade'=>$order['cp_orderno']])->find();
            if (!$OrdersModel) {
                file_put_contents($orderHandleInfo.$order['cp_orderno'].'.log',"订单不存在\r\n",FILE_APPEND);
                return json(['err_no'=>-100,'err_tips'=>'订单不存在']);
            }
            $OrdersModel->status        =   1;
            $OrdersModel->pay_type      =   6;
            $OrdersModel->pay_time      =   time();
            $PushTaskModel=new PushTaskModel;
            $PushTaskModel->event       =   'orderPaySuccess';
            $PushTaskModel->uid         =   $OrdersModel->uid;
            $PushTaskModel->data        =   json_encode($OrdersModel,JSON_UNESCAPED_UNICODE);

            $AdminPushTaskModel=new PushTaskModel;
            $AdminPushTaskModel->event       =   'SystemWarning';
            $PushData=[
                'tpl'       =>'pay',
                'level'     =>'订单支付',
                'range'     =>'后台',
                'time'      =>date('Y-m-d H:i:s'),
                'msg'       =>'字节跳动支付，订单号:'.$OrdersModel->otrade
            ];
            $AdminPushTaskModel->data        =   json_encode($PushData,JSON_UNESCAPED_UNICODE);
            //启动事务
            Db::startTrans();
            try {
                file_put_contents($orderHandleInfo.$order['cp_orderno'].'.log',"订单信息入库\n",FILE_APPEND);
                $NotifyToutiaoModel->save();
                $OrdersModel->save();
                $PushTaskModel->save();
                $AdminPushTaskModel->save();
                // 提交事务
                Db::commit();
                return json(['err_no'=>0,'err_tips'=>'success']);
            } catch (Exception $e) {
                //回滚事务
                Db::rollback();
                file_put_contents($orderHandleInfo.$order['cp_orderno'].'.log',"插入数据库失败\n",FILE_APPEND);
                return json(['err_no'=>-100,'err_tips'=>'入库失败']);
            }
        }else{
            file_put_contents($illegalData.date('Ymd').'.log',json_encode($D,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
            return json(['err_no'=>-100,'err_tips'=>'验签失败']);
        }
    }
    public function toutiaoSign($map,$salt) {
        $rList = [];
        foreach($map as $k => $v) {
            if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
                continue;
            $value = trim(strval($v));
            $len = strlen($value);
            if ($len > 1 && substr($value, 0,1)=="\"" && substr($value,$len, $len-1)=="\"")
                $value = substr($value,1, $len-1);
            $value = trim($value);
            if ($value == "" || $value == "null")
                continue;
            array_push($rList, $value);
        }
        array_push($rList, $salt);
        sort($rList, 2);
        return md5(implode('&', $rList));
    }
    public function baiduPayNotify()
    {
        $D=request()->post();
        $path=runtime_path().'/baiduPayNotify/';
        $payInfo=$path.'/payInfo/'.date('Ymd').'/';
        $orderHandleInfo=$path.'/orderHandleInfo/'.date('Ymd').'/';
        $illegalData=$path.'/illegalData/';
        if (!file_exists($path))
            mkdir($path, 0777, true);
        if (!file_exists($payInfo))
            mkdir($payInfo, 0777, true);
        if (!file_exists($illegalData))
            mkdir($illegalData, 0777, true);
        if (!file_exists($orderHandleInfo))
            mkdir($orderHandleInfo, 0777, true);
        if (intval($D['status'])!==2)
            return json(['errno'=>-100,'msg'=>'订单未支付']);
        if (BaiduPay::checkSign($D,config('xy_baidupay.public_key'))) {
            file_put_contents($payInfo.date('Ymd').'.log',json_encode($D,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
            file_put_contents($orderHandleInfo.$D['tpOrderId'].'.log',json_encode($D,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
            if(NotifyBaiduModel::where(['tp_order_id'=>$D['tpOrderId']])->count()){
                file_put_contents($orderHandleInfo.$D['tpOrderId'].'.log',"重复推送，已拦截\n",FILE_APPEND);
                return json(['errno'=>0,'msg'=>'success','data'=>['isConsumed'=>2]]);
            }
            file_put_contents($orderHandleInfo.$D['tpOrderId'].'.log',"开始处理\r\n",FILE_APPEND);
            $NotifyBaiduModel=new NotifyBaiduModel;
            $NotifyBaiduModel->unit_price   =$D['unitPrice'];
            $NotifyBaiduModel->order_id     =$D['orderId'];
            $NotifyBaiduModel->pay_time     =$D['payTime'];
            $NotifyBaiduModel->deal_id      =$D['dealId'];
            $NotifyBaiduModel->tp_order_id  =$D['tpOrderId'];
            $NotifyBaiduModel->count        =$D['count'];
            $NotifyBaiduModel->total_money  =$D['totalMoney'];
            $NotifyBaiduModel->hb_balance_money=$D['hbBalanceMoney'];
            $NotifyBaiduModel->user_id      =$D['userId'];
            $NotifyBaiduModel->gift_card_money=$D['giftCardMoney'];
            $NotifyBaiduModel->pay_money    =$D['payMoney'];
            $NotifyBaiduModel->pay_type     =$D['payType'];
            $NotifyBaiduModel->rsa_sign     =$D['rsaSign'];
            $NotifyBaiduModel->pay_status   =$D['status'];
            $OrdersModel=OrdersModel::where(['otrade'=>$D['tpOrderId']])->find();
            if (!$OrdersModel) {
                file_put_contents($orderHandleInfo.$D['tpOrderId'].'.log',"订单不存在\r\n",FILE_APPEND);
                return json(['errno'=>-100,'msg'=>'订单不存在']);
            }
            $OrdersModel->status        =   1;
            $OrdersModel->pay_type      =   7;
            $OrdersModel->pay_time      =   time();
            $PushTaskModel=new PushTaskModel;
            $PushTaskModel->event       =   'orderPaySuccess';
            $PushTaskModel->uid         =   $OrdersModel->uid;
            $PushTaskModel->data        =   json_encode($OrdersModel,JSON_UNESCAPED_UNICODE);

            $AdminPushTaskModel=new PushTaskModel;
            $AdminPushTaskModel->event       =   'SystemWarning';
            $PushData=[
                'tpl'       =>'pay',
                'level'     =>'订单支付',
                'range'     =>'后台',
                'time'      =>date('Y-m-d H:i:s'),
                'msg'       =>'百度支付，订单号:'.$OrdersModel->otrade
            ];
            $AdminPushTaskModel->data        =   json_encode($PushData,JSON_UNESCAPED_UNICODE);
            //启动事务
            Db::startTrans();
            try {
                file_put_contents($orderHandleInfo.$D['tpOrderId'].'.log',"订单信息入库\n",FILE_APPEND);
                $NotifyBaiduModel->save();
                $OrdersModel->save();
                $PushTaskModel->save();
                $AdminPushTaskModel->save();
                // 提交事务
                Db::commit();
                return json(['errno'=>0,'msg'=>'success','data'=>['isConsumed'=>2]]);
            } catch (Exception $e) {
                //回滚事务
                Db::rollback();
                file_put_contents($orderHandleInfo.$D['tpOrderId'].'.log',"插入数据库失败\n",FILE_APPEND);
                return json(['errno'=>-100,'msg'=>'入库失败']);
            }
        }else{
            file_put_contents($illegalData.date('Ymd').'.log',json_encode($D,JSON_UNESCAPED_UNICODE)."\r\n",FILE_APPEND);
            return json(['errno'=>-100,'msg'=>'验签失败']);
        }
    }
}