点击文末小卡片免费获取软件测试全套资料资料在手涨薪更快公司最近有一个网站商城项目要开始开发了这几天老板和几个同事一起开着需求会议讨论了接下来的业务规划和需求策略等技术需求一下来还要讨论技术需求确认后再慢慢的进入开发阶段趁着闲暇时间想总结一下进入公司不久接触过的一个关于银行支付API接口的调用咱是第一次接触这类东西。以后还是尽量养成写技术生活博客的习惯工作了4年多今年才开始想起来应该把自己的工作经历记录成文形成经验积累和技术共享以前很多经历都淡忘了希望以后能够每每有点思绪就记录下来时间长了也是一笔不小的积累和总结好记性不如烂笔头总不能工作这么多年一点技术经验积累记录都木有实为缺憾哉语言组织能力欠佳还望海涵一、API调用环境与相关配置详细说明要在网上支持客户或商城会员使用交通银行BOCOM交行国际支付方式买东西首先公司得与交行合作要求其提供支付接口API一般程序员都知道等公司拿到API之后需要按照银行API要求调用的环境安装一些软件一般是由银行提供API安装包以及配置各种参数从银行拿到的API安装包图中start.bat文件是后来加的具体作用后面会做说明各文件夹简要说明我直接从doc文件夹里的技术开发说明文档拷贝过来的cert 提供商户端测试环境的商户测试证书、银行端测试环境测试根证书及 银行端生产环境根证书demo 存放交易演示Asp页面文件商户可参照demo中的页面进行编程开发起始页面Index.htmdoc 存放开发编程说明文档icon 交通银行logo徽标ini 商户端API配置文件API初始化需指定该配置文件配置文件内容包含地址的指定、证书的指定及日志存放目录指定等。setup 存放API的安装文件。lib 提供商户编程API所需全部 DLL 文件 里面会有一个安装说明如上图的简要说明.txt,打开后内有详细API安装及环境参数配置说明相信以上图片中白纸黑字大家都能看懂我为大家更详细介绍下上图所示文本中提到的 文档 是指由交行提供的另一个技术开发指导文档放在doc文件夹里注以下各种安装配置是配置的通用版的测试环境网上有下载的正式调用只需修改相关配置参数即可1.首先在网上下载最新版本jdk安装java运行环境根据自己电脑的情况选择合适版本的java运行环境我电脑是64位系统2.C盘新建文件夹commjava可自定义但要和后面相关参数的配置一致不知道可不可以装在别的盘待我后期测试再看看补起来将上图1中ini、cert文件夹复制进去3.将已经拷过去的文件夹cert中的证书文件PFX文件打开进行安装导入到浏览器支付的时候需要验证是否安装了交行提供的证书否则无法支付交行也会返回相关验证信息一直点“下一步”直到填写密码处默认密码是再继续点“下一步”直到完成导入成功以后可以在浏览器中看到Internet选项→内容→证书4.将之前安装包里的lib文件夹下所有的文件都拷到之前安装的jdk目录 Java\jre7\lib\ext 下同时也要复制一份拷到之前commjava文件夹下需先在commjava文件夹下新建lib目录或者干脆把整个lib文件夹拷进去并在commjava文件夹新建名为log和settlement的文件夹其中log用来存放下面提到的bat文件执行日志5.在任何一个文件夹新建一个.bat 批处理文件并执行我是新建在安装包目录下其实只要内容编辑正确放哪里都可以内容编辑按照你之前安装的目录自行修改编辑内容如下java -jar C:\bocommjava\lib\socket_c#.jar 8080 C:\bocommjava\ini\B2CMerchant.xml C:\bocommjava\log\socket.log这里采用8080端口命令大致意思是执行该批处理命令会调用jar包读取xml配置信息返回执行结果日志并在log目录下生成日志文件与执行结果日志一致。注该批处理文件打开后就不要关闭以后测试接口调用就是以这个为基础关掉后会无法调用笔者注这么一路配置下来总感觉网上银行支付接口的调用环境配置都是银行自己定义死了下面的页面调用很多配置也是定死的。。。只要有一个地方配置错误后面调用就会有问题。二、页面调用详细说明以上的准备工作做好后就可以在页面前后台代码中进行相关调用了。1.前台配置交行支付接口报文验证很严格报文中不能有其他任何规定之外的参数存在不然就会因验签失败而出错所以页面提交的时候一个form是不够的一个form用来放除支付接口所需参数外的所有页面控件HTML代码另一个form用来专门提交支付接口所需参数1第一个form1 form idform1 runatserver 2 !--除支付接口所需参数外的所有页面控件HTML代码比如选择银行的控件确认支付按钮等-- 3 /form2第二个form(注以下各个参数安装包的开发文档中都有说明。每个参数具体注释请见后面的后台代码注释)1 form idform2 nameform2 methodpost action%orderUrl % 2 input typehidden nameinterfaceVersion value%interfaceVersion% / 3 input typehidden namemerID value%merID% / 4 input typehidden nameorderid value%orderid% / 5 input typehidden nameorderDate value%orderDate% / 6 input typehidden nameorderTime value%orderTime% / 7 input typehidden nametranType value%tranType% / 8 input typehidden nameamount value%amount% / 9 input typehidden namecurType value%curType% / 10 input typehidden nameorderContent value%orderContent% / 11 input typehidden nameorderMono value%orderMono% / 12 input typehidden namephdFlag value%phdFlag% / 13 input typehidden namenotifyType value%notifyType% / 14 input typehidden namemerURL value%merURL% / 15 input typehidden namegoodsURL value%goodsURL% / 16 input typehidden namejumpSeconds value%jumpSeconds% / 17 input typehidden namepayBatchNo value%payBatchNo% / 18 input typehidden nameproxyMerName value%proxyMerName% / 19 input typehidden nameproxyMerType value%proxyMerType% / 20 input typehidden nameproxyMerCredentials value%proxyMercredentials% / 21 input typehidden namenetType value%netType% / 22 input typehidden namemerSignMsg value%merSignMsg% / 23 input typehidden nameissBankNo value%issBankNo% / 24 /form3.表单提交的jsscript languagejavascript typetext/javascript function submitForm(form) { setTimeout(function () { $(form).submit(); }, 0); } /script2.后台代码1网关传输参数初始化1 #region 交行网关传输参数 2 public string interfaceVersion 1.0.0.0; /*消息版本号,固定为1.0.0.0*/ 3 public string orderid DateTime.Now.ToString(yyyyMMddHHmmss); /*订单号,商户应保证3个月以上的唯一性*/ 4 public string orderDate DateTime.Now.ToString(yyyyMMdd); /*商户订单日期,格式yyyyMMdd*/ 5 public string orderTime DateTime.Now.ToString(HHmmss); /*商户订单时间,格式HHmmss*/ 6 public string tranType 0; /*交易类别 0 B2C*/ 7 public string amount 1; /*订单金额单位:元并带两位小数15位整数2位小数*/ 8 public string curType CNY; /*订单币种 人民币 CNY*/ 9 public string orderContent string.Empty; /*商家填写的其他订单信息在个人客户页面显示*/ 10 public string orderMono 6222600110030037084; /*不在个人客户页面显示的备注但可在商户管理页面上显示*/ 11 public string phdFlag string.Empty; /*物流配送标志0-非物流 1-物流配送*/ 12 public string notifyType 1; /*通知方式:0-不通知,1-通知,2-转页面*/ 13 public string jumpSeconds string.Empty; /*自动跳转时间,等待n秒后自动跳转取货URL若不填写则表示不自动跳转*/ 14 public string payBatchNo string.Empty; /*商户批次号,商家可填入自己的批次号对账使用*/ 15 public string proxyMerName string.Empty; /*代理商家名称,二级商户编号/或证件号码*/ 16 public string proxyMerType string.Empty; /*代理商家证件类型*/ 17 public string proxyMercredentials string.Empty; /*代理商家证件号码*/ 18 public string netType 0; /*渠道编号,固定填0:html渠道*/ 19 public string issBankNo BOCOM; /*发行卡机构号*/ 20 public string merURL ; /*主动通知URL,为空则不发通知*/ 21 public string goodsURL ../PayRuslut/COMMPayReslut.aspx; /*取货URL,显示商户最终订单支付结果信息,为空则不显示按钮不自动跳转*/ 22 public string merSignMsg string.Empty; /*发行卡机构号*/ 23 public string merID 301310063009501; /*网上支付授权码也就是上面导入的那个证书编号*/ 24 public string tranCode cb2200_sign; /*交易编号*/ 25 public string orderUrl string.Empty; /*订单最终的提交地址需要从xml配置文件里获取*/ 26 #endregion2把安装包里的demo文件下C#\netpay\App_Code 的 config.cs 文件拷贝到系统界面层修改其命名空间及其类名即可或者在你自己的代码中添加也可以只要能够供后面调用即可这个类的完整代码如下1 using System; 2 using System.Data; 3 using System.Configuration; 4 5 using System.Web; 6 using System.Web.Security; 7 using System.Web.UI; 8 using System.Web.UI.HtmlControls; 9 using System.Web.UI.WebControls; 10 using System.Web.UI.WebControls.WebParts; 11 12 using System.Net.Sockets; 13 14 /// summary 15 ///config 的摘要说明 16 ///配置的系统参数和通讯方法示例 17 /// 18 /// /summary 19 public class config 20 { 21 //商户号就是前面导入进去的那个证书编号 22 public static string merchantID 301310063009501; 23 //socket bridge通讯ip测试环境一般是本地正式生产环境中需要修改 24 public static string ip 127.0.0.1; 25 //socket bridge端口 26 public static int port 8080; 27 28 public config() 29 { 30 31 } 32 33 //与socket bridge通讯的方法示例 34 public string sendAndReceive(string sendMsg) 35 { 36 TcpClient client new TcpClient(config.ip, config.port); 37 NetworkStream stream client.GetStream(); 38 39 Byte[] data System.Text.Encoding.UTF8.GetBytes(sendMsg.ToString()); 40 stream.Write(data, 0, data.Length); 41 data new Byte[50 * 1024]; 42 String responseData String.Empty; 43 Int32 bytes stream.Read(data, 0, data.Length); 44 responseData System.Text.Encoding.UTF8.GetString(data, 0, bytes); 45 stream.Close(); 46 client.Close(); 47 return responseData; 48 } 49 }3.在支付提交的方法里加入如下代码#region 交行支付网关 orderid DateTime.Now.ToString(yyyyMMddHHmmss); /*订单号,商户应保证3个月以上的唯一性*/ amount _CountPayMoney.ToString(F2); /*订单金额单位:元并带两位小数15位整数2位小数*/ merID config.merchantID;/*获取证书编号*/ string issuerId IssUserID;/*银行代码交行为bocom*/ Random ro new Random(); string orderDatetime DateTime.Now.ToString(yyyy-MM-dd HH:mm:ss); int orderAmount Convert.ToInt32(Convert.ToDouble(_CountPayMoney.ToString(F2)) * 100); string ext1 OrderID 0; string ext2 VIPID.ToString();//会员帐号 //拼接商户订单支付所需信息字符串 orderMono _payType _ issuerId _ orderAmount _ ext1 _ ext2 _ orderDatetime; string sourceMsg interfaceVersion | merID | orderid | orderDate | orderTime | tranType | amount | curType | orderContent | orderMono | phdFlag | notifyType | merURL | goodsURL | jumpSeconds | payBatchNo | proxyMerName | proxyMerType | proxyMercredentials | netType; StringBuilder sendMsg new StringBuilder(); //组织申请报文 sendMsg.Append(Message) .Append(TranCode).Append(tranCode).Append(/TranCode) .Append(MsgContent) .Append(sourceMsg) .Append(/MsgContent/Message); string responseData new config().sendAndReceive(sendMsg.ToString()); //解析返回报文 XmlDocument xmlDoc new XmlDocument(); xmlDoc.LoadXml(responseData); XmlNodeList list xmlDoc.GetElementsByTagName(retCode); string retCode list.Item(0).InnerText.Trim(); list xmlDoc.GetElementsByTagName(errMsg); string errMsg list.Item(0).InnerText.Trim(); list xmlDoc.GetElementsByTagName(signMsg); merSignMsg list.Item(0).InnerText.Trim(); list xmlDoc.GetElementsByTagName(orderUrl); orderUrl list.Item(0).InnerText.Trim(); if (!retCode.Equals(0)) { Response.Write(交易返回码 retCode br); Response.Write(交易错误信息 errMsg br); } else { //提交 ClientScript.RegisterStartupScript(.GetType(), , script language\javascript\ type\text/javascript\submitForm(#form2);/script); } #endregion4银行返回支付结果后系统进行处理的代码需新建一个支付结果接收页面也就是上面配置的取货URL参数goodsURL里的aspx页面。在页面加载的时候调用protected void Page_Load(object sender, EventArgs e) { PayResult(); }1 /// summary 2 /// 支付返回结果 3 /// /summary 4 private void PayReslut() 5 { 6 string tranCode cb2200_verify; 7 string notifyMsg Request.Params.Get(notifyMsg); 8 9 StringBuilder sendMsg new StringBuilder(); 10 //sendMsg.Append(?xml version1.0 encodingUTF-8?) 11 //组织申请报文 12 sendMsg.Append(Message) 13 .Append(TranCode).Append(tranCode).Append(/TranCode) 14 .Append(MsgContent) 15 .Append(notifyMsg) 16 .Append(/MsgContent/Message); 17 18 TcpClient client new TcpClient(config.ip, config.port); 19 NetworkStream stream client.GetStream(); 20 21 Byte[] data System.Text.Encoding.UTF8.GetBytes(sendMsg.ToString()); 22 stream.Write(data, 0, data.Length); 23 data new Byte[50 * 1024]; 24 String responseData String.Empty; 25 Int32 bytes stream.Read(data, 0, data.Length); 26 responseData System.Text.Encoding.UTF8.GetString(data, 0, bytes); 27 stream.Close(); 28 client.Close(); 29 30 //解析返回报文 31 XmlDocument xmlDoc new XmlDocument(); 32 xmlDoc.LoadXml(responseData); 33 XmlNodeList list xmlDoc.GetElementsByTagName(retCode); 34 string retCode list.Item(0).InnerText.Trim(); 35 list xmlDoc.GetElementsByTagName(errMsg); 36 string errMsg list.Item(0).InnerText.Trim(); 37 38 if (!retCode.Equals(0)) 39 { 40 //支付失败 41 PayReslutShowH3.InnerHtml 当前订单本次支付失败; 42 PayReslutShowH3.Attributes.Add(class, paySuccess_p1F); 43 } 44 else 45 { 46 //支付成功 47 string[] strs notifyMsg.Split(|); 48 string[] orderMono Encoding.GetEncoding(utf-8).GetString(Convert.FromBase64String(strs[16])).Split(_); 49 decimal PayMoney Convert.ToDecimal(strs[2]);//获得支付的钱 50 decimal OrderMoney (Convert.ToDecimal(orderMono[2]) / 100);//获得订单钱 51 orderIDSpan.InnerHtml strs[1];//显示交行支付的订单号 52 PayMoneySpan.InnerHtml PayMoney.ToString(F2);//显示本次支付的钱 53 string[] _ext1 orderMono[3].Split(); 54 string PayType _ext1[1];//获得支付类型 0订单1充值2还款 3团购订单 4续费 55 string OrderID _ext1[0];//订单号订单支付的时候才会有 56 int VipID int.Parse(orderMono[4]);//会员ID号码 57 //BLL.HSSM_LinPayLog.Exists(paymentResult.getPaymentOrderId()) 58 if (HSSM_Public_DB.IsRecord(HSSM_LinPayLog, paymentOrderId OrderID ))/*判断是否重复支付根据支付的订单号进行判断*/ 59 { 60 PayReslutShowH3.InnerHtml 当前订单已经支付成功; 61 return; 62 } 63 if (PayMoney 0) 64 { 65 Response.Redirect(~/NullData.html); 66 return; 67 } #region 系统接收支付结果返回成功结果进行扣款操作 //相关代码略依据系统需求而定可能调用发送订单回执短信、邮件等 #endregion 256 } 257 }好了至此所有的相关配置以及代码就介绍完了。以上所有的过程都是按照成功运行之后回头总结的其实在配置API调用环境和调试支付接口的调用时遇到了一些问题通过技术主管跟银行方面沟通以及主管和自己的不断调试运行最终支付接口的调用才成功银行那边也返回了各种消息。写在最后最后感谢每一个认真阅读我文章的人礼尚往来总是要有的虽然不是什么很值钱的东西如果你用得到的话可以直接拿走这些资料对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴我走过了最艰难的路程希望也能帮助到你凡事要趁早特别是技术行业一定要提升技术功底。