php版交通银行网银支付接口开发入门教程


Posted in PHP onSeptember 26, 2016

本文实例讲述了php版交通银行网银支付接口实现方法。分享给大家供大家参考,具体如下:

概述:网银支付接口 和支付宝接口大体上差不多,主要的区别是 交通银行提供的 接口核心的比如,加密等是通过java实现的,所以,要想办法使php和java能正常的通信,为此,官方也提供了两套实现方法,一个是通过 socket 进行通信,另一个方法是通过 java 桥接,下面演示的是 socket方法.

1. 配置运行环境

1.1  安装java,自行到oracle官网下载 java,然后安装,并配置正确的 环境变量.

1.2  把 测试的证书导入到java 虚拟机.

keytool " -import -keystore "java虚拟机放置证书的地址" -storepass changeit -alias test_bocommca -file "证书路径" 完成导入。

例子:keytool" -import -keystore "C:\Program Files\Java\jre1.5\lib\security\cacerts" -storepass changeit -alias test_bocommca -file "C:\socket\cert\test_root.cer"

1.3  修改配置文件(in/B2CMerchantSocket.xml).

采用官方提供的测试 商号进行测试时,无需配置,否则要配置,具体看xml文件说明.

1.4  启动 socket 服务

window:启动  start.bat 及可.

linux:启动  ohup  sh.start,sh&  //使当前脚本脱离终端,并在后台运行。

2. 将网银集成到现有的系统,以mvc的结构进行说明.

2.1  将不变的参数 配置 写入配置文件:

$config['interfaceVersion'] = "1.0.0.0"; #接口版本
$config['tranType'] =0; #交易类别 0:B:C
$config['curType'] = 'CNY'; # 交易币种
$config['notifyType'] =1; #0=不通知 1=通知 2=抓取
$config['merURL'] = "/pay/notify";  # 主动通知url
$config['goodsURL'] = '/goods/1.html'; #取货url
$config['jumpSeconds'] =3; #跳转时间
$config['payBatchNo'] = ''; #商户批次号
$config['proxyMerName'] = ''; #代理商家名字
$config['proxyMerType'] = ''; #代理商类型
$config['proxyMerCredentials']= ''; #代理商家批次号
$config['netType'] = 0; #渠道编号
//以下是 新接口需要的参数
$config['socketUrl'] ="tcp://127.0.0.1:8891"; #socket url
$config['merID'] ='301310063009501'; #商户id 3013100630095012

2.2 Model

/**
 * 交通银行支付类
 */
class Bocom extends CI_Model {
 private $arrReturn=array();
 private $socket;
 public function __construct() {
 parent::__construct ();
 //加载交通银行配置文件
 $this->config->load('bocom');
 $this->socket=$this->config->item('socketUrl');
 }
 /**
 * 支付方法
 *
 * @param unknown $arr_data=array(
 * 'bill_no'=>
 * )
 */
 public function pay($arr_data){
 //获得表单传过来的数据
 $this->arrReturn['interfaceVersion'] = $this->config->item('interfaceVersion');
 $this->arrReturn['merID']    = $this->config->item('merID'); //商户号为固定
 $this->arrReturn['orderid'] = $arr_data['bill_no'];
 $this->arrReturn['orderDate'] = $arr_data['bill_date'];
 $this->arrReturn['orderTime'] = $arr_data['bill_time'];
 $this->arrReturn['tranType'] = $this->config->item('tranType');
 $this->arrReturn['amount']  = $arr_data['bill_fee'];
 $this->arrReturn['curType'] = $this->config->item('curType');
 $this->arrReturn['orderContent'] = isset($arr_data['bill_title'])?iconv('utf-8','gb2312',$arr_data["bill_title"]): ''; #订单内容
 $this->arrReturn['orderMono']   = isset($arr_data['bill_mono'])? iconv('utf-8','gb2312',$arr_data['bill_mono']):''; #商家备注
 $this->arrReturn['phdFlag']    = isset($arr_data['phpFlag'])?$arr_data['phpFlag']:'';
 $this->arrReturn['notifyType']  = $this->config->item('notifyType');
 $this->arrReturn['merURL']    = $this->config->item('merURL');
 $this->arrReturn['goodsURL']   = $this->config->item('goodsURL');
 $this->arrReturn['jumpSeconds']  = $this->config->item('jumpSeconds');
 $this->arrReturn['payBatchNo']  = $this->config->item('payBatchNo');
 $this->arrReturn['proxyMerName'] = $this->config->item('proxyMerName');
 $this->arrReturn['proxyMerType'] = $this->config->item('proxyMerType');
 $this->arrReturn['proxyMerCredentials']= $this->config->item('proxyMerCredentials');
 $this->arrReturn['netType']    = $this->config->item('netType');
 //以下参数 不参与签名
 $this->arrReturn['issBankNo']   =isset($arr_data['code_id'])? trim($arr_data['code_id']):'';
 $tranCode = "cb2200_sign";
 $source='';
 $len = count($this->arrReturn)-1;$j=1;
 foreach($this->arrReturn as $v){
  if($j<=$len){
  $source.=$v."|";
  }
  $j++;
 }
 $source= substr($source, 0,strlen($source)-1);
   $fp= stream_socket_client($this->socket,$errno, $errstr, 30);
   $retMsg="";
   if (!$fp) {
   log_message("info","socket连接失败");
   return false;
   } else
   {
   $in = "<?xml version='1.0' encoding='gbk2312'?>";
 $in .= "<Message>";
 $in .= "<TranCode>".$tranCode."</TranCode>";
 $in .= "<MsgContent>".$source."</MsgContent>";
 $in .= "</Message>";
 fwrite($fp, $in);
    while (!feof($fp)) {
    $retMsg =$retMsg.fgets($fp, 1024);
    }
    fclose($fp);
   }
  if(false!==$xml_arr=$this->xmlParse($retMsg)){
    if(is_array($xml_arr)){
    foreach($xml_arr as $k=>$v){
     $this->arrReturn[$k]=$v;
    }
    }else{
    return false;
    }
  }else{
   return false;
  }
  return $this->arrReturn;
 }
 /**
 * 解析XML
 */
 public function xmlParse($retMsg){
 $arr=array();
 //解析返回xml
 $dom = new DOMDocument;
 $dom->loadXML($retMsg);
 $retCode = $dom->getElementsByTagName('retCode');
 $retCode_value = $retCode->item(0)->nodeValue;
 $errMsg = $dom->getElementsByTagName('errMsg');
 $errMsg_value = $errMsg->item(0)->nodeValue;
 $signMsg = $dom->getElementsByTagName('signMsg');
 $signMsg_value = $signMsg->item(0)->nodeValue;
 $orderUrl = $dom->getElementsByTagName('orderUrl');
 $orderUrl_value = $orderUrl->item(0)->nodeValue;
 $MerchID = $dom->getElementsByTagName('MerchID');
 $merID = $MerchID->item(0)->nodeValue;
 if($retCode_value != "0"){
  log_message("info","交易返回码:".$retCode_value);
  log_message("info","交易错误信息:".$errMsg_value);
      return false;
    }
  $arr['merSignMsg'] = $signMsg_value;
  $arr['merID']   = $merID;
  $arr['orderUrl']  = $orderUrl_value;
  return $arr;
 }
 /**
 * 交通银行 支付通知
 * @return boolean|unknown
 */
 public function notify(){
 $tranCode = "cb2200_verify";
 if(!isset($_REQUEST['notifyMsg'])){
  log_message("error","网银支付通知·非法请求");
  return false;
 }
 $notifyMsg = $_REQUEST["notifyMsg"];
 log_message("error",$notifyMsg."回调....");
 $lastIndex = strripos($notifyMsg,"|");
 $signMsg = substr($notifyMsg,$lastIndex+1); //签名信息
 $srcMsg = substr($notifyMsg,0,$lastIndex+1);//原文
 $merID = $this->config->item('merID');
 $fp = stream_socket_client($this->socket, $errno, $errstr, 30);
 $retMsg="";
 //
 if (!$fp) {
  echo "$errstr ($errno)<br />\n";
  log_message("error","$errstr ($errno)<br />\n");
 } else{
  $in = "<?xml version='1.0' encoding='gb2312'?>";
  $in .= "<Message>";
  $in .= "<TranCode>".$tranCode."</TranCode>";
  $in .= "<merchantID>".$merID."</merchantID>";
  $in .= "<MsgContent>".$notifyMsg."</MsgContent>";
  $in .= "</Message>";
 fwrite($fp, $in);
  while (!feof($fp)) {
   $retMsg =$retMsg.fgets($fp, 1024);
  }
  fclose($fp);
 }
 //解析返回xml
 $dom = new DOMDocument;
 $dom->loadXML($retMsg);
 $retCode = $dom->getElementsByTagName('retCode');
 $retCode_value = $retCode->item(0)->nodeValue;
 $errMsg = $dom->getElementsByTagName('errMsg');
 $errMsg_value = $errMsg->item(0)->nodeValue;
 if($retCode_value != '0')
 {
  log_message("error","交易错误信息:" .$errMsg_value."<br>");
  return false;
 }else{
  $arr = preg_split("/\|{1,}/",$srcMsg);
  if($arr[9]=="1"){
  return $this->updateBill($arr[1]);
  }
  log_message("error","交易失败:".$arr[13]."<br/>");
  return false;
 }
 }
 private function updateBill($billNo){
 // 更新 订单状态
 }
 //end class
}

2.3 控制器

$this->load->model("Bocom");

支付方法:

$this->arrData =$this->Bocom->pay($this->data);

通知:

$this->arrData =$this->Bocom->notify();

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP 处理图片的类实现代码
Oct 23 PHP
PHP中4个加速、缓存扩展的区别和选用建议
Mar 12 PHP
php 模拟 asp.net webFrom 按钮提交事件实例
Oct 13 PHP
php程序内部post数据的方法
Mar 31 PHP
PHP变量赋值、代入给JavaScript中的变量
Jun 29 PHP
PHP中抽象类、接口的区别与选择分析
Mar 29 PHP
PHP实现的通过参数生成MYSQL语句类完整实例
Apr 11 PHP
php自动载入类用法实例分析
Jun 24 PHP
PHP基于堆栈实现的高级计算器功能示例
Sep 15 PHP
PHP实现图的邻接矩阵表示及几种简单遍历算法分析
Nov 24 PHP
tp框架(thinkPHP)实现三次登陆密码错误之后锁定账号功能示例
May 24 PHP
laravel 实现向公共模板中传值 (view composer)
Oct 22 PHP
php版微信公众平台实现预约提交后发送email的方法
Sep 26 #PHP
php版微信公众平台入门教程之开发者认证的方法
Sep 26 #PHP
php is_executable判断给定文件名是否可执行实例
Sep 26 #PHP
PHP弱类型的安全问题详细总结
Sep 25 #PHP
php中mkdir()函数的权限问题分析
Sep 24 #PHP
php 生成Tab键或逗号分隔的CSV
Sep 24 #PHP
php 使用fopen函数创建、打开文件详解及实例代码
Sep 24 #PHP
You might like
一个简单的MySQL数据浏览器
2006/10/09 PHP
PHP中is_file不能替代file_exists的理由
2014/03/04 PHP
PHP中SERIALIZE和JSON的序列化与反序列化操作区别分析
2016/10/11 PHP
PHP实现的折半查找算法示例
2017/12/19 PHP
laravel框架模型中非静态方法也能静态调用的原理分析
2019/11/23 PHP
checkbox勾选判断代码分析
2014/06/11 Javascript
js中运算符&amp;&amp; 和 || 的使用记录
2014/08/21 Javascript
js判断当前页面在移动设备还是在PC端中打开
2016/01/06 Javascript
javascript HTML5文件上传FileReader API
2020/03/27 Javascript
jQuery中JSONP的两种实现方式详解
2016/09/26 Javascript
Vue响应式添加、修改数组和对象的值
2017/03/20 Javascript
捕获未处理的Promise错误方法
2017/10/13 Javascript
Vue2.0用户权限控制解决方案
2017/11/29 Javascript
浅谈JavaScript中this的指向问题
2020/07/28 Javascript
vue cli 3.0通用打包配置代码,不分一二级目录
2020/09/02 Javascript
Vant picker 多级联动操作
2020/11/02 Javascript
[49:21]2018DOTA2亚洲邀请赛3月30日 小组赛B组 Effect VS iG
2018/03/31 DOTA
python动态性强类型用法实例
2015/05/09 Python
浅谈django model的get和filter方法的区别(必看篇)
2017/05/23 Python
Python实现自动发送邮件功能
2021/03/02 Python
Python实现的视频播放器功能完整示例
2018/02/01 Python
django连接mysql配置方法总结(推荐)
2018/08/18 Python
用python实现k近邻算法的示例代码
2018/09/06 Python
git查看、创建、删除、本地、远程分支方法详解
2020/02/18 Python
浅谈TensorFlow之稀疏张量表示
2020/06/30 Python
协程Python 中实现多任务耗资源最小的方式
2020/10/19 Python
CSS3 对过渡(transition)进行调速以及延时
2020/10/21 HTML / CSS
美国睫毛、眉毛精华液领导品牌:RevitaLash Cosmetics
2018/03/26 全球购物
KELLER SPORTS荷兰:在线订购最好的运动产品
2020/10/13 全球购物
保加利亚手表、香水、化妆品和珠宝购物网站:Brasty.bg
2020/04/22 全球购物
幼儿园教师国培感言
2014/02/02 职场文书
保险经纪人求职信
2014/03/11 职场文书
大学生推广普通话演讲稿
2014/09/21 职场文书
2015年领导干部廉洁自律工作总结
2015/05/26 职场文书
Python机器学习之PCA降维算法详解
2021/05/19 Python
浅析MySQL如何实现事务隔离
2021/06/26 MySQL