• 农业银行快捷支付php版说明和实例代码



    接入的是shopnc,代码改改就可以用了,虽然不是一个完善的类,也可以按照类的方法直接调用,省得再去扣开发文档 农行在接收返回信息也会验证一次,还有一点就是页面通知返回结果

    一定要用服务器通知,不然会出异常问题,导致问题
    2016年5月12日11:15:41

      大概有一下几个文件,

    <?php
    
    class abchina{
        
           //农行网关
       const GATEWAY  = 'https://pay.abchina.com/ebus/trustpay/ReceiveMerchantTrxReqServlet';
       //标示
       private $code      = 'abchina';
        
         /**
    	 * 支付接口配置信息
    	 *
    	 * @var array
    	 */
        private $payment;
         /**
    	 * 订单信息
    	 *
    	 * @var array
    	 */
        private $order;
        /**
    	 * 发送至农行的参数
    	 *
    	 * @var array
    	 */
        private $parameter;
        
        //发送请求
        private $request;
        
        //订单数据
        private $orderitems;
        
        private $payment_info;
        private $order_info;
        private $res;
        
        //签名算法
        const SIGNATURE_ALGORITHM = 'SHA1withRSA';
        
        //商户编号
         const MERCHANTID = '';
        
        //商户私钥加密密码
        const MERCHANTCERTPASSWORD = '';
         
        //网上支付平台证书
        const TRUSTPAYCERTFILE= './TrustPay.cer';
        
        //商户证书储存目录档名
         const MERCHANTCERTFILE= './fuwuqi.pfx';
         
        //报文里有的东西 
         const  TRX_TYPE_PAY_REQ = "PayReq";
        public function __construct($payment_info = array(),$order_info = array()) {
                    $this->payment_info	= $payment_info;
        		$this->order_info	= $order_info;
            
        }
    
        //提交订单
        public function submit() {
              
    //        var_dump($this->payment_info);
    //        
    //        var_dump($this->order_info);
    //        die;
            
                //没有自己传参的不要随意修改
            
                $this->order["PayTypeID"] = 'ImmediatePay'; //设定交易类型
                $this->order["OrderNo"] = $this->order_info['pay_sn']; //设定订单编号  自己传参数
                $this->order["OrderAmount"] = $this->order_info['api_pay_amount']; //设定交易金额     自己传参数
    //            $this->order["OrderAmount"] = '0.01'; //设定交易金额     自己传参数 测试使用
                $this->order["CurrencyCode"] = 156; //设定交易币种
                $this->order["InstallmentMark"] = 0; //分期标识
                $this->order["OrderDate"] = date('Y/m/d'); //设定订单日期 (必要信息 - YYYY/MM/DD)
                $this->order["OrderTime"] = date('H:i:s'); //设定订单时间 (必要信息 - HH:MM:SS)
                $this->order["CommodityType"] = '0202'; //设置商品种类
    
                //2、订单明细
                $orderitem = array ();
                $orderitem["ProductName"] = "GG"; //商品名称  自己写随意
                $this->orderitems[0] = $orderitem;
    
    
                //3、生成支付请求对象
                $this->request["TrxType"] = self::TRX_TYPE_PAY_REQ; //设定交易类型
                $this->request["PaymentType"] = 'A'; //设定支付类型
                $this->request["PaymentLinkType"] = 1; //设定支付接入方式
                $this->request["NotifyType"] = 1; //设定通知方式
                $this->request["ResultNotifyURL"] = SHOP_SITE_URL."/api/payment/abchina/notify_url.php"; //设定通知URL地址 自己设定
                $this->request["IsBreakAccount"] = 0; //设定交易是否分账
       
     
            
            
                $aMerchantNo =1;
                //取得交易报文
                $tRequestMessage = $this->getRequestMessage();
                
    //            echo '<pre>';
    //            var_export($tRequestMessage);
    //            echo '</pre>';
    //            die;
                //组成完整交易报文
                $tRequestMessage = $this->composeRequestMessage($aMerchantNo,$tRequestMessage);
                
    //              echo '<pre>';
    //            var_export($tRequestMessage);
    //            echo '</pre>';
    //            die;
                //对交易报文进行签名
                $tRequestMessage = $this->signMessage($aMerchantNo, $tRequestMessage);
    //              echo '<pre>';
    //            var_export($tRequestMessage);
    //            echo '</pre>';
    //            die;
            //发送交易报文至网上支付平台
                $tResponseMessage = $this->sendMessage($aMerchantNo,$tRequestMessage);
                
                  //验证网上支付平台响应报文的签名 
               $this->res =   $this->verifySign($tResponseMessage);
                
                
                
              
               
    //            echo '<pre>';
    //            var_export($tResponseMessage);
    //            echo '</pre>';
                
              $PaymentURL =  self::GetValue($tResponseMessage,'PaymentURL') ;  
              $ReturnCode =  self::GetValue($tResponseMessage,'ReturnCode') ;  
              
              
             //验证报文签名正确而却返回码是0000,就可以跳转支付页面 
              if($this->res == 1 && $ReturnCode=='0000' ){
                  
                  header("Location:".$PaymentURL);
                  die;
              }else{
                  header('<meta http-equiv="content-type" content="text/html;charset=utf-8">');
                  die('abchina pay check error');
                  
              }
    
    //          var_dump($PaymentURL);
    //          
    //           var_dump($ReturnCode); 
    //            echo '<pre>';
    //            var_export(json_decode($tResponseMessage,true));
    //            echo '</pre>';
                
                
    //            var_dump($res);
    //            die;
                
    
        }
        
        public static function arrayRecursive(&$array, $function, $apply_to_keys_also = false){		
    		foreach ($array as $key => $value)
    		{ 
    			$array[$key] = $function($value); 
    		}
        } 
        protected function getRequestMessage() {
    		self :: arrayRecursive($this->order, "urlencode", false);
    		self :: arrayRecursive($this->request, "urlencode", false);
    		$js = '"Order":' . (json_encode(($this->order)));
    		$js = substr($js, 0, -1);
    		$js = $js . ',"OrderItems":[';
    		$count = count($this->orderitems, COUNT_NORMAL);
    		for ($i = 0; $i < $count; $i++) {
    			self :: arrayRecursive($this->orderitems[$i], "urlencode", false);
    			$js = $js . json_encode($this->orderitems[$i]);
    			if ($i < $count -1) {
    				$js = $js . ',';
    			}
    		}
    		$js = $js . ']}}';
    		$tMessage = json_encode($this->request);
    		$tMessage = substr($tMessage, 0, -1);
    		$tMessage = $tMessage . ',' . $js;
    		$tMessage = urldecode($tMessage);
    		return $tMessage;
                    
                    
        }
        
        private function composeRequestMessage($aMerchantNo,$aMessage) {
            $tMessage = "{"Version":"V3.0.0","Format":"JSON","Merchant":" . "{"ECMerchantType":"" . "EBUS" . "","MerchantID":"" . self::MERCHANTID . ""}," . ""TrxRequest":" . $aMessage . "}";
            return $tMessage;
        }
    
                
        private function signMessage($aMerchantNo, $aMessage) {
    //    public function signMessageOp() {
    
            //1、读取证书
            
    //          $tTrustPayCertFile = dirname(__FILE__).'/TrustPay.cer';
             $tTrustPayCertFile =  "fuwuqi.pfx";
    //          $iTrustpayCertificate = openssl_x509_read(self :: der2pem(file_get_contents($tTrustPayCertFile)));
              
    //          var_dump($tTrustPayCertFile);
    //           var_dump(self::MERCHANTCERTPASSWORD);
    //          die;
    
            
              openssl_pkcs12_read(file_get_contents($tTrustPayCertFile), $tCertificate, self::MERCHANTCERTPASSWORD);
              
    //          var_dump($tCertificate);
    //          die;
            
            //2、验证证书是否在有效期内
    	    $cer = openssl_x509_parse($tCertificate['cert']);
    //            var_dump($cer);
            //3、取得密钥
    	    $pkey = openssl_pkey_get_private($tCertificate['pkey']);
    //             var_dump($pkey);                   
                                    
                   $key = $pkey;
    //               $key = self :: $iMerchantKeys[$aMerchantNo -1];
    		$signature = '';
    		$data = strval($aMessage);
    		if (!openssl_sign($data, $signature, $key, OPENSSL_ALGO_SHA1)) {
    			return null;
    		}
    		$signature = base64_encode($signature);
    		$tMessage = "{"Message":$data" . "," . '"Signature-Algorithm":' . '"' . self :: SIGNATURE_ALGORITHM . '","Signature":"' . $signature . '"}';
    		return $tMessage;
                 
                    
    //                return $pkey;
    //                var_dump($iTrustpayCertificate);
            }
        
             private function sendMessage($aMerchantNo, $aMessage) {
                         //组成<MSG>段         
                    $tMessage = strval($aMessage);        
                    $tURL = self::GATEWAY;
                    $opts = array(
                            'http' => array(
                                'method' => 'POST',
                                'user_agent' => 'TrustPayClient V3.0.0',
                                'protocol_version' => 1.0,
                                'header' => array('Content-Type: text/html', 'Accept: */*'),
                                'content' => $tMessage
                            ), 
                            'ssl' => array(
                                'verify_peer' => false
                            )
                    );
    
                    $context = stream_context_create($opts);
                    $tResponseMessage = file_get_contents($tURL, false, $context);
                   
    //                $tTrxResponse = self::init($tResponseMessage);
    
                    return $tResponseMessage;
                 
             }
             
             private static function der2pem($der_data) {
    		$pem = chunk_split(base64_encode($der_data), 64, "
    ");
    		$pem = "-----BEGIN CERTIFICATE-----
    " . $pem . "-----END CERTIFICATE-----
    ";
    		return $pem;
    	}
             
             
            public static function verifySign($aMessage) {
                
                  $TrustPayFile =  "TrustPay.cer";
                
                  $iTrustpayCertificate = openssl_x509_read(self :: der2pem(file_get_contents($TrustPayFile)));
    
                  
                  $tTrxResponse =  self::GetValue($aMessage,'Message') ;
                  
                  $tSignBase64 = self::GetValue($aMessage,'Signature') ;
    
    
                  
                  $tSign = base64_decode($tSignBase64);
    	      $key = openssl_pkey_get_public($iTrustpayCertificate);
    	      $data = strval($tTrxResponse);
                    
     
                  return openssl_verify($data, $tSign, $key, OPENSSL_ALGO_SHA1); 
                        
            }
            
    
            public function GetValue($json,$aTag)
            {
                $json = $json;            
                $index = 0;
                $length = 0;
                $index = strpos($json, $aTag, 0);
                if ($index === false)
                    return "";
                do
                {
                	if($json[$index-1] === """ && $json[$index+strlen($aTag)] === """)                
                    {
                        break;
                    }
                    else
                    {
                        $index = strpos($json, $aTag, $index+1);
                        if ($index === false)
                    		return "";
                    }
                } while (true);
                $index = $index + strlen($aTag) + 2;            
                $c = $json[$index];
                if ($c === '{') 
    			{
    				$output = self::GetObjectValue($index, $json);
    			}
                if ($c === '"') 
                {
    				$output = self::GetStringValue($index, $json);
                }
                return $output;
            }
             private function GetObjectValue($index, $json)
            {
                $count = 0;
                $_output = "";
                do
                {
                    $c = $json[$index];                
                    if ($c === '{')
                    {                	
                        $count++;
                    }
                    if ($c === '}')
                        $count--;
    
                    if ($count !== 0)
                    {
                        $_output =$_output.$c;
                    }
                    else
                    {
                        $_output = $_output.$c;
                        return $_output;
                    }
                    $index++;
                } while (true);
            }
            
            private function GetStringValue($index, $json)
            {
                $index++;
                $_output = "";
                do
                {
                    $c = $json[$index++];
                    if ($c !== '"') 
                    {
                        $_output = $_output.$c;
                    }
                    else
                    {                	
                        return $_output;
                    }
    
                } while (true);
            }
            
            
            /**
    	 * 返回地址验证(同步)
    	 *
    	 * @param 
    	 * @return boolean
    	 */
    	public function return_verify(){
    	
                 $this->order["PayTypeID"] = 'ImmediatePay'; //设定交易类型
                $this->order["OrderNo"] = $this->order_info['pay_sn']; //设定订单编号  自己传参数
                $this->order["OrderAmount"] = $this->order_info['api_pay_amount']; //设定交易金额     自己传参数
    //            $this->order["OrderAmount"] = '0.01'; //设定交易金额     自己传参数 测试使用
                $this->order["CurrencyCode"] = 156; //设定交易币种
                $this->order["InstallmentMark"] = 0; //分期标识
                $this->order["OrderDate"] = date('Y/m/d'); //设定订单日期 (必要信息 - YYYY/MM/DD)
                $this->order["OrderTime"] = date('H:i:s'); //设定订单时间 (必要信息 - HH:MM:SS)
                $this->order["CommodityType"] = '0202'; //设置商品种类
    
                //2、订单明细
                $orderitem = array ();
                $orderitem["ProductName"] = "GG"; //商品名称  自己写随意
                $this->orderitems[0] = $orderitem;
    
    
                //3、生成支付请求对象
                $this->request["TrxType"] = self::TRX_TYPE_PAY_REQ; //设定交易类型
                $this->request["PaymentType"] = 'A'; //设定支付类型
                $this->request["PaymentLinkType"] = 1; //设定支付接入方式
                $this->request["NotifyType"] = 1; //设定通知方式
                $this->request["ResultNotifyURL"] = SHOP_SITE_URL."/api/payment/abchina/notify_url.php"; //设定通知URL地址 自己设定
                $this->request["IsBreakAccount"] = 0; //设定交易是否分账
       
     
            
            
                $aMerchantNo =1;
                //取得交易报文
                $tRequestMessage = $this->getRequestMessage();
                
    
                //组成完整交易报文
                $tRequestMessage = $this->composeRequestMessage($aMerchantNo,$tRequestMessage);
                
    
                //对交易报文进行签名
                $tRequestMessage = $this->signMessage($aMerchantNo, $tRequestMessage);
    
            //发送交易报文至网上支付平台
                $tResponseMessage = $this->sendMessage($aMerchantNo,$tRequestMessage);
                
                  //验证网上支付平台响应报文的签名 
                $this->res =   $this->verifySign($tResponseMessage);
             
                $PaymentURL =  self::GetValue($tResponseMessage,'PaymentURL') ;  
                $ReturnCode =  self::GetValue($tResponseMessage,'ReturnCode') ;  
              
                 
                
             //验证报文签名正确而却返回码是0000,就可以跳转支付页面 
              if($this->res == 1){  
                  return  true;
              }else{
                return false;           
              }
                
                
    	}
            
            public function getPayResult($param){
    	   return $this->res;
    	}
    }
    

      

    abchina.php

    notify.php

    <?php      
            
    error_reporting(7);
    
    
    
    
    
     function der2pem($der_data) {
    		$pem = chunk_split(base64_encode($der_data), 64, "
    ");
    		$pem = "-----BEGIN CERTIFICATE-----
    " . $pem . "-----END CERTIFICATE-----
    ";
    		return $pem;
    	}
            
    //$tt =  json_decode(json_encode((array) simplexml_load_string(base64_decode($_POST['MSG']))), true);
    
    
    function verifySignXML($aMessage) {
        include dirname(__FILE__)."/XMLDocument.php";
        $TrustPayFile =  dirname(__FILE__)."/TrustPay.cer";
        
        $iTrustpayCertificate = openssl_x509_read(der2pem(file_get_contents($TrustPayFile)));
        
    		$aMessage = new XMLDocument($aMessage);
    
    		$tTrxResponse = $aMessage->getValue('Message');
    		
    		$tSignBase64 = $aMessage->getValue('Signature');
    		
    		$tSign = base64_decode($tSignBase64);
    		$key = openssl_pkey_get_public($iTrustpayCertificate);
    		$data = strval($tTrxResponse);
                    $result['res'] = openssl_verify($data, $tSign, $key, OPENSSL_ALGO_SHA1);
                    $result['iRspRef'] =$aMessage->getValue('iRspRef'); //交易流水号
                    $result['OrderNo'] =$aMessage->getValue('OrderNo'); //网站交易订单号
                    $result['Amount'] =$aMessage->getValue('Amount');  //订单金额
                    $result['VoucherNo'] =$aMessage->getValue('VoucherNo');
                     
    		return $result; 
    
    	}
            
            
            
    
                
    
    
    $rr = verifySignXML(base64_decode($_POST['MSG']));
    //var_dump($rr);
    //die;
    
    if ($rr['res'] == 1) {
    
    $_GET['act']	= 'payment';
    $_GET['op']     = 'return';
    $_GET['payment_code'] = 'abchina';  
      
    
    $_GET['trade_no'] = $rr['iRspRef'];
    $_GET['out_trade_no'] = $rr['OrderNo'];
    $_GET['bank_total'] = $rr['Amount'];
    $_GET['extra_common_param'] = 'real_order';
    require_once(dirname(__FILE__).'/../../../index.php');
    } else {
    die('abchina notify check error');
    }
    

      XMLDocument.php

    <?php
    class XMLDocument
    {
        private $iXMLString = '';
    
    
        public function getFirstTagName()
        {
            $tTagName = null;
            $tStartIndex = strpos($this->iXMLString, '<');
            $tEndIndex = strpos($this->iXMLString, '>');
            if ($tEndIndex > $tStartIndex)
            {
                $tTagName = substr($this->iXMLString, $tStartIndex + 1, $tEndIndex - ($tStartIndex + 1));
            }
    
            return $tTagName;
        }
    
        public function __construct($aXMLString='')
        {
            $this->init($aXMLString);
        }
    
        public function init($aXMLString)
        {
            $this->iXMLString = $aXMLString;
            return $this;
        }
    
        public function __toString()
        {
            return $this->iXMLString;
        }
    
        public function getValue($aTag)
        {
            $tXMLDocument = null;
            $tStartIndex = strpos($this->iXMLString, '<'.trim($aTag).'>');
            $tEndIndex = strpos($this->iXMLString, '</'.trim($aTag).'>');
            if (($tStartIndex !== FALSE) && ($tEndIndex !== FALSE) && ($tStartIndex < $tEndIndex))
            {
                $tXMLDocument = substr($this->iXMLString, $tStartIndex + strlen($aTag) + 2, $tEndIndex - ($tStartIndex + strlen($aTag) + 2));
            }
            return $tXMLDocument;
        }
        
        public function getValueNoNull($aTag)
        {
            $tValue = "";
            $tXML = $this->getValue($aTag);
            if ($tXML !== null)
            {
                $tValue = $tXML;
            }
            return $tValue;
        }
    
        public function getValueArray($aTag)
        {
            $tValues = array();
            $offset = 0;
            while(TRUE)
            {
                $tStartIndex = strpos($this->iXMLString, '<'.trim($aTag).'>', $offset);
                $tEndIndex = strpos($this->iXMLString, '</'.trim($aTag).'>', $offset);
                if (($tStartIndex === FALSE) || ($tEndIndex === FALSE) || ($tStartIndex > $tEndIndex))
                {
                    break;
                }
                array_push($tValues, new XMLDocument(substr($this->iXMLString, $tStartIndex + strlen($aTag) + 2, $tEndIndex - ($tStartIndex + strlen($aTag) + 2))));
                $offset = $tEndIndex + 1;
            }
            return $tValues;
        }
    
        public function getValueArrayList($aTag)
        {
            return $this->getValueArray($aTag);
        }
    
        public function getDocuments($aTag)
        {
            return $this->getValueArray($aTag);
        }
        
        public function getFormatDocument($aSpace)
        {
            return $this->getFormatDocumentLevel(0, $aSpace);
        }
    
    
        private function getFormatDocumentLevel($aLevel, $aSpace)
        {
            $tSpace1 = str_repeat($aSpace, $aLevel + 1);
            $tTagName = $this->getFirstTagName();
            if ($tTagName === null)
            {
                return $this;
            }
            $tXMLString = "
    ";
            $tXMLDocument = new XMLDocument($this->iXMLString);
            while (($tTagName = $tXMLDocument->getFirstTagName()) !== null)
            {
                $tTemp = $tXMLDocument->getValue($tTagName);
                $tSpace = "";
                
                if ($tTemp->getFirstTagName() !== null)
                {
                    $tSpace = $tSpace1;
                }
                $tXMLString = "$tXMLString$tSpace1<$tTagName>".$tTemp->getFormatDocumentLevel($aLevel + 1, $aSpace)."$tSpace</$tTagName>
    ";
                $tXMLDocument = $tXMLDocument->deleteFirstTagDocument();
                           
            }
            return new XMLDocument($tXMLString);
        }
    
        public function deleteFirstTagDocument()
        {
            $tTagName = $this->getFirstTagName();
            $tStartIndex = strpos($this->iXMLString, "<$tTagName>");
            $tEndIndex = strpos($this->iXMLString, "</$tTagName>");
            if ($tEndIndex > $tStartIndex)
            {
                $this->iXMLString = substr($this->iXMLString, $tEndIndex + strlen($tTagName) + 3);
                if ($this->iXMLString === FALSE)
                {
                    $this->iXMLString = "";
                }
            }
            return $this;
        }
    
    }
    
    ?>

    代码包和开发文档说明下载地址 :http://download.csdn.net/detail/zh7314/9517627

    便宜没好货你懂的,或者你可以直接复制代码也是可以使用的

  • 相关阅读:
    Java学习day2
    Java 学习day1
    const
    数组
    scanf、printf、gets、puts的应用及区别
    指针数组和数组指针
    指针函数和函数指针
    nginx Windows版使用说明
    windows平台上nginx部署web.py(转)
    python安装程序是报这样的错UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 1: ordinal not in range(128)
  • 原文地址:https://www.cnblogs.com/zx-admin/p/5484962.html
Copyright © 2020-2023  润新知