<?php
if(!defined('DEDEINC')) exit('Request Error!');
/**
 * 支付寶接口類
 */
class Alipay
{
    var $dsql;
    var $mid;
    var $return_url = "/plus/carbuyaction.php?dopost=return";
    /**
     * 構造函數
     *
     * @access  public
     * @param
     *
     * @return void
     */
    function Alipay()
    {
        global $dsql;
        $this->dsql = $dsql;
    }

    function __construct()
    {
        $this->Alipay();
    }
    
    /**
     *  設定接口會送地址
     *
     *  例如: $this->SetReturnUrl($cfg_basehost."/tuangou/control/index.php?ac=pay&orderid=".$p2_Order)
     *
     * @param     string  $returnurl  會送地址
     * @return    void
     */
    function SetReturnUrl($returnurl='')
    {
        if (!empty($returnurl))
        {
            $this->return_url = $returnurl;
        }
    }

    /**
    * 生成支付代碼
    * @param   array   $order      訂單信息
    * @param   array   $payment    支付方式信息
    */
    function GetCode($order, $payment)
    {
        global $cfg_basehost,$cfg_cmspath,$cfg_soft_lang;
        $charset = $cfg_soft_lang;
        //對於二級目錄的處理
        if(!empty($cfg_cmspath)) $cfg_basehost = $cfg_basehost.'/'.$cfg_cmspath;

        $real_method = $payment['alipay_pay_method'];

        switch ($real_method){
            case '0':
                $service = 'trade_create_by_buyer';
                break;
            case '1':
                $service = 'create_partner_trade_by_buyer';
                break;
            case '2':
                $service = 'create_direct_pay_by_user';
                break;
        }
        $agent = 'C4335994340215837114';
        $parameter = array(
          'agent'             => $agent,
          'service'           => $service,
          'partner'           => $payment['alipay_partner'],
          //'partner'           => ALIPAY_ID,
          '_input_charset'    => $charset,
          'notify_url'        => $cfg_basehost.$this->return_url."&code=".$payment['code'],
          'return_url'        => $cfg_basehost.$this->return_url."&code=".$payment['code'],
          /* 業務參數 */
          'subject'           => "支付訂單號:".$order['out_trade_no'],
          'out_trade_no'      => $order['out_trade_no'],
          'price'             => $order['price'],
          'quantity'          => 1,
          'payment_type'      => 1,
          /* 物流參數 */
          'logistics_type'    => 'EXPRESS',
          'logistics_fee'     => 0,
          'logistics_payment' => 'BUYER_PAY_AFTER_RECEIVE',
          /* 買賣雙方信息 */
          'seller_email'      => $payment['alipay_account']
        );

        ksort($parameter);
        reset($parameter);

        $param = '';
        $sign  = '';

        foreach ($parameter AS $key => $val)
        {
            $param .= "$key=" .urlencode($val). "&";
            $sign  .= "$key=$val&";
        }

        $param = substr($param, 0, -1);
        $sign  = substr($sign, 0, -1). $payment['alipay_key'];

        $button = '<div style="text-align:center"><input type="button" onclick="window.open(\'https://www.alipay.com/cooperate/gateway.do?'.$param. '&sign='.md5($sign).'&sign_type=MD5\')" value="立即使用alipay支付寶支付"/></div>';

        /* 清空購物車 */
        require_once DEDEINC.'/shopcar.class.php';
        $cart     = new MemberShops();
        $cart->clearItem();
        $cart->MakeOrders();
        return $button;
    }

    
    /**
    * 響應操作
    */
    function respond()
    {
        if (!empty($_POST))
        {
            foreach($_POST as $key => $data)
            {
                $_GET[$key] = $data;
            }
        }
        /* 引入配置文件 */
        require_once DEDEDATA.'/payment/'.$_GET['code'].'.php';
        /* 取得訂單號 */
        $order_sn = trim($_GET['out_trade_no']);
        /*判斷訂單類型*/
        if(preg_match ("/S-P[0-9]+RN[0-9]/",$order_sn)) {
            //檢查支付金額是否相符
            $row = $this->dsql->GetOne("SELECT * FROM #@__shops_orders WHERE oid = '{$order_sn}'");
            if ($row['priceCount'] != $_GET['total_fee'])
            {
                return $msg = "支付失敗，支付金額與商品總價不相符!";
            }
            $this->mid = $row['userid'];
            $ordertype="goods";
        }else if (preg_match ("/M[0-9]+T[0-9]+RN[0-9]/", $order_sn)){
            $row = $this->dsql->GetOne("SELECT * FROM #@__member_operation WHERE buyid = '{$order_sn}'");
            //獲取訂單信息，檢查訂單的有效性
            if(!is_array($row)||$row['sta']==2) return $msg = "您的訂單已經處理，請不要重複提交!";
            elseif($row['money'] != $_GET['total_fee']) return $msg = "支付失敗，支付金額與商品總價不相符!";
            $ordertype = "member";
            $product =    $row['product'];
            $pname= $row['pname'];
            $pid=$row['pid'];
            $this->mid = $row['mid'];
        } else {    
            return $msg = "支付失敗，您的訂單號有問題！";
        }

        /* 檢查數字簽名是否正確 */
        ksort($_GET);
        reset($_GET);

        $sign = '';
        foreach ($_GET AS $key=>$val)
        {
            if ($key != 'sign' && $key != 'sign_type' && $key != 'code' && $key != 'dopost')
            {
                $sign .= "$key=$val&";
            }
        }

        $sign = substr($sign, 0, -1).$payment['alipay_key'];

        if (md5($sign) != $_GET['sign'])
        {
            return $msg = "支付失敗!";
        }

        if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'WAIT_SELLER_SEND_GOODS' || $_GET['trade_status'] == 'TRADE_SUCCESS')
        {
            if($ordertype=="goods"){ 
                if($this->success_db($order_sn))  return $msg = "支付成功!<br> <a href='/'>返回主頁</a> <a href='/member'>會員中心</a>";
                else  return $msg = "支付失敗！<br> <a href='/'>返回主頁</a> <a href='/member'>會員中心</a>";
            } else if ( $ordertype=="member" ) {
                $oldinf = $this->success_mem($order_sn,$pname,$product,$pid);
                return $msg = "<font color='red'>".$oldinf."</font><br> <a href='/'>返回主頁</a> <a href='/member'>會員中心</a>";
            }
        } else {
            $this->log_result ("verify_failed");
            return $msg = "支付失敗！<br> <a href='/'>返回主頁</a> <a href='/member'>會員中心</a>";
        }
    }

    /*處理物品交易*/
    function success_db($order_sn)
    {
        //獲取訂單信息，檢查訂單的有效性
        $row = $this->dsql->GetOne("SELECT state FROM #@__shops_orders WHERE oid='$order_sn' ");
        if($row['state'] > 0)
        {
            return TRUE;
        }    
        /* 改變訂單狀態_支付成功 */
        $sql = "UPDATE `#@__shops_orders` SET `state`='1' WHERE `oid`='$order_sn' AND `userid`='".$this->mid."'";
        if($this->dsql->ExecuteNoneQuery($sql))
        {
            $this->log_result("verify_success,訂單號:".$order_sn); //將驗證結果存入文件
            return TRUE;
        } else {
            $this->log_result ("verify_failed,訂單號:".$order_sn);//將驗證結果存入文件
            return FALSE;
        }
    }

    /*處理點卡，會員升級*/
    function success_mem($order_sn,$pname,$product,$pid)
    {
        //更新交易狀態為已付款
        $sql = "UPDATE `#@__member_operation` SET `sta`='1' WHERE `buyid`='$order_sn' AND `mid`='".$this->mid."'";
        $this->dsql->ExecuteNoneQuery($sql);

        /* 改變點卡訂單狀態_支付成功 */
        if($product=="card")
        {
            $row = $this->dsql->GetOne("SELECT cardid FROM #@__moneycard_record WHERE ctid='$pid' AND isexp='0' ");;
            //如果找不到某種類型的卡，直接為用戶增加金幣
            if(!is_array($row))
            {
                $nrow = $this->dsql->GetOne("SELECT num FROM #@__moneycard_type WHERE pname = '{$pname}'");
                $dnum = $nrow['num'];
                $sql1 = "UPDATE `#@__member` SET `money`=money+'{$nrow['num']}' WHERE `mid`='".$this->mid."'";
                $oldinf ="已經充值了".$nrow['num']."金幣到您的帳號！";
            } else {
                $cardid = $row['cardid'];
                $sql1=" UPDATE #@__moneycard_record SET uid='".$this->mid."',isexp='1',utime='".time()."' WHERE cardid='$cardid' ";
                $oldinf='您的充值密碼是：<font color="green">'.$cardid.'</font>';
            }
            //更新交易狀態為已關閉
            $sql2=" UPDATE #@__member_operation SET sta=2,oldinfo='$oldinf' WHERE buyid='$order_sn'";
            if($this->dsql->ExecuteNoneQuery($sql1) && $this->dsql->ExecuteNoneQuery($sql2))
            {
                $this->log_result("verify_success,訂單號:".$order_sn); //將驗證結果存入文件
                return $oldinf;
            } else {
                $this->log_result ("verify_failed,訂單號:".$order_sn);//將驗證結果存入文件
                return "支付失敗！";
            }
        /* 改變會員訂單狀態_支付成功 */
        } else if ( $product=="member" ){
            $row = $this->dsql->GetOne("SELECT rank,exptime FROM #@__member_type WHERE aid='$pid' ");
            $rank = $row['rank'];
            $exptime = $row['exptime'];
            /*計算原來升級剩餘的天數*/
            $rs = $this->dsql->GetOne("SELECT uptime,exptime FROM #@__member WHERE mid='".$this->mid."'");
            if($rs['uptime']!=0 && $rs['exptime']!=0 ) 
            {
                $nowtime = time();
                $mhasDay = $rs['exptime'] - ceil(($nowtime - $rs['uptime'])/3600/24) + 1;
                $mhasDay=($mhasDay>0)? $mhasDay : 0;
            }
            //獲取會員默認級別的金幣和積分數
            $memrank = $this->dsql->GetOne("SELECT money,scores FROM #@__arcrank WHERE rank='$rank'");
            //更新會員信息
            $sql1 =  " UPDATE #@__member SET rank='$rank',money=money+'{$memrank['money']}',
                       scores=scores+'{$memrank['scores']}',exptime='$exptime'+'$mhasDay',uptime='".time()."' 
                       WHERE mid='".$this->mid."'";
            //更新交易狀態為已關閉
            $sql2=" UPDATE #@__member_operation SET sta='2',oldinfo='會員升級成功!' WHERE buyid='$order_sn' ";
            if($this->dsql->ExecuteNoneQuery($sql1) && $this->dsql->ExecuteNoneQuery($sql2))
            {
                $this->log_result("verify_success,訂單號:".$order_sn); //將驗證結果存入文件
                return "會員升級成功！";
            } else {
                $this->log_result ("verify_failed,訂單號:".$order_sn);//將驗證結果存入文件
                return "會員升級失敗！";
            }
        }    
    }

    function  log_result($word) 
    {
        global $cfg_cmspath;
        $fp = fopen(dirname(__FILE__)."/../../data/payment/log.txt","a");
        flock($fp, LOCK_EX) ;
        fwrite($fp,$word.",執行日期:".strftime("%Y-%m-%d %H:%I:%S",time())."\r\n");
        flock($fp, LOCK_UN);
        fclose($fp);
    }
}//End API