工行ICBC_WAPB_B2C支付接口
一、 前期准备
- 手机银行(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命令请使用管理员权限运行,否则注册失败。
三、编码
定义订单实体类:
//基本信息
public class B2CReq
{
/// <summary>
/// 接口名称
/// </summary>
public string interfaceName { get; set; }
/// <summary>
/// 接口版本号
/// </summary>
public string interfaceVersion { get; set; } } /// <summary>
/// 订单信息
/// </summary>
public class OrderInfo
{
/// <summary>
/// 交易日期时间
/// </summary>
public string orderDate { get; set; }
/// <summary>
/// 订单号
/// </summary>
public string orderid { get; set; }
/// <summary>
/// 订单金额
/// </summary>
public string amount { get; set; }
/// <summary>
/// 分期付款期数
/// </summary>
public string installmentTimes { get; set; }
/// <summary>
/// 支付币种
/// </summary>
public string curType { get; set; }
/// <summary>
/// 商户代码
/// </summary>
public string merID { get; set; }
/// <summary>
/// 商户账号
/// </summary>
public string merAcct { get; set; }
}
/// <summary>
/// 客户信息
/// </summary>
public class Custom
{
/// <summary>
/// 联名校验标志
/// </summary>
public string verifyJoinFlag { get; set; }
/// <summary>
/// 语言版本
/// </summary>
public string Language { get; set; }
} /// <summary>
/// 信息
/// </summary>
public class Message
{
/// <summary>
/// 商品编号
/// </summary>
public string goodsID { get; set; }
/// <summary>
/// 商品名称
/// </summary>
public string goodsName { get; set; }
/// <summary>
/// 商品数量
/// </summary>
public string goodsNum { get; set; }
/// <summary>
/// 已含运费金额
/// </summary>
public string carriageAmt { get; set; }
/// <summary>
/// 商城提示
/// </summary>
public string merHint { get; set; }
/// <summary>
/// 备注字段1
/// </summary>
public string remark1 { get; set; }
/// <summary>
/// 备注字段2
/// </summary>
public string remark2 { get; set; }
/// <summary>
/// 通知商户URL
/// </summary>
public string merURL { get; set; }
/// <summary>
/// 返回商户变量
/// </summary>
public string merVAR { get; set; }
/// <summary>
/// 通知类型
/// </summary>
public string notifyType { get; set; }
/// <summary>
/// 结果发送类型
/// </summary>
public string resultType { get; set; }
/// <summary>
/// 备用字段1
/// </summary>
public string backup1 { get; set; }
/// <summary>
/// 备用字段2
/// </summary>
public string backup2 { get; set; }
/// <summary>
/// 备用字段3
/// </summary>
public string backup3 { get; set; }
/// <summary>
/// 备用字段4
/// </summary>
public string backup4 { get; set; }
}
帮助类
public class XmlHelper
{
/// <summary>
/// 根据模型生成一个xml,其中不包括类名
/// </summary>
/// <param name="Model">模型</param>
/// <param name="flag">属性值为空,xml生成是否返回该属性</param>
/// <returns></returns>
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}</{0}>", PropertiesName, PropertiesValue);
}
}
else
{
Xml.AppendFormat("<{0}>{1}</{0}>", PropertiesName, PropertiesValue);
}
}
return Xml;
} /// <summary>
/// 根据模型生成一个xml,其他不包括类名
/// </summary>
/// <param name="Model">模型</param>
/// <param name="flag">属性值为空,xml生成是否返回该属性</param>
/// <param name="sort">对属性名称排序/可选(升序、降序)</param>
/// <returns></returns>
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<string, object> dic = new Dictionary<string, object>();
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}</{0}>", item.Key, item.Value);
}
}
else
{
Xml.AppendFormat("<{0}>{1}</{0}>", item.Key, item.Value);
}
}
return Xml;
} /// <summary>
/// 根据模型生成一个xml,其他不包括类名
/// </summary>
/// <param name="Model">模型</param>
/// <param name="flag">属性值为空,xml生成是否返回该属性</param>
/// <param name="sort">对属性名称排序/可选(升序、降序)</param>
/// <param name="RootName">父节点名称</param>
/// <returns></returns>
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<string, object> dic = new Dictionary<string, object>();
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}</{0}>", item.Key, item.Value);
}
}
else
{
Xml.AppendFormat("<{0}>{1}</{0}>", item.Key, item.Value);
}
}
Xml.AppendFormat("</{0}>", RootName);
return Xml;
} }
/// <summary>
/// 枚举
/// </summary>
public enum Flag
{
/// <summary>
/// 是
/// </summary>
Y,
/// <summary>
/// 否
/// </summary>
N
}; /// <summary>
/// 排序
/// </summary>
public enum Sort
{
/// <summary>
/// 升序
/// </summary>
Asc,
/// <summary>
/// 降序
/// </summary>
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 = "";//订单金额以分为单位
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 = "";
order.curType = "";
order.merID = merID;
order.merAcct = merAcct;
//客户信息
Custom custom = new Custom();
custom.verifyJoinFlag = "";
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 = "";
message.backup1 = "";
message.backup2 = "";
message.backup3 = "";
message.backup4 = "";
#endregion
#region 组装XML报文内容
//组装xml报文内容
StringBuilder tranDataContent = new StringBuilder();
tranDataContent.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
tranDataContent.Append("<B2CReq>");
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("</B2CReq>");
#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"), "") == )
{
merSignMsg = icbcObj.signC(tranDataContent.ToString(), tranDataContent.Length);//生成签名
}
//BASE64商城证书公钥
merCert = icbcObj.getCert();
#endregion
#region 数据准完成,发送至页面
//参数传至HTML
ViewBag.interfaceName = req.interfaceName;
ViewBag.interfaceVersion = req.interfaceVersion;
ViewBag.clientType = "";
ViewBag.tranData = tranData;
ViewBag.merSignMsg = merSignMsg;
ViewBag.merCert = merCert;
#endregion
发起支付H5
<form action="https://mywap2.icbc.com.cn/ICBCWAPBank/servlet/ICBCWAPEBizServlet" method="post" id="order">
<input name="interfaceName" id="interfaceName" type="hidden" value="@ViewBag.interfaceName">
<input name="interfaceVersion" id="interfaceVersion" type="hidden" value="@ViewBag.interfaceVersion">
<input name="clientType" id="clientType" type="hidden" value="@ViewBag.clientType">
<input name="tranData" id="tranData" type="hidden" value="@ViewBag.tranData">
<input name="merSignMsg" id="merSignMsg" type="hidden" value="@ViewBag.merSignMsg">
<input name="merCert" id="merCert" type="hidden" value="@ViewBag.merCert"> </form>
<script >
document.order.submit(); </script>
发起支付App
<input name="interfaceName" id="interfaceName" type="hidden" value="@ViewBag.interfaceName">
<input name="interfaceVersion" id="interfaceVersion" type="hidden" value="@ViewBag.interfaceVersion">
<input name="clientType" id="clientType" type="hidden" value="@ViewBag.clientType">
<input name="tranData" id="tranData" type="hidden" value="@ViewBag.tranData">
<input name="merSignMsg" id="merSignMsg" type="hidden" value="@ViewBag.merSignMsg">
<input name="merCert" id="merCert" type="hidden" value="@ViewBag.merCert"> <script >
ICBCUtil.submitOrder({
interfaceName:document.getElementById('interfaceName').value,
interfaceVersion:document.getElementById('interfaceVersion').value,
tranData:document.getElementById('tranData').value,
merSignMsg:document.getElementById('merSignMsg').value,
merCert:document.getElementById('merCert').value,
}); </script>
Ps:
1.在使用测试帐号的时候,订单日期必须与测试服务器一致,可以使用工行提供的工具获取服务器当前时间。
2.运行项目时需要启用32应用程序。
3.测试期间一般是使用H5支付,正式商户号申请完成之后,H5嵌入工行APP,使用工行APP支付。
组件下载
http://pan.baidu.com/s/1c2yyjWO
如有转载,请标明出处
http://www.cnblogs.com/cai-niao/p/6231428.html
工行ICBC_WAPB_B2C支付接口的更多相关文章
- 对接第三方支付接口-获取http中的返回参数
这几天对接第三方支付接口,在回调通知里获取返回参数,有一家返回的json格式,请求参数可以从标准输入流中获取. //1.解析参数 , 读取请求内容 BufferedReader br; String ...
- 支付宝WAP支付接口开发(Node/Coffee语言)
此博客不更新很久了, 更新的文档在这, 有兴趣到这里围观: http://neutra.github.io/2013/%E6%94%AF%E4%BB%98%E5%AE%9DWAP%E6%94%AF%E ...
- 【网站国际化必备】Asp.Net MVC 集成Paypal(贝宝)快速结账 支付接口 ,附源码demo
开篇先给大家讲段历史故事,博主是湖北襄阳人.襄阳物华天宝,人杰地灵,曾用名襄樊.在2800多年的历史文化中出现了一代名相诸葛亮(卧龙),三国名士庞统(凤雏),魏晋隐士司马徽(水镜先生),唐代大诗人孟浩 ...
- 【Java EE 学习 21 下】【 使用易宝支付接口实现java网上支付功能】
一.网上支付分为两种情况,一种方法是使用直接和银行的支付接口,另外一种方法是使用第三方支付平台和银行对接完成支付. 1.直接和银行对接. 2.使用第三方支付平台 3.常见的第三方支付平台 二.使用易宝 ...
- 酷友观点/经验:支付接口返回数据接收地址,session数据丢失(或者说失效)的问题浅析(原创文章)
酷友观点/经验:支付接口返回数据接收地址,session数据丢失(或者说失效)的问题浅析(原创文章) 最近手头在开发一个游戏官网,在支付模块采用神州付技术支持,神州付数据表单中要求提供服务器返回地 ...
- php支付宝在线支付接口开发教程【转】
php支付宝在线支付接口开发教程 这篇文章主要为大家详细介绍了php支付宝在线支付接口开发教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 1.什么是第三方支付 所谓第三方支付,就是一些和各 ...
- UnionPay,ChinaPay 最新 银联支付接口C#\Asp.net\MVC 版本
1.概念普及 一.理解什么是UnionPay.ChinaPay 这两个概念如果搞不清楚,绝对够你瞎折腾一段时间的. UnionPay:中国银联,最大的机构:他本身也提供系统接口但都是B2B的,对于单个 ...
- 自己动手搞定支付宝手机网站支付接口 FOR ECShop
支付宝WAP网站版本的支付接口网上整合的比较少,看到很多网站在卖,顿觉无语. 主要是得自己查看支付宝官方提供的SDK中的开发文档. 支付宝sdk下载地址:https://doc.open.alipay ...
- php支付接口,代付、感悟
支付接口: 1.验证用户登录信息 2.验证参数.用加密串来匹配,开信息是否被篡改 3.如果有必要可以仿造购物城 建立购物车列表 4.建立和请求方的关联表 5.进行订单生成.支付流程.各种判断.验证. ...
随机推荐
- LINUX篇,设置MYSQL远程访问实用版
每次设置root和远程访问都容易出现问题, 总结了个通用方法, 关键在于实用 step1: # mysql -u root mysql mysql> Grant all privileges o ...
- 移动端之Android开发的几种方式的初步体验
目前越来越多的移动端混合开发方式,下面列举的大多数我都略微的尝试过,就初步的认识写个简单的心得: 开发方式 开发环境 是否需要AndroidSDK 支持跨平台 开发语言&技能 MUI Win+ ...
- Hyper-V 激活Windows系统重启后黑屏的解决方法 + 激活方法
异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 服务器相关的知识点:http://www.cnblogs.com/dunitia ...
- Python标准模块--ContextManager
1 模块简介 在数年前,Python 2.5 加入了一个非常特殊的关键字,就是with.with语句允许开发者创建上下文管理器.什么是上下文管理器?上下文管理器就是允许你可以自动地开始和结束一些事情. ...
- js获取给定月份的N个月后的日期
1.在讲js获取给定月份的N个月后的日期之前,小颖先给大家讲下getFullYear().getYear()的区别. ①getYear() var d = new Date() console.log ...
- 前端学HTTP之web攻击技术
前面的话 简单的HTTP协议本身并不存在安全性问题,因此协议本身几乎不会成为攻击的对象.应用HTTP协议的服务器和客户端,以及运行在服务器上的Web应用等资源才是攻击目标.本文将详细介绍攻击web站点 ...
- WebAPi之SelfHost自创建证书启动Https疑难解惑及无法正确返回结果
前言 话说又来需求了,之前对于在SelfHost中需要嵌套页面并操作为非正常需求,这回来正常需求了,客户端现在加了https,老大过来说WebAPi访问不了了,这是什么情况,我去试了试,还真是这个情况 ...
- zookeeper源码分析之二客户端启动
ZooKeeper Client Library提供了丰富直观的API供用户程序使用,下面是一些常用的API: create(path, data, flags): 创建一个ZNode, path是其 ...
- 数据图表插件Echarts(一)
一.引言 最近做一个智慧城市项目,项目中需要图表和报表进行数据分析,从网上找了很多,最后找到了百度开放的echarts,一个很强大的插件. 二.介绍 ECharts,缩写来自Enterprise Ch ...
- JS继承之借用构造函数继承和组合继承
根据少一点套路,多一点真诚这个原则,继续学习. 借用构造函数继承 在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数(constructor stealing)的技术( ...