www.gusucode.com > ShopEx481 & PHPWind 整合版码程序 > plugins/payment/pay.icbc.php

    <?php
require('paymentPlugin.php');
class pay_icbc extends paymentPlugin{

	var $name = '中国工商银行[1.0.0.3版]';//工商银行
	var $logo = 'ICBC';
	var $version = 20070902;
	var $charset = 'utf-8';
	var $submitUrl = 'https://mybank.icbc.com.cn/servlet/com.icbc.inbs.b2c.pay.B2cMerPayReqServlet';
	var $submitButton = 'http://img.alipay.com/pimg/button_alipaybutton_o_a.gif'; ##需要完善的地方
	var $supportCurrency = array("CNY"=>"001");
	var $supportArea = array("AREA_CNY");
	var $intro = "中国工商银行网上银行B2C支付网关可以使用在windows主机和linux主机,请在申请工行网关接口时申请1.0.0.3版。";
	var $orderby = 12;
	function toSubmit($payment){
		$merId = $this->getConf($payment["M_OrderId"], 'member_id');
		$ikey = $this->getConf($payment["M_OrderId"], 'PrivateKey');
		if (strtoupper(substr(PHP_OS,0,3))=="WIN"){
			$bb = new COM("ICBCEBANKUTIL.B2CUtil");
			$pKey = $this->getConf($payment["M_OrderId"], 'key1');
			$rc = $bb->init($pKey, $pKey, $this->getConf($payment["M_OrderId"], 'key2'), $ikey);
			//$src = $merId . $this->callbackUrl  . "HS" . $order->M_OrderId . $order->M_Amount . $order->M_Currency . "0";
			$src = $merId . $this->callbackUrl  . "HS" . $payment["M_OrderId"] . $payment["M_Amount"] . $payment["M_Currency"] . "0";
			$ssrc = $bb->signC($src, strlen($src));
			
			$rc = $bb->verifySignC($src, strlen($src), $ssrc, strlen($ssrc)); //数据签名
			$cert = $bb->getCert(1); //商户证书
			
			$return['merchantid'] = $merId;
			$return['interfaceType'] = "HS";
			$return['merURL'] = $this->callbackUrl;
			$return['orderid'] = $payment["M_OrderId"];//$order->M_OrderId;
			$return['amount'] = $payment["M_Amount"] * 100;//$order->M_Amount;
			$return['curType'] = $payment["M_Currency"];//$order->M_Currency;
			$return['hsmsgType'] =  "0";
			$return['signMsg'] = $ssrc;
			$return['cert'] = $cert;
		}
		else{
			 $this->submitUrl="https://B2C.icbc.com.cn/servlet/ICBCINBSEBusinessServlet";
			 $return['rnote'] = utf2local($payment['M_Remark'],"zh");

			 $realpath = dirname(__FILE__)."/../../cert/ICBC/";
			 $key = $realpath.$payment['keyFile'];//私钥文件
			 $cert = $realpath.$payment['certFile'];//公钥文件
			 /*
			 * passwd.php的内容为 $passwd=密码;
			 */
			 $pass = $payment['keyPass'];
			 
			 if(!file_exists($key)){ 
				die("ICBC key file not found!");
			 }
			 if(!file_exists($cert)){ 
				die("ICBC Cert file not found!");
			 }
			 /*/////////////////////////////////////////////////////////////////////
			 *      开始构建工行要求的参数
			 *///////////////////////////////////////////////////////////////////////
			 //接口名称固定为“ICBC_PERBANK_B2C”
			 $aREQ["interfaceName"] = "ICBC_PERBANK_B2C"; 
			 //接口版本目前为“1.0.0.0”
			 $aREQ["interfaceVersion"] = "1.0.0.3";
			 //商城代码,ICBC提供
			 $aREQ["merID"] = $payment['certNo'];
			 //商户帐号,ICBC提供
			 $aREQ["merAcct"] = $this->getConf($payment['M_OrderId'], 'member_id');
			 //接收银行通知地址,目前只支持http协议80端口
			 $aREQ["merURL"] = $this->callbackUrl;
			 //HS方式实时发送通知;AG方式不发送通知;
			 $aREQ["notifyType"] = "HS";
			 //订单号商户端产生,一天内不能重复,拼接上订单号和支付号。
			 $aREQ["orderid"] = $payment['M_OrderNO'].$payment['M_OrderId'];
			 //金额以分为单位
			 $aREQ["amount"] = $payment['M_Amount'] * 100;
			 //币种目前只支持人民币,代码为“001”
			 $aREQ["curType"] = "001"; 
			 //对于HS方式“0”:发送成功或者失败信息;“1”,只发送交易成功信息。
			 $aREQ["resultType"] = 0;
			 //14位时间戳
			 $aREQ["orderDate"] = date("YmdHis",time());
			 //$aREQ["orderDate"] = "20080620".date("His",time());
			 $aREQ["verifyJoinFlag"] = "0";
			 //以上五个字段用于客户支付页面显示
			 $aREQ["goodsID"] = "";
			 //网关只认GB2312
			 $aREQ["goodsName"]  = $payment['M_OrderNO'];
			 //$aREQ["goodsName"]  = "中文";
			 //$convert = new iconvex();
			 //$aREQ["goodsName"]  = $convert->utf82gb($aREQ["goodsName"]);
			 $aREQ["goodsNum"] = 1;
			 //运费金额以分为单位
			 $aREQ["carriageAmt"] = 0;
			 $aREQ["merHint"] = "";
			 //备注
			 $aREQ["remark1"] = utf2local($payment['rnote'],"zh");
			 //备注2
			 $aREQ["remark2"] = "";
			 //“1”判断该客户是否与商户联名;取值“0”不检验客户是否与商户联名。
			 $aREQ["verifyJoinFlag"] = 0;

			 //构造V3版的xml
			 $tranData = "<?xml version=\"1.0\" encoding=\"GBK\" standalone=\"no\"?><B2CReq><interfaceName>".$aREQ["interfaceName"]."</interfaceName><interfaceVersion>".$aREQ["interfaceVersion"]."</interfaceVersion><orderInfo><orderDate>".$aREQ["orderDate"]."</orderDate><orderid>". $aREQ["orderid"]."</orderid><amount>".$aREQ["amount"]."</amount><curType>".$aREQ["curType"]."</curType><merID>".$aREQ["merID"]."</merID><merAcct>".$aREQ["merAcct"]."</merAcct></orderInfo><custom><verifyJoinFlag>".$aREQ["verifyJoinFlag"]."</verifyJoinFlag><Language>ZH_CN</Language></custom><message><goodsID>".$aREQ["goodsID"]."</goodsID><goodsName>".$aREQ["goodsName"] ."</goodsName><goodsNum>".$aREQ["goodsNum"]."</goodsNum><carriageAmt>".$aREQ["carriageAmt"]."</carriageAmt><merHint>". $aREQ["merHint"]."</merHint><remark1>".$aREQ["remark1"]."</remark1><remark2>".$aREQ["remark2"]."</remark2><merURL>".$aREQ["merURL"]."</merURL><merVAR></merVAR></message></B2CReq>";
				
			
			 //商户签名数据BASE64编码
			 $cmd = "/bin/icbc_sign '{$key}' '{$passwd}' '{$tranData}'";
			 //error_log($cmd,3,__FILE__.".log");
			 $handle = popen($cmd, 'r');
			 $merSignMsg = fread($handle, 2096);
			 pclose($handle);
			 //商户证书公钥BASE64编码
			 //用二进制方式读取用户证书文件
			 $fp = fopen($cert,"rb");
			 $merCert = fread($fp,filesize($cert));
			 $merCert = base64_encode($merCert);
			 fclose($fp);
			 /*
			 1、订单只能使用POST方式提交;使用https协议通讯;
			 2、银行地址:
						生产则为				https://B2C.icbc.com.cn/servlet/ICBCINBSEBusinessServlet
						模拟测试环境		https://210.82.37.103/servlet/ICBCINBSEBusinessServlet
			 */		 
			 $aFinalReq['interfaceName'] = $aREQ["interfaceName"];
			 $aFinalReq['interfaceVersion'] = $aREQ["interfaceVersion"];
			 $aFinalReq['tranData'] = base64_encode($tranData);
			 $aFinalReq['merSignMsg'] = $merSignMsg;
			 $aFinalReq['merCert'] = $merCert;
			 foreach($aFinalReq as $key=>$val) {
				$return[$key]=$val;
			 }
			 $return['shopex_encoding']="gb2312";
		}
		return $return;
	}

	function callback($in,&$paymentId,&$money,&$message){
		if (strtoupper(substr(PHP_OS,0,3))=="WIN"){
			$UserID = $in["UserID"];
			$orderNum = $in["orderNum"];
			$amount = $in["amount"];
			$tranDate = $in["tranDate"];
			$tranSerialNum = $in["tranSerialNum"];
			$authNum = $in["authNum"];
			$succMark = $in["succMark"];
			$comment = $in["comment"];
			$curType = $in["curType"];
			$hsmsgType = $in["hsmsgType"];
			$signMsg = $in["signMsg"];

			$paymentId = $orderNum;
			$money = $amount/100;

			if ($succMark == 0){ //成功
				return PAY_SUCCESS;
			} else { // 失败
				$message = '支付失败,请立即与商店管理员联系';
				return PAY_FAILED;
			}
		}
		else{
			$realpath = dirname(__FILE__)."/../../cert/ICBC/";
			$oPay=$this->system->loadModel("trading/payment");
			$oPayF=$oPay->getPaymentFileByType("ICBC");

			$icbcpubcert = $realpath.$in['icbcfile'];//工行公钥文件

			if(!file_exists($icbcpubcert)){
			  die("ICBC cert file not found!");
			}

			//error_log(var_export($_POST,true),3,__FILE__.".log");
			$notifyData = $in['notifyData'];
			$notifyData = base64_decode($notifyData);
			$signMsg = $in['signMsg'];

			//用工行的公钥做验证
			$cmd = "/bin/icbc_verify '{$icbcpubcert}' '{$notifyData}' '{$signMsg}'";
			$handle = popen($cmd, 'r');
			$isok = fread($handle, 8);
			pclose($handle);
			//////////////////////////////////////////////////////////////////////////////
			//给工行返回一个地址,工行跳回来用
			if(intval($isok) == 1){
				//取出orderid和tranStat
				preg_match("/\<orderid\>(.*)\<\/orderid\>.+\<tranStat\>(.*)\<\/tranStat\>/i",$notifyData,$rnt);
				$orderid = $rnt[1];
				$tranStat = $rnt[2];
				//分拆支付号和订单号
				//ShopEx支付号
				$paymentId = $payid = substr($orderid,-6);	
				//ShopEx订单号
				$orderid = substr($orderid,0,14);	
				
				if($tranStat == 1){
					$paymentId = $orderId;
					$money = $in['amount']/100;
					$message="支付成功!";
					return PAY_SUCCESS;
				}else{
					$message="支付失败!";
					return PAY_FAIL;
				}
			}else{
					$message="支付出错!";
					return PAY_ERROR;
			}
		}

	}

	function getfields(){
		if (strtoupper(substr(PHP_OS,0,3))=="WIN"){
			return array(
				'member_id'=>array(
							'label'=>'客户号',
							'type'=>'string',
							'helpMsg'=>'此处填写您的支付帐号、客户号或客户id等,此帐号在支付服务提供商处取得;'
						),
					'PrivateKey'=>array(
							'label'=>'私钥',
							'type'=>'string',
							'helpMsg'=>'证书拆分过程中输入的保存私钥 “口令”'
					),
					"key1"=>array(
							'label'=>'私钥文件1',
							'type'=>'file',
							'helpMsg'=>'此处上传拆分出来的user.crt文件;'
					),
					'key2'=>array(
							'label'=>'私钥文件2',
							'type'=>'file',
							'helpMsg'=>'此处上传拆分出来的user.key文件;'
					)
			);
		}
		else{
			return array(
				"member_id"=>array(
					"label"=>'客户号',
					"type"=>'string'
				),
				'certNo'=>array(
					"label"=>'商户号',
					"type"=>'string'
				),
				'keyFile'=>array(
					"label"=>'商户私钥文件',
					"type"=>'file'
				),
				'certFile'=>array(
					"label"=>'商户公钥文件',
					"type"=>'file'
				),
				'icbcFile'=>array(
					"label"=>'工行公钥文件',
					"type"=>'file'
				), 
				'keyPass'=>array(
					"label"=>'私钥保护密码',
					"type"=>'string'
				),
			);
		}
	}
}
?>