<?php
 /**
 *      [XCECP] (C) Colorful Network Inc.
 *      This is NOT a freeware, use is subject to license terms
 */
if(!defined("IN_QKWEB")){exit("Access Denied");}
class Cmbc extends Pay{
	private $config;
	private $args;
	private $autoSubmit = true;
	public $msg;
	public $action = array();
	function __construct($config=false,$args=array()){
		if($config){
			$this->config = $config;
			if($config['autoSubmit']===true || $config['autoSubmit']===false){
				$this->autoSubmit = $config['autoSubmit'];
			}
			$this->args = $args;
			if($this->args['bank']){
				$this->args['defaultPayType'] = 'CSPay';
			}
		}
		$this->action = array("query"=>true);
	}
	function pay($paymentId,$amount,$tradeNo,$bank=''){
		$info = $this->paymentInfo($paymentId);$config = $info['config'];
		if(!$config){Msg::show('该支付接口未配置');}
		$config = unserialize($config);
		foreach($config as $item){ $config[$item['name']] = $item['value']; }
		$args['return_url'] = "http://".$_SERVER['HTTP_HOST']."/pay/payReturn/cmbc";
		$args['notify_url'] = "http://".$_SERVER['HTTP_HOST']."/pay/payNotify/cmbc";
		$args['amount'] = $amount;
		$args['subject'] = $_POST['subject'];
		$args['outTradeNo'] = $tradeNo;
		$config['autoSubmit']=true;
		$this->args = $args;
		$this->config = $config;
		echo $this->htmlpay();exit;
	}
	function htmlpay(){
		$config = $this->config;
		if(!$this->args['subject']){$this->args['subject']=$GLOBALS['siteConf']['siteName'];}
		$url = $this->config['gateway']?$this->config['gateway']:"https://epay.cmbc.com.cn/ipad/service.html?";
		$param=array(
			'service'=>$this->config['service'],
			'partner_id'=>$this->config['partner_id'],
			'input_charset'=>'utf-8',	 //utf-8 gbk gb2312
			'sign_type'=>'MD5',	//DSA RSA MD5
			'notify_url'=>$this->args['notify_url'],
			'out_trade_no'=>$this->args['outTradeNo'],
			'subject'=>$this->args['subject'],
			//'buyer_email'=>'',
			'seller_email'=>$this->config['seller_email'],
			'amount'=>$this->args['amount'],
			'body'=>$this->args['subject'],
			//'show_url'=>'',
			//'payMethod'=>''
			//'default_bank'=>''
			//'royalty_parameters'=>''
			'return_url'=>$this->args['return_url']
		);
		/*
		if($this->args['bank'] && in_array($this->args['bank'],array('ICBCBTB','ABCBTB','CCBBTB','SPDBB2B','BOCBTB','CMBBTB','BOCB2C','ICBCB2C','CMB','CCB','ABC','SPDB','CIB','GDB','CMBC','CITIC','HZCBB2C','CEBBANK','SHBANK','NBBANK','SPABANK','BJRCB','FDB','POSTGC','abc1003','abc1004'))){
			$param['defaultbank']=$this->args['bank'];
			$param['paymethod']='bankPay';
		}
		*/
		$param['sign'] = $this->sign($param);
		ksort($param);
		$html = Pay::html($url,$param,'post',$this->config['autoSubmit']);
		return $html;
	}
	function sign($param){
		ksort($param);$str = '';$i=0;
		foreach($param as $key=>$val){$i++;if($key!='sign' && $val!=''){$str .= $key.'='.$val;if($i<count($param)){$str .= '&'; }}}
		$str .= $this->config['secret'];//echo $str.'<br/>';
		$sign = md5($str);
		return $sign;
	}

	function payReturn(){
		global $db;
		$outTradeNo	= trim($_GET['out_trade_no']);
		$paymentId = $db->getOne("select paymentId from qk_onlinepay where outTradeNo='$outTradeNo'");//echo $outTradeNo;exit;
		$config = $this->getConfig($paymentId);
		$config['sign_type']    = 'MD5';
		$payNotify = new CmbcNotify($config);
		$verify_result = $payNotify->verifyReturn();
		if($verify_result) {
			$tradeNo		= $_GET['trade_no'];
			$payAmount		= $_GET['total_fee'];
			if($_GET['trade_status'] == 'TRADE_FINISHED' && $_GET['is_success'] == 'T') {
					return true;
			}else {
					return false;
			}
		}else{
			return false;
		}
	}

	function payNotify(){
		$outTradeNo	= trim($_POST['out_trade_no']);
		if($outTradeNo){$log = '';foreach($_POST as $key=>$val){$log .= $key.'='.$val.'&';}if($log){saveLog('民生E支付通知数据：'.$log);}}
		$paymentId = $GLOBALS['db']->getOne("select paymentId from qk_onlinepay where outTradeNo='$outTradeNo'");
		$config = $this->getConfig($paymentId);
		$config['sign_type']='MD5';
		$payNotify = new CmbcNotify($config);
		$verify_result = $payNotify->verifyNotify();
		if($verify_result) {
			$tradeNo		= $_POST['pay_order_no'];		//获取支付宝交易号
			$payAmount		= $_POST['total_fee'];		//获取总价格
			if($_POST['trade_status'] == 'TRADE_FINISHED') {
					if($this->payResult($outTradeNo,$payAmount,$remark,$tradeNo)){						
					}else{
					}
					echo "true";
					return true;
			}else {
					return false;
			}
		}else{
			echo "false";
			return false;
		}
		exit;
	}
	function query($param){
		$this->msg='查询结果成功';
		$args['return_url'] = "http://".$_SERVER['HTTP_HOST']."/pay/payReturn/cmbc";
		$args['notify_url'] = "http://".$_SERVER['HTTP_HOST']."/pay/payNotify/cmbc";
		$pay_param = array(
			'service'=>'query_pay_by_platform',
			'partner_id'=>$this->config['partner_id'],
			'input_charset'=>'utf-8',
			'sign_type'=>'MD5',
			'notify_url'=>$args['notify_url'],
			'out_trade_no'=>$param['outTradeNo'],
			'return_url'=>$args['return_url'],
			'sign'=>'',
		);
		$pay_param['sign'] = $this->sign($pay_param);
		$url = 'https://epay.cmbc.com.cn/ipad/service.html?';
		
		$http = new http($url);
		$http->setPost($pay_param);saveLog('向民生E支付发送查询请求报文：URL：'.$url.' 参数：'.$http->_postFields);
		$http->setSsl(true);
		$http->maxredirs=1;
		$http->createCurl($url);
		$ret = $http->responseText();
		$retUrl=$http->getEffectiveUrl();
		if($retUrl==$url){
			if(preg_match("/&#37325;&#22797;&#25903;&#20184;&#35831;&#27714;&#25928;&#39564;&#19981;&#21512;&#27861;&#25110;&#25214;&#19981;&#21040;&#21407;&#26377;&#35760;&#24405;/",$ret)){
				$this->msg='重复支付请求效验不合法或找不到原有记录';
			}else{
				$this->msg='查询请求失败，请检测订单是否已提交到民生E支付';
			}
			return false;
		}
		$retUrlArr = explode('?',$retUrl);
		$retParam = $retUrlArr[1];
		if(!$retParam){ $this->msg='民生E支付返回参数检测失败';return false; }
		saveLog('向民生E支付接口查询支付状态返回结果：'.$retParam);
		if(preg_match("/is_success=T/",$retParam)){
			preg_match("/trade_status=([A-Z\_]+)&/",$retParam,$data);
			switch($data[1]){
				case 'TRADE_CREATED':$result='支付订单已创建';break;
				case 'TRADE_CLOSED':$result='支付订单已关闭';break;
				case 'TRADE_PAYED':$result='已支付';break;
				case 'TRADE_FAIL':$result='支付失败';break;
				case 'TRADE_FINISHED':$result='支付订单已完成';break;
				case 'TRADE_RESERVED':$result='已撤消';break;
			}
			$this->msg='民生E支付返回结果为：'.$result;
			return true;
		}else{
			$this->msg='民生E支付返回结果为：查询失败';
		}
		//echo $this->html($url,$pay_param);
		return false;
	}

	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" || $val == "" || $key=='md5_sign')continue;
			else	$para_filter[$key] = $para[$key];
		}
		return $para_filter;
	}
	function argSort($para) {
		ksort($para);
		reset($para);
		return $para;
	}
	function logResult($word='') {
		$fp = fopen("cmbc.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 getHttpResponsePOST($url, $cacert_url, $para, $input_charset = '') {
		if (trim($input_charset) != '') {$url = $url."_input_charset=".$input_charset;}
		$curl = curl_init($url);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);//SSL证书认证
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//严格认证
		curl_setopt($curl, CURLOPT_CAINFO,$cacert_url);//证书地址
		curl_setopt($curl, CURLOPT_HEADER, 0 ); // 过滤HTTP头
		curl_setopt($curl,CURLOPT_RETURNTRANSFER, 1);// 显示输出结果
		curl_setopt($curl,CURLOPT_POST,true); // post传输数据
		curl_setopt($curl,CURLOPT_POSTFIELDS,$para);// post传输数据
		$responseText = curl_exec($curl);
		//var_dump( curl_error($curl) );//如果执行curl过程中出现异常，可打开此开关，以便查看异常内容
		curl_close($curl);
		return $responseText;
	}
	function getHttpResponseGET($url,$cacert_url) {
		$curl = curl_init($url);
		curl_setopt($curl, CURLOPT_HEADER, 0 ); // 过滤HTTP头
		curl_setopt($curl,CURLOPT_RETURNTRANSFER, 1);// 显示输出结果
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);//SSL证书认证
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//严格认证
		curl_setopt($curl, CURLOPT_CAINFO,$cacert_url);//证书地址
		$responseText = curl_exec($curl);
		//var_dump( curl_error($curl) );//如果执行curl过程中出现异常，可打开此开关，以便查看异常内容
		curl_close($curl);
		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 md5Sign($prestr, $key) {
		$prestr = $prestr . $key;
		return md5($prestr);
	}

	function md5Verify($prestr, $sign, $key) {
		$prestr = $prestr . $key;
		$mysgin = md5($prestr);//echo $prestr.' = '.$mysgin.' = '.$sign;
		if($mysgin == $sign) {
			return true;
		}
		else {
			return false;
		}
	}

}


class CmbcNotify {
	var $payConfig;
	function __construct($payConfig){ $this->payConfig = $payConfig; }
    function CmbcNotify($payConfig) { $this->__construct($payConfig);}
	function verifyNotify(){
		if(empty($_POST)) {return false;}
		else {
			$isSign = $this->getSignVeryfy($_POST, $_POST["sign"]);
			$responseTxt = 'true';
			//if (! empty($_POST["notify_id"])) {$responseTxt = $this->getResponse($_POST["notify_id"]);}
			//if ($isSign) {$isSignStr = 'true';}else {$isSignStr = 'false';}$log_text = "responseTxt=".$responseTxt."\n notify_url_log:isSign=".$isSignStr.",".createLinkString($_POST);
			//logResult($log_text);
			if (preg_match("/true$/i",$responseTxt) && $isSign) {return true;}
		}
		return false;
	}
	function verifyReturn(){
		if(empty($_GET)) {return false;}
		else {
			$pay_param['process_date'] = $_GET['process_date'];
			$pay_param['partner_id'] = $_GET['partner_id'];
			$pay_param['buyer_email'] = $_GET['buyer_email'];
			$pay_param['is_success'] = $_GET['is_success'];
			$pay_param['total_fee'] = $_GET['total_fee'];
			$pay_param['md5_sign'] = $_GET['md5_sign'];
			$pay_param['seller_email'] = $_GET['seller_email'];
			$pay_param['notify_id'] = $_GET['notify_id'];
			$pay_param['out_trade_no'] = $_GET['out_trade_no'];
			$pay_param['pay_order_no'] = $_GET['pay_order_no'];
			$pay_param['trade_status'] = $_GET['trade_status'];
			$isSign = $this->getSignVeryfy($pay_param, $pay_param["md5_sign"]);
			$responseTxt = 'true';
			//if (! empty($_GET["notify_id"])) {$responseTxt = $this->getResponse($_GET["notify_id"]);}
			//if ($isSign) {$isSignStr = 'true';}else {$isSignStr = 'false';}$log_text = "responseTxt=".$responseTxt."\n return_url_log:isSign=".$isSignStr.",".createLinkString($_GET);
			//logResult($log_text);
			if (preg_match("/true$/i",$responseTxt) && $isSign) {return true;}
		}
		return false;
	}
	function getSignVeryfy($para_temp, $sign) {
		$para_filter = Cmbc::paraFilter($para_temp);
		$para_sort = Cmbc::argSort($para_filter);
		$prestr = Cmbc::createLinkstring($para_sort);
		$isSgin = false;
		switch (strtoupper(trim($this->payConfig['sign_type']))) {
			case "MD5" :
				$isSgin = Cmbc::md5Verify($prestr, $sign, $this->payConfig['secret']);
				break;
			default :
				$isSgin = false;
		}
		return $isSgin;
	}
	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 = Cmbc::getHttpResponseGET($veryfy_url, $this->payConfig['cacert']);
		return $responseTxt;
	}
}


?>