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 HtmlReplace输入过滤安全函数
Jul 03 PHP
php fputcsv命令 写csv文件遇到的小问题(多维数组连接符)
May 24 PHP
php随机输出名人名言的代码
Oct 07 PHP
php三维数组去重(示例代码)
Nov 26 PHP
Windows和Linux中php代码调试工具Xdebug的安装与配置详解
May 08 PHP
ThinkPHP中RBAC类的四种用法分析
Nov 24 PHP
Symfony2之session与cookie用法小结
Mar 18 PHP
php并发加锁示例
Oct 17 PHP
php mysql操作mysql_connect连接数据库实例详解
Dec 26 PHP
PHP创建自己的Composer包方法
Apr 09 PHP
php5.6.x到php7.0.x特性小结
Aug 17 PHP
PHP获取真实IP及IP模拟方法解析
Nov 24 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
php下判断数组中是否存在相同的值array_unique
2008/03/25 PHP
基于jquery的超简单上下翻
2010/04/20 Javascript
Jquery练习之表单验证实现代码
2010/12/14 Javascript
原生js结合html5制作小飞龙的简易跳球
2015/03/30 Javascript
javascript 实现map集合
2015/04/03 Javascript
jQuery平滑旋转幻灯片特效代码分享
2015/09/07 Javascript
AngularJS中的$watch(),$digest()和$apply()区分
2016/04/04 Javascript
angularjs使用directive实现分页组件的示例
2017/02/07 Javascript
详解Vuex中mapState的具体用法
2017/09/28 Javascript
浅谈layui 表单元素的选中问题
2019/10/25 Javascript
如何通过javaScript去除字符串两端的空白字符
2020/02/06 Javascript
vue使用echarts图表自适应的几种解决方案
2020/12/04 Vue.js
Python新手入门最容易犯的错误总结
2017/04/24 Python
深入理解Python分布式爬虫原理
2017/11/23 Python
python merge、concat合并数据集的实例讲解
2018/04/12 Python
PyQT实现菜单中的复制,全选和清空的功能的方法
2019/06/17 Python
python 一篇文章搞懂装饰器所有用法(建议收藏)
2019/08/23 Python
Python selenium爬虫实现定时任务过程解析
2020/06/08 Python
Django-Scrapy生成后端json接口的方法示例
2020/10/06 Python
地图可视化神器kepler.gl python接口的使用方法
2020/12/22 Python
x-ua-compatible content=”IE=7, IE=9″意思理解
2013/07/22 HTML / CSS
解析html5 canvas实现背景鼠标连线动态效果代码
2019/06/17 HTML / CSS
BONIA官方网站:国际奢侈品牌和皮革专家
2016/11/27 全球购物
请说出你所知道的线程同步的方法
2013/04/19 面试题
如何找出EMP表里面SALARY第N高的employee
2013/12/05 面试题
治安消防安全责任书
2014/07/23 职场文书
社区两委对照检查材料
2014/08/23 职场文书
办理信用卡工作证明
2014/09/30 职场文书
2014年学校团委工作总结
2014/12/20 职场文书
安全员岗位职责范本
2015/04/11 职场文书
行政申诉状范文
2015/05/20 职场文书
小学少先队工作总结2015
2015/05/26 职场文书
赤壁观后感(2)
2015/06/15 职场文书
《刺客之王:C罗全景传记》:时代从来不会亏待手艺人
2019/11/28 职场文书
CSS3 实现的图片悬停的切换按钮
2021/04/13 HTML / CSS
MySql学习笔记之事务隔离级别详解
2021/05/12 MySQL