<?php
namespace app\pay\controller;

class Home extends \think\Controller{
    // +----------------------------------------------------------------------
    // | 支付配置 开始
	// | 技术支持：三七云(37yz.com)
    // +----------------------------------------------------------------------
    //商户ID（商户编号）
	private $appid;
	//商户密钥
	private $appkey;
	//异步通知地址
	private $notify_url;
	//页面跳转同步通知页面
	private $return_url;
	//聚合支付POST提交地址
	private $payurl;
	// +----------------------------------------------------------------------
    // | 支付配置 结束 
    // +----------------------------------------------------------------------
    public function _initialize(){
        //返回数组配置下的某一项属性
        $this->appid = config('yuanbaopay.appid');
        $this->appkey = config('yuanbaopay.appkey');
        $this->payurl = config('yuanbaopay.payurl');
        $this->notify_url='http://'.$_SERVER['HTTP_HOST'].'/pay/Home/notify';
        $this->return_url='http://'.$_SERVER['HTTP_HOST'].'/pay/Home/page';
	}
	public function index()
	{
        $account=\think\Session::get("account");
		$datae = \think\Db::name("user")->field("Id,rmb,lock")->where("account", $account)->find();
		if ($datae["lock"] != 0) {
		    $this->error("账号被锁定！"); 
		}
		$moneyList = pay_kk("", true);
		$token = $this->request->token("__token__", "sha1");
		$this->assign(["token" => $token, "rmb" => $datae["rmb"], "moneyList" => $moneyList, "account" => $account]);
		return $this->fetch();
	}
	
	public function doPay(){
	    $request = \think\Request::instance()->post();
	    $account=\think\Session::get("account");
	    $money=\intval($request["money"]);
	    if(empty($money)){
	       $this->error("充值金额必须大于0"); 
	    }
	    $paytype=$request["paytype"];
	    $datae = \think\Db::name("user")->field("Id,agent,lock")->where("account", $account)->find();
	    if ($datae["lock"] != 0) {
		    $this->error("账号被锁定！"); 
		}
        //创建订单
	    $order_id = $this->generateOrderNumber();
        $Testdata["order_id"] = $order_id;
        $Testdata["account"] = $account;
		$Testdata["agent"] = $datae["agent"];
		$Testdata["money"] = $money;
		$Testdata["pay_type"] = $paytype;
		$Testdata["time"] = date("Y-m-d H:i:s", time());
		$Testdata["status"] = 0;
		\think\Db::name("charge_order")->data($Testdata)->insert();
		/*------------------------------------ 提交到三七云平台 -------------------------------------*/
    	try {
    		//计算签名
    		$postData=array(
    		    "appid" => $this->appid,
    		    "payid" => $order_id,//订单号
    		    "money" => $money,//提交金额
    		    "type" => $paytype,//支付方式 1：支付宝  2：微信支付
    		    "notify_url" => $this->notify_url,
    		    "return_url" => $this->return_url,
    		    "subject" => $account, 
    		    "param" => $account,//账号放自定义参数里
				"codesize" => 150,
    		);
    		$stringTemp = $this->ASCII($postData);
    		$postData["sign"] =	$this->md5Sign($stringTemp,$this->appkey);
    		//4.跳转到支付页面
    		$res = $this->buildRequestForm($this->payurl,$postData);
    		echo $res;
    		exit;
    	}catch (\Exception $e) {
    		return  "<script>alert('充值异常');type='text/javascript'>history.go(-1);</script>";
    	}
    	/*------------------------------------ 提交到三七云平台 -------------------------------------*/
	}
	public function page(){
        if (empty($_POST)) $_POST = $_GET;//如果为GET方式访问
		$sign = $this->ASCII($_POST);
		$flag = $this->md5Verify($sign,$_POST['sign'],config('yuanbaopay.appkey'));
		if($flag){
		    $pay_id = $_POST['pay_id'];              //需要充值的ID 或订单号 或用户名
    		$pay_money = (float)$_POST['pay_money']; //实际付款金额
    		$param = isset($_POST['param'])?$_POST['param']:'';//自定义参数
    		$result = '支付成功';
    	    $goback='http://'.$_SERVER['HTTP_HOST'].'/index/Home';
        	$this->assign('result',$result);
    		$this->assign('goback',$goback);
    		$this->assign('pay_id',$pay_id);
    		$this->assign('pay_money',$pay_money);
    		return view();
		}else{
		    exit("支付失败");
		}
	
    }
	//充值回调（异步通知）
	public function notify(){
	    if (empty($_POST)) $_POST = $_GET;//如果为GET方式访问
		$sign = $this->ASCII($_POST);
		$flag = $this->md5Verify($sign,$_POST['sign'],$this->appkey);
		if($flag){
			$pay_id = $_POST['pay_id']; //需要充值的ID 或订单号 或用户名
			$pay_no = $_POST['pay_no']; //交易流水号
			$pay_money = (float)$_POST['pay_money']; //实际付款金额	
			$param = isset($_POST['param'])?$_POST['param']:'';//自定义参数
			if(empty($param)){
			    exit('自定义参数为空'); 
			}
			//查询订单
		    $order = \think\Db::name("charge_order")->field("id,account,money,agent,status")->where("order_id", $pay_id)->find();
            if(empty($order)){
                exit('订单不存在'); 
            }
             if($order["status"] == 1){
                 exit('success'); 
             }
           //充值比例
			$bili = config('yuanbaopay.bili');
		    $money = intval($bili) * $pay_money;
		    \think\Db::startTrans();
			try{
			    \think\Db::name("charge_order")->where("order_id", $pay_id)->update(["status" => 1, "pay_id" => $pay_no, "pay_time" => date("Y-m-d H:i:s", time())]);
                \think\Db::name("user")->where("account", $param)->setInc("rmb", \intval($money));
                $this->agentPoint($order["agent"], $param, \intval($money),$pay_no, $pay_id);
                \think\Db::commit();
				exit('success'); //返回成功，业务处理完成，下面不再执行了
			} catch (\Exception $e) {
			    \think\Db::rollback();
				exit('充值失败');
			}
		}else{
			exit('fail');//返回失败 继续补单
		}
	}
	
	protected function agentPoint($agent, $account, $money,$order_id, $pay_id){
		$datae = \think\Db::name("agent")->field("id,branch,agent")->where("account", $agent)->find();
		if($datae){
			$branch=$datae["branch"];
			$rmb=$money * ($branch / 100);
			\think\Db::name("agent")->where("account", $agent)->setInc("rmb", $rmb);
			$Testdata["agent"] = $agent;
			$Testdata["order_id"] = $order_id;
			$Testdata["pay_id"] = $pay_id;
			$Testdata["account"] = $account;
			$Testdata["money"] = $money;
			$Testdata["point"] = $rmb;
			$Testdata["time"] = date("Y-m-d H:i:s", time());
			\think\Db::name("agent_log")->data($Testdata)->insert();
		}
	}
	/**
     * 签名字符串
     * @param $prestr 需要签名的字符串
     * @param $key 私钥
     * return 签名结果
     */
	protected function md5Sign($prestr, $key) {
		$prestr = $prestr . $key;
		return md5($prestr);
	}
	/**
     * 验证签名
     * @param $prestr 需要签名的字符串
     * @param $sign 签名结果
     * @param $key 私钥
     * return 签名结果
     */
	protected function md5Verify($prestr, $sign, $key) {
		$prestr = $prestr . $key;
		$mysgin = md5($prestr);
		if($mysgin == $sign) {
			return true;
		} else {
			return false;
		}
	}
	/**
	 * 生成订单号
	 */
	 protected function generateOrderNumber($length=4){
		$date=trim(date('Ymdhis ',time()));
		$number=trim($this->getRandNumber($length));
		return $date.$number;
	 }
	/**
	*生成不重复的随机数字
	*@paramint$start需要生成的数字开始范围
	*@paramint$end结束范围
	*@paramint$length需要生成的随机数个数
	*@returnnumber生成的随机数
	*/
	protected function getRandNumber($length=4){
		//初始化变量为0
		$connt = 0;
		//建一个新数组
		$temp = array();
		while($connt < $length){
		//在一定范围内随机生成一个数放入数组中
		$temp[] = mt_rand(0, 9);
		//$data = array_unique($temp);
		//去除数组中的重复值用了“翻翻法”，就是用array_flip()把数组的key和value交换两次。这种做法比用 array_unique() 快得多。	
		$data = array_flip(array_flip($temp));
		//将数组的数量存入变量count中	
		$connt = count($data);
		}
		//为数组赋予新的键名
		shuffle($data);
		//数组转字符串
		$str=implode(",", $data);
		//替换掉逗号
		$number=str_replace(',', '', $str);
		return $number;
	}
	/* 1.将数组内非空参数值的参数按照参数名从小到大排序（ASCII码字典序）
	 * 2.然后使URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串
	 */
	function ASCII($params = array()){
		//ksort()对数组按照键名进行升序排序
		ksort($params);
		//reset()内部指针指向数组中的第一个元素
		reset($params);
		//$sign = http_build_query($params, '', '&amp');
		$sign = '';//初始化
		foreach ($params as $key => $val) { //遍历POST参数
			if ($val == ''||$key == 'sign') continue; //跳过这些不签名
			if ($sign) $sign .= '&'; //第一个字符串签名不加& 其他加&连接起来参数
			$sign .= "$key=$val"; //拼接为url参数形式
		}
		return $sign;
	}
	/**
	 * 建立跳转请求表单
	 * @param string $url 数据提交跳转到的URL
	 * @param array $data 请求参数数组
	 * @param string $method 提交方式：post或get 默认post
	 * @return string 提交表单的HTML文本
	 */
	protected function buildRequestForm($url, $data, $method = 'post')
	{
		$sHtml = "<form id='requestForm' name='requestForm' action='".$url."' method='".$method."'>";
		while (list ($key, $val) = each ($data))
		{
			$sHtml.= "<input type='hidden' name='".$key."' value='".$val."' />";
		}
		$sHtml = $sHtml."<input type='submit' value='正在跳转到支付'></form>";
		$sHtml = $sHtml."<script>document.forms['requestForm'].submit();</script>";
		return $sHtml;
	}
}