一、 前期准备
- 手机银行(WAP)B2C在线支付接口说明V1.0.0.6.doc
- 手机银行移动生活商户及门户网站js接口API.doc
- 支付组件ICBCEBankUtil.dll和infosecapi.dll
- 工行联测环境时间查看工具ICBCTime_V20141011.exe
- 测试公钥、商户公钥和私钥
- 个人银行测试帐号
Ps:工行运营提供开发文档时,没有直接提供支付组件ICBCEBankUtil.dll和infosecapi.dll,工行运营说有这个组件在文档中,但是没有找到,工行没有技术提供支持,后来在网上自己找的。
二、 环境搭配
- 复制支付组件ICBCEBankUtil.dll和infosecapi.dll到C盘中System32或System64文件夹下,在DOS窗口下切换目录System32或System64文件夹下 中运行regsvr32 ICBCEBankUtil.dll注册组件,并在项目中引用组件。
- IIS下解析项目,在程序池中修改启用32应用程序
Ps:本人使用的是64位系统,支付组件是放在System64文件夹下的,如果系统是32位,支付组件要放在System32文件夹下。使用DOS命令请使用管理员权限运行,否则注册失败。
三、编码
定义订单实体类:
1 //基本信息 2 public class B2CReq 3 { 4 ///5 /// 接口名称 6 /// 7 public string interfaceName { get; set; } 8 ///9 /// 接口版本号 10 /// 11 public string interfaceVersion { get; set; } 12 13 } 14 15 ///16 /// 订单信息 17 /// 18 public class OrderInfo 19 { 20 ///21 /// 交易日期时间 22 /// 23 public string orderDate { get; set; } 24 ///25 /// 订单号 26 /// 27 public string orderid { get; set; } 28 ///29 /// 订单金额 30 /// 31 public string amount { get; set; } 32 ///33 /// 分期付款期数 34 /// 35 public string installmentTimes { get; set; } 36 ///37 /// 支付币种 38 /// 39 public string curType { get; set; } 40 ///41 /// 商户代码 42 /// 43 public string merID { get; set; } 44 ///45 /// 商户账号 46 /// 47 public string merAcct { get; set; } 48 } 49 ///50 /// 客户信息 51 /// 52 public class Custom 53 { 54 ///55 /// 联名校验标志 56 /// 57 public string verifyJoinFlag { get; set; } 58 ///59 /// 语言版本 60 /// 61 public string Language { get; set; } 62 } 63 64 ///65 /// 信息 66 /// 67 public class Message 68 { 69 ///70 /// 商品编号 71 /// 72 public string goodsID { get; set; } 73 ///74 /// 商品名称 75 /// 76 public string goodsName { get; set; } 77 ///78 /// 商品数量 79 /// 80 public string goodsNum { get; set; } 81 ///82 /// 已含运费金额 83 /// 84 public string carriageAmt { get; set; } 85 ///86 /// 商城提示 87 /// 88 public string merHint { get; set; } 89 ///90 /// 备注字段1 91 /// 92 public string remark1 { get; set; } 93 ///94 /// 备注字段2 95 /// 96 public string remark2 { get; set; } 97 ///98 /// 通知商户URL 99 /// 100 public string merURL { get; set; }101 ///102 /// 返回商户变量103 /// 104 public string merVAR { get; set; }105 ///106 /// 通知类型107 /// 108 public string notifyType { get; set; }109 ///110 /// 结果发送类型111 /// 112 public string resultType { get; set; }113 ///114 /// 备用字段1115 /// 116 public string backup1 { get; set; }117 ///118 /// 备用字段2119 /// 120 public string backup2 { get; set; }121 ///122 /// 备用字段3123 /// 124 public string backup3 { get; set; }125 ///126 /// 备用字段4127 /// 128 public string backup4 { get; set; }129 }
帮助类
public class XmlHelper { ////// 根据模型生成一个xml,其中不包括类名 /// /// 模型 /// 属性值为空,xml生成是否返回该属性 ///public static StringBuilder ModelToXml(object Model, Flag flag) { StringBuilder Xml = new StringBuilder(); Type t = Model.GetType(); System.Reflection.PropertyInfo[] properties = t.GetProperties(); foreach (var item in properties) { var PropertiesValue = item.GetValue(Model, null); string PropertiesName = item.Name; if (PropertiesValue == null || string.IsNullOrEmpty(PropertiesValue.ToString())) { if (flag==Flag.Y) { Xml.AppendFormat("<{0}>{1} ", PropertiesName, PropertiesValue); } } else { Xml.AppendFormat("<{0}>{1} ", PropertiesName, PropertiesValue); } } return Xml; } /// /// 根据模型生成一个xml,其他不包括类名 /// /// 模型 /// 属性值为空,xml生成是否返回该属性 /// 对属性名称排序/可选(升序、降序) ///public static StringBuilder ModelToXml(object Model, Flag flag,Sort sort=Sort.Asc) { StringBuilder Xml = new StringBuilder(); Type t = Model.GetType(); System.Reflection.PropertyInfo[] properties = t.GetProperties(); Dictionary dic = new Dictionary (); foreach (var item in properties) { var PropertiesValue = item.GetValue(Model, null); string PropertiesName = item.Name; dic.Add(PropertiesName, PropertiesValue); } //对属性排序 var SortList = sort == Sort.Asc ? dic.OrderBy(o => o.Key) : dic.OrderByDescending(o => o.Key); foreach (var item in SortList) { if (item.Value == null || string.IsNullOrEmpty(item.Value.ToString())) { if (flag == Flag.Y) { Xml.AppendFormat("<{0}>{1} ", item.Key, item.Value); } } else { Xml.AppendFormat("<{0}>{1} ", item.Key, item.Value); } } return Xml; } /// /// 根据模型生成一个xml,其他不包括类名 /// /// 模型 /// 属性值为空,xml生成是否返回该属性 /// 对属性名称排序/可选(升序、降序) /// 父节点名称 ///public static StringBuilder ModelToXml(object Model, Flag flag, Sort sort,string RootName) { StringBuilder Xml = new StringBuilder(); Type t = Model.GetType(); System.Reflection.PropertyInfo[] properties = t.GetProperties(); Dictionary dic = new Dictionary (); Xml.AppendFormat("<{0}>",RootName); foreach (var item in properties) { var PropertiesValue = item.GetValue(Model, null); string PropertiesName = item.Name; dic.Add(PropertiesName, PropertiesValue); } //对属性排序 var SortList = sort == Sort.Asc ? dic.OrderBy(o => o.Key) : dic.OrderByDescending(o => o.Key); foreach (var item in SortList) { if (item.Value == null || string.IsNullOrEmpty(item.Value.ToString())) { if (flag == Flag.Y) { Xml.AppendFormat("<{0}>{1} ", item.Key, item.Value); } } else { Xml.AppendFormat("<{0}>{1} ", item.Key, item.Value); } } Xml.AppendFormat(" ", RootName); return Xml; } } /// /// 枚举 /// public enum Flag { ////// 是 /// Y, ////// 否 /// N }; ////// 排序 /// public enum Sort { ////// 升序 /// Asc, ////// 降序 /// Desc }; public class Too { //编码内容 public static string Base64Encode(string str) { byte[] b = System.Text.Encoding.Default.GetBytes(str); //转成Base64形式的System.String return Convert.ToBase64String(b); } //解码内容 public static string Base64Decode(string str) { byte[] outputb = Convert.FromBase64String(str); string orgStr = Encoding.Default.GetString(outputb); return orgStr; } }
组装支付报文信息
#region 订单信息 //在此自定义加密验证 string merVAR = "";//订单加密数据 string Url = "http://localhost:8076/Pay/Notify";//支付成功通知地址 string No = DateTime.Now.ToString("TestyyyyMMddHHmmssfff");//订单号 string PayPrice = "100";//订单金额以分为单位 string ProName = "充值卡";//产品名称 string merID = "";//商户号 string merAcct = "";//开户帐号 ///基本信息 B2CReq req = new B2CReq(); req.interfaceName = "ICBC_WAPB_B2C"; req.interfaceVersion = "1.0.0.6"; //订单信息 OrderInfo order = new OrderInfo(); order.orderDate = Convert.ToDateTime("2016/12/31 0:47:55").ToString("yyyyMMddHHmmss"); order.orderid = No; order.amount = PayPrice; order.installmentTimes = "1"; order.curType = "001"; order.merID = merID; order.merAcct = merAcct; //客户信息 Custom custom = new Custom(); custom.verifyJoinFlag = "0"; custom.Language = "zh_CN"; //信息 Message message = new Message(); message.goodsID = ""; message.goodsName = ProName; message.goodsNum = ""; message.carriageAmt = ""; message.merHint = ""; message.remark1 = ""; message.remark2 = ""; message.merURL = Url; message.merVAR = merVAR; message.notifyType = "HS"; message.resultType = "1"; message.backup1 = ""; message.backup2 = ""; message.backup3 = ""; message.backup4 = ""; #endregion #region 组装XML报文内容 //组装xml报文内容 StringBuilder tranDataContent = new StringBuilder(); tranDataContent.Append(" "); tranDataContent.Append(""); tranDataContent.Append(XmlHelper.ModelToXml(order, Flag.Y, Sort.Asc, "orderInfo"));//订单信息 tranDataContent.Append(XmlHelper.ModelToXml(custom, Flag.Y, Sort.Asc, "custom"));//客户信息 tranDataContent.Append(XmlHelper.ModelToXml(message, Flag.Y, Sort.Asc, "message"));//信息 tranDataContent.Append(" "); #endregion #region 编码报文内容、生成签名 string tranData = null; string merSignMsg = null; string merCert = null; //生成支付订单信息 tranData =Comm.Too.Base64Encode(tranDataContent.ToString()); B2CUtil icbcObj = new B2CUtil(); if (icbcObj.init(Server.MapPath("~/Deed/测试公钥ebb2cpublic.crt"), Server.MapPath("~/Deed/rp03.crt"), Server.MapPath("~/Deed/rp03.key"), "12345678") == 0) { merSignMsg = icbcObj.signC(tranDataContent.ToString(), tranDataContent.Length);//生成签名 } //BASE64商城证书公钥 merCert = icbcObj.getCert(1); #endregion #region 数据准完成,发送至页面 //参数传至HTML ViewBag.interfaceName = req.interfaceName; ViewBag.interfaceVersion = req.interfaceVersion; ViewBag.clientType = "0"; ViewBag.tranData = tranData; ViewBag.merSignMsg = merSignMsg; ViewBag.merCert = merCert; #endregion
发起支付H5
发起支付App
Ps:
1.在使用测试帐号的时候,订单日期必须与测试服务器一致,可以使用工行提供的工具获取服务器当前时间。
2.运行项目时需要启用32应用程序。
3.测试期间一般是使用H5支付,正式商户号申请完成之后,H5嵌入工行APP,使用工行APP支付。
组件下载
http://pan.baidu.com/s/1c2yyjWO
如有转载,请标明出处
http://www.cnblogs.com/cai-niao/p/6231428.html