<?php
class Alipaydirect extends Pay{
	private $info;
	private $path;
	private $payConfig;
	var $https_verify_url = 'https://mapi.alipay.com/gateway.do?service=notify_verify&';
	var $http_verify_url = 'http://notify.alipay.com/trade/notify_query.do?';
	function __construct(){
		$path = str_replace("/Alipaydirect.class.php","/",str_replace("\\","/",__FILE__));
		$this->path = $path;
	}

	function pay($paymentId,$amount,$tradeNo){
		$payConfig = $this->getConfig($paymentId);
		if(!$payConfig){Msg::show('该支付接口未配置');}
		$this->payConfig = $payConfig;
		$this->payConfig['gateway']=$this->payConfig['gateway']?$this->config['gateway']:"https://mapi.alipay.com/gateway.do?_input_charset=utf-8";
		$this->payConfig['sign_type']='MD5';
		$this->payConfig['sign_type'] = strtoupper(trim($this->payConfig['sign_type']));
		$out_trade_no = $tradeNo;
		$subject      = $_POST['subject'];
		$body         = $_POST['body'];
		$total_fee    = $amount;
		$paymethod = 'directPay';
		if($bank && in_array($bank,array('UPOP','ALIPAY','ICBC','CCB','CMB','ABC','BOCOM','SPDB','GDB','BOC','PSBC','CNCB','CEB','CIB','PAB','CMBC','HXB','BCCB','BOS'))){ $paymethod = 'bankPay';$defaultbank = $bank; }
		$show_url			= 'http://'.$_SERVER['HTTP_HOST'];
		$info['return_url'] = "http://".$_SERVER['HTTP_HOST']."/pay/payReturn/alipaydirect";
		$info['notify_url'] = "http://".$_SERVER['HTTP_HOST']."/pay/payNotify/alipaydirect";
		$extra_common_param = $paybank;
		$payConfig['sign_type']    = 'MD5';
		$payConfig['input_charset']= 'utf-8';
		$payConfig['transport']    = 'http';
		$parameter = array(
				"service"			=> "create_direct_pay_by_user",
				"payment_type"		=> "1",
				"partner"			=> trim($payConfig['partner']),
				"_input_charset"	=> trim(strtolower($payConfig['input_charset'])),
				"seller_email"		=> trim($payConfig['seller_email']),
			   "return_url"		=> trim($info['return_url']),
				"notify_url"		=> trim($info['notify_url']),
				"out_trade_no"		=> $out_trade_no,
				"subject"			=> $subject,
				"body"				=> $body,
				"total_fee"			=> $total_fee,
				"paymethod"			=> $paymethod,
				"defaultbank"		=> $defaultbank,
				"buyer_email"=>"",
				"anti_phishing_key"	=> $anti_phishing_key,
				"exter_invoke_ip"	=> $exter_invoke_ip,
				"show_url"			=> $show_url,
				"extra_common_param"=> $extra_common_param,
				"royalty_type"		=> $royalty_type,
				"royalty_parameters"=> $royalty_parameters,
		);
		$button_name = "确认支付";
		$para = $this->buildRequestPara($parameter);
		$html_text=Pay::html($this->payConfig['gateway'],$para,"POST",true);
		echo $html_text;
	}
	
	function payReturn(){
		global $db;
		$outTradeNo	= trim($_GET['out_trade_no']);	//获取订单号
		$paymentId = $db->getOne("select paymentId from qk_onlinepay where outTradeNo='$outTradeNo'");
		$payConfig = $this->getConfig($paymentId);
		$payConfig['sign_type']    = 'MD5';
		$payConfig['input_charset']= 'utf-8';
		$payConfig['transport']    = 'http';
		$this->payConfig = $payConfig;
		$verify_result = $this->verifyReturn();
		if($verify_result) {
			$tradeNo		= $_GET['trade_no'];
			$payAmount		= $_GET['total_fee'];
			if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'TRADE_SUCCESS') {
					return true;
			}else {
					return false;
			}
		}else{
			return false;
		}
	}
	function payNotify(){
		global $db;
		$outTradeNo	= trim($_POST['out_trade_no']);	//获取订单号
		if($outTradeNo){$log = '';foreach($_POST as $key=>$val){$log .= $key.'='.$val.'&';}if($log){saveLog('支付宝通知数据：'.$log);}}
		$paymentId = $db->getOne("select paymentId from qk_onlinepay where outTradeNo='$outTradeNo'");
		$payConfig = $this->getConfig($paymentId);
		$payConfig['sign_type']    = 'MD5';
		$payConfig['input_charset']= 'utf-8';
		$payConfig['transport']    = 'http';
		$this->payConfig = $payConfig;
		$verify_result = $this->verifyNotify();
		if($verify_result) {
			$tradeNo		= $_POST['trade_no'];		//获取支付宝交易号
			$payAmount		= $_POST['total_fee'];		//获取总价格
			if($_POST['trade_status'] == 'TRADE_FINISHED' || $_POST['trade_status'] == 'TRADE_SUCCESS') {
					if($this->payResult($outTradeNo,$payAmount,$remark,$tradeNo)){
					}else{
					}
					echo "success";
					return true;
			}else {
					return false;
			}
		}else{
			echo "fail";
			return false;
		}
	}
	function query_timestamp() {
		$url = $this->alipay_gateway_new."service=query_timestamp&partner=".trim($this->payConfig['partner'])."&_input_charset=".trim(strtolower($this->payConfig['input_charset']));
		$encrypt_key = "";
		$doc = new DOMDocument();
		$doc->load($url);
		$itemEncrypt_key = $doc->getElementsByTagName( "encrypt_key" );
		$encrypt_key = $itemEncrypt_key->item(0)->nodeValue;
		return $encrypt_key;
	}
	function buildRequestPara($para_temp) {
		$para_filter = $this->paraFilter($para_temp);
		$para_sort = $this->argSort($para_filter);
		$mysign = $this->buildMysign($para_sort);
		$para_sort['sign'] = $mysign;
		$para_sort['sign_type'] = $this->payConfig['sign_type'];
		return $para_sort;
	}
	function buildRequestParaToString($para_temp) {
		$para = $this->buildRequestPara($para_temp);
		$request_data = createLinkstringUrlencode($para);
		return $request_data;
	}
	function sendPostInfo($para_temp, $gateway) {
		$xml_str = '';
		$request_data = $this->buildRequestParaToString($para_temp);
		$url = $gateway . $request_data;
		$xml_data = $this->getHttpResponse($url,trim(strtolower($this->payConfig['input_charset'])));
		$doc = new DOMDocument();
		$doc->loadXML($xml_data);
		return $doc;
	}
	function buildMysign($sort_para) {
		$prestr = $this->createLinkstring($sort_para);
		$prestr = $prestr.$this->payConfig['secret'];
		$mysgin = $this->sign($prestr);
		return $mysgin;
	}
	function createLinkstring($para) {
		$arg  = "";
		while (list ($key, $val) = each ($para)) {$arg.=$key."=".$val."&";}
		$arg = substr($arg,0,count($arg)-2);
		if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
		return $arg;
	}
	function createLinkstringUrlencode($para) {
		$arg  = "";
		while (list ($key, $val) = each ($para)) {$arg.=$key."=".urlencode($val)."&";}
		$arg = substr($arg,0,count($arg)-2);
		if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
		return $arg;
	}
	function paraFilter($para) {
		$para_filter = array();
		while (list ($key, $val) = each ($para)) {
			if($key == "sign" || $key == "sign_type" || $key == "a" || $key == "m" || $key == "act" || $key=="PATH_INFO" || $val == "")continue;
			else	$para_filter[$key] = $para[$key];
		}
		return $para_filter;
	}
	function argSort($para) { ksort($para);reset($para);return $para; }
	function sign($prestr) {
		$sign='';
		if($this->payConfig['sign_type'] == 'MD5') {
			$sign = md5($prestr);
		}elseif($this->payConfig['sign_type'] =='DSA') {
			die("DSA 签名方法待后续开发，请先使用MD5签名方式");
		}else {
			die("支付宝暂不支持".$signType."类型的签名方式");
		}
		return $sign;
	}

	function logResult($word='') {
		$fp = fopen("log.txt","a");
		flock($fp, LOCK_EX) ;
		fwrite($fp,"执行日期：".strftime("%Y%m%d%H%M%S",time())."\n".$word."\n");
		flock($fp, LOCK_UN);
		fclose($fp);
	}

	function getHttpResponse($url, $input_charset = '', $time_out = "60") {
		$urlarr     = parse_url($url);
		$errno      = "";
		$errstr     = "";
		$transports = "";
		$responseText = "";
		if($urlarr["scheme"] == "https") {
			$transports = "ssl://";
			$urlarr["port"] = "443";
		} else {
			$transports = "tcp://";
			$urlarr["port"] = "80";
		}
		$fp=@fsockopen($transports . $urlarr['host'],$urlarr['port'],$errno,$errstr,$time_out);
		if(!$fp) {
			die("ERROR: $errno - $errstr<br />\n");
		} else {
			if (trim($input_charset) == '') {
				fputs($fp, "POST ".$urlarr["path"]." HTTP/1.1\r\n");
			}
			else {
				fputs($fp, "POST ".$urlarr["path"].'?_input_charset='.$input_charset." HTTP/1.1\r\n");
			}
			fputs($fp, "Host: ".$urlarr["host"]."\r\n");
			fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
			fputs($fp, "Content-length: ".strlen($urlarr["query"])."\r\n");
			fputs($fp, "Connection: close\r\n\r\n");
			fputs($fp, $urlarr["query"] . "\r\n\r\n");
			while(!feof($fp)) {
				$responseText .= @fgets($fp, 1024);
			}
			fclose($fp);
			$responseText = trim(stristr($responseText,"\r\n\r\n"),"\r\n");
			
			return $responseText;
		}
	}

	function charsetEncode($input,$_output_charset ,$_input_charset) {
		$output = "";
		if(!isset($_output_charset) )$_output_charset  = $_input_charset;
		if($_input_charset == $_output_charset || $input ==null ) {
			$output = $input;
		} elseif (function_exists("mb_convert_encoding")) {
			$output = mb_convert_encoding($input,$_output_charset,$_input_charset);
		} elseif(function_exists("iconv")) {
			$output = iconv($_input_charset,$_output_charset,$input);
		} else die("sorry, you have no libs support for charset change.");
		return $output;
	}

	function charsetDecode($input,$_input_charset ,$_output_charset) {
		$output = "";
		if(!isset($_input_charset) )$_input_charset  = $_input_charset ;
		if($_input_charset == $_output_charset || $input ==null ) {
			$output = $input;
		} elseif (function_exists("mb_convert_encoding")) {
			$output = mb_convert_encoding($input,$_output_charset,$_input_charset);
		} elseif(function_exists("iconv")) {
			$output = iconv($_input_charset,$_output_charset,$input);
		} else die("sorry, you have no libs support for charset changes.");
		return $output;
	}
	function verifyNotify(){
		if(empty($_POST)) {return false;}
		else {
			$mysign = $this->getMysign($_POST);
			$responseTxt = 'true';
			//if (! empty($_POST["notify_id"])) {$responseTxt = $this->getResponse($_POST["notify_id"]);}
			//$log_text = "responseTxt=".$responseTxt."\n notify_url_log:sign=".$_POST["sign"]."&mysign=".$mysign.",";
			//$log_text = $log_text.createLinkString($_POST);
			//logResult($log_text);
			if (preg_match("/true$/i",$responseTxt) && $mysign == $_POST["sign"]) {
				return true;
			} else {
				return false;
			}
		}
	}
	function verifyReturn(){
		if(empty($_GET)) {return false;}
		else {
			$pay_param['buyer_email'] = $_GET['buyer_email'];
			$pay_param['buyer_id'] = $_GET['buyer_id'];
			$pay_param['exterface'] = $_GET['exterface'];
			$pay_param['is_success'] = $_GET['is_success'];
			$pay_param['notify_id'] = $_GET['notify_id'];
			$pay_param['notify_time'] = $_GET['notify_time'];
			$pay_param['notify_type'] = $_GET['notify_type'];
			$pay_param['out_trade_no'] = $_GET['out_trade_no'];
			$pay_param['payment_type'] = $_GET['payment_type'];
			$pay_param['seller_email'] = $_GET['seller_email'];
			$pay_param['seller_id'] = $_GET['seller_id'];
			$pay_param['subject'] = $_GET['subject'];
			$pay_param['total_fee'] = $_GET['total_fee'];
			$pay_param['trade_no'] = $_GET['trade_no'];
			$pay_param['trade_status'] = $_GET['trade_status'];
			$pay_param['sign'] = $_GET['sign'];
			$pay_param['sign_type'] = $_GET['sign_type'];
			$mysign = $this->getMysign($pay_param);
			$responseTxt = 'true';
			//if (! empty($pay_param["notify_id"])) {$responseTxt = $this->getResponse($pay_param["notify_id"]);}
			//$log_text = "responseTxt=".$responseTxt."\n notify_url_log:sign=".$_GET["sign"]."&mysign=".$mysign.",";
			//$log_text = $log_text.createLinkString($_GET);
			//logResult($log_text);
			if (preg_match("/true$/i",$responseTxt) && $mysign == $_GET["sign"]) {return true;} else {return false;}
		}
	}
	function getMysign($para_temp) {
		$para_filter = $this->paraFilter($para_temp);
		$para_sort = $this->argSort($para_filter);
		$mysign = $this->buildMysign($para_sort);
		return $mysign;
	}
	function getResponse($notify_id) {
		$transport = strtolower(trim($this->payConfig['transport']));
		$partner = trim($this->payConfig['partner']);
		$veryfy_url = '';
		if($transport == 'https') {$veryfy_url = $this->https_verify_url;}else {$veryfy_url = $this->http_verify_url;}
		$veryfy_url = $veryfy_url."partner=" . $partner . "&notify_id=" . $notify_id;
		$responseTxt = $this->getHttpResponse($veryfy_url);
		return $responseTxt;
	}
}
?>