银行项目网上支付接口调用测试实例

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 

公司最近有一个网站商城项目要开始开发了,这几天老板和几个同事一起开着需求会议,讨论了接下来的业务规划和需求策略,等技术需求一下来还要讨论技术需求,确认后再慢慢的进入开发阶段,趁着闲暇时间想总结一下进入公司不久接触过的一个关于银行支付API接口的调用,咱是第一次接触这类东西。

以后还是尽量养成写技术生活博客的习惯,工作了4年多,今年才开始想起来应该把自己的工作经历记录成文,形成经验积累和技术共享,以前很多经历都淡忘了,希望以后能够每每有点思绪就记录下来,时间长了也是一笔不小的积累和总结(好记性不如烂笔头),总不能工作这么多年一点技术经验积累记录都木有,实为缺憾哉!(语言组织能力欠佳,还望海涵)

一、API调用环境与相关配置详细说明

要在网上支持客户(或商城会员)使用交通银行(BOCOM,交行国际)支付方式买东西,首先公司得与交行

合作,要求其提供支付接口API(一般程序员都知道),等公司拿到API之后需要按照银行API要求调用的环

境安装一些软件(一般是由银行提供API安装包)以及配置各种参数:

从银行拿到的API安装包:

(图中start.bat文件是后来加的,具体作用后面会做说明)

各文件夹简要说明(我直接从doc文件夹里的技术开发说明文档拷贝过来的):

  • cert 提供商户端测试环境的商户测试证书、银行端测试环境测试根证书及    银行端生产环境根证书;
  • demo 存放交易演示Asp页面文件,商户可参照demo中的页面进行编程开发;起始页面:Index.htm;
  • doc 存放开发编程说明文档;
  • 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文件)打开进行安装导入到浏览器

(支付的时候需要验证是否安装了交行提供的证书,否则无法支付,交行也会返回相关验证信息):

一直点“下一步”直到填写密码处,默认密码是:12345678,再继续点“下一步”直到完成,

导入成功以后可以在浏览器中看到(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)第一个form:

1 <form id="form1" runat="server">

2 <!--除支付接口所需参数外的所有页面控件HTML代码比如选择银行的控件,确认支付按钮等-->

3 </form>

(2)第二个form:(注:以下各个参数安装包的开发文档中都有说明。每个参数具体注释请见后面的后台代码注释)


1 <form id="form2" name="form2" method="post" action="<%=orderUrl %>">

2 <input type="hidden" name="interfaceVersion" value="<%=interfaceVersion%>" />

3 <input type="hidden" name="merID" value="<%=merID%>" />

4 <input type="hidden" name="orderid" value="<%=orderid%>" />

5 <input type="hidden" name="orderDate" value="<%=orderDate%>" />

6 <input type="hidden" name="orderTime" value="<%=orderTime%>" />

7 <input type="hidden" name="tranType" value="<%=tranType%>" />

8 <input type="hidden" name="amount" value="<%=amount%>" />

9 <input type="hidden" name="curType" value="<%=curType%>" />

10 <input type="hidden" name="orderContent" value="<%=orderContent%>" />

11 <input type="hidden" name="orderMono" value="<%=orderMono%>" />

12 <input type="hidden" name="phdFlag" value="<%=phdFlag%>" />

13 <input type="hidden" name="notifyType" value="<%=notifyType%>" />

14 <input type="hidden" name="merURL" value="<%=merURL%>" />

15 <input type="hidden" name="goodsURL" value="<%=goodsURL%>" />

16 <input type="hidden" name="jumpSeconds" value="<%=jumpSeconds%>" />

17 <input type="hidden" name="payBatchNo" value="<%=payBatchNo%>" />

18 <input type="hidden" name="proxyMerName" value="<%=proxyMerName%>" />

19 <input type="hidden" name="proxyMerType" value="<%=proxyMerType%>" />

20 <input type="hidden" name="proxyMerCredentials" value="<%=proxyMercredentials%>" />

21 <input type="hidden" name="netType" value="<%=netType%>" />

22 <input type="hidden" name="merSignMsg" value="<%=merSignMsg%>" />

23 <input type="hidden" name="issBankNo" value="<%=issBankNo%>" />

24 </form>

(3).表单提交的js:

<script language="javascript" type="text/javascript">

function submitForm(form) {

setTimeout(function () {

$(form).submit();

}, 0);

}

</script>
2.后台代码

(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 #endregion

(2)把安装包里的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>");

}

#endregion

(4)银行返回支付结果后系统进行处理的代码:

需新建一个支付结果接收页面,也就是上面配置的取货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 version='1.0' encoding='UTF-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调用环境和调试支付接口的调用时遇到了一些问题,

通过技术主管跟银行方面沟通以及主管和自己的不断调试运行,最终支付接口的调用才成功,银行那边也返回了各种消息。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

​​​软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

第4章 文件系统接口测试 文件系统攻击分为两类:基于介质的攻击和基于文件的攻击 基于介质的攻击 基于介质的攻击目标是模拟存储介质本身-软盘、硬盘、CD-ROM等 攻击1 按容量填满文件系统 按容量填满文件系统会确保你的应用程序很好地处理满磁盘的情况。一旦Canned HEAT模拟了满状态下的磁盘,就应该抓住每个机会试者强制应用程序打开、关闭、读取、写入和修改文件。这样能发现访问文件的位置,但是对满状态下的磁盘,软件无法实施检查。 攻击2 强制介质忙或不可用 强制介质忙或不可用会保证与存在问题的存储设备相关的错误条件得到测试。其思想是,当应用程序访问硬驱、软驱或其他外部存储机制时,强制错误返回码标明介质存在的问题。如果开发人员无法对这些条件编写适当的错误处理程序,应用程序就会失效。 攻击3毁坏介质 模拟被破坏的存储介质对任务关键的应用程序是有用的,这种应用程序在受损介质下也必须仍然能够运行。这种攻击有助于对开发人员没有编写存取文件或写文件时的错误处理代码这种情况进行测试。 基于文件的攻击 攻击4 赋给无效文件名 赋给无效文件名用来发现在哪里没有对读取或写入文件标识符进行约束。由于名字常受限于操作系统,如果应用程序对名字没有真正的约束,创建有效名字的失败会引发失效。其思想就是试着用很长的,且包含非法字符和字符组合的名字进行命名。 如何进行攻击? 第一组测试是使应用程序进入相当于“另存为...”对话框,并键入操作系统不能接收的名字。 第二组测试是使用操作系统以应用程序可能不接收的有效文件名创建文件。 攻击5 改变文件访问许可 改变文件访问许可会发现难以察觉的隐错,当应用程序使用的文件可在该应用程序控制之外得到处理时才显示出来。该攻击强调创建和修改文件访问许可,然后驱动应用程序访问文件内容。如果用以检查各种许可处理的错误代码丢失或出错,那么应用程序就会失效。 如何进行攻击? 在不同应用程序中打开和关闭同一文件,并试着在某个应用程序中打开在另一个程序中已打开的文件。 攻击6 更改或破坏文件内容 更改和破坏文件内容模拟对文件故意地或偶然地修改。如果在读取文件以前没有编写错误代码来检查文件内容,则软件可能会崩溃。可使用Canned HEAT来模拟这些事件,以便测试员能强制文件操作,并密切观察可能的文件失效。 有两种基本方法来实现攻击-手工损坏文件或使用运行期故障植入作为文件进行操作。 文件系统攻击小结 基于介质的攻击 1.看软件是否能处理满状态的存储介质。填满硬驱,然后强制软件执行文件操作(通过打开、移动和保存文件)。 2.看软件是否能有条不紊地处理忙文件系统。一些应用程序没有真正的超时/等待机制,所以当文件系统忙于响应另一个应用程序的请求时就会失效。强制软件执行与后台应用程序相关联的文件操作,这些后台应用程序也在执行文件操作。 3.试图在受损介质上强制软件进行文件操作。在这种场景下,有一些故障的处理代码的应用程序常会失效。 基于文件的攻击 4.对应用程序的数据文件、临时文件和只读文件试图赋给无效文件名,然后强制软件使用这些文件。 5.修改应用程序数据文件的访问许可。用户许可和读-写-执行-删除许可常被开发人员所忽视。 6.看软件是否能处理文件中损坏的数据。由于大多数数据破坏会导致失败的循环冗余校验,所以Canned HEAT是植入这种故障的理想机制。否则,使用十六进制/文本编辑器来修改文件内容,然后强制软件打开文件或从中读取。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值