工商银行在线支付接口
最近做工行的网上支付接口,其中也遇到了不少问题,现在整理一下发布出来希望能对需要的人有所帮助。
参考了下面博客:http://www.cnblogs.com/gonganruyi/archive/2011/07/01/2095463.html
1、首先需要注册工行提供的ICBCEBankUtil.dll,将ICBCEBankUtil.dll和infosecapi.dll复制到system32文件夹下CMD输入regsvr32 ICBCEBankUtil.dll注册控件。WINDOWS SERVER2008/2012等系统需要运行管理员命令提示符。
2、拆分银行提供的.pfx证书文件,生成.key 和.crt两个文件,记住拆分时设置的私钥密码。将ebb2cpublic.crt(公钥文件)、Name.key、Name.crt三个文件复制到指定目录。
3、下面是代码
<form method="post" action="<%= icmcModel.OrderPostUrl %>" id="order"> <div style="width: 500px; margin: auto auto; padding: 10px; line-height: 30px;"> 正在跳转至工商银行支付地址..... </div> <input type="hidden" name="interfaceName" value="<%= icmcModel.InterfaceName %>" /> <input type="hidden" name="interfaceVersion" value="<%= icmcModel.InterfaceVersion %>" /> <input type="hidden" name="tranData" value="<%= icmcModel.TranData %>" /> <input type="hidden" name="merSignMsg" value="<%= icmcModel.MerSignMsg %>" /> <input type="hidden" name="merCert" value="<%= icmcModel.MerCert %>" /> <script type="text/javascript"> document.getElementById("order").submit();</script> </form>
//用户账号(身份证) this.userIdCardNumber = Request.QueryString["userIdCardNumber"]; //充值金额,(工商银行按分进行计算) // this.money = (Convert.ToInt32(Request.QueryString["payMnoney"]) * 100).ToString(); this.money = "1"; //生成订单号 string orderId = DateTime.Now.ToString("yyyyMMddHHmmss") + userIdCardNumber.Substring(userIdCardNumber.Length - 5, 5) + Inhua.Common.Rand.Number(5); StringBuilder strXml = new StringBuilder(); strXml.Append("<?xml version=\"1.0\" encoding=\"GBK\" standalone=\"no\"?>"); strXml.Append("<B2CReq>"); //接口名称 strXml.Append("<interfaceName>" + icmcModel.InterfaceName + "</interfaceName>"); //接口版本号 strXml.Append("<interfaceVersion>" + icmcModel.InterfaceVersion + "</interfaceVersion>"); //订单信息 strXml.Append("<orderInfo>"); //交易日期时间 strXml.Append("<orderDate>" + icmcModel.OrderDate + "</orderDate>"); //支付币种 strXml.Append("<curType>" + icmcModel.CurType + "</curType>"); //商户代码 strXml.Append("<merID>" + icmcModel.MerID + "</merID>"); //订单信息列表 strXml.Append("<subOrderInfoList>"); //订单信息 strXml.Append("<subOrderInfo>"); //订单编号 strXml.Append("<orderid>" + orderId + "</orderid>"); //订单金额 //strXml.Append("<amount>" + user.ExaminationModel.Examination_fees.ToString("0.00") + "</amount> "); strXml.Append("<amount>" + money + "</amount> "); //分期付款期数 1代表全额付款 strXml.Append("<installmentTimes>1</installmentTimes>"); //商户账号 strXml.Append("<merAcct>" + icmcModel.MerAcct + "</merAcct>"); //商品编号 strXml.Append("<goodsID>" + icmcModel.Orderid + "</goodsID>"); //商品名称 strXml.Append("<goodsName>商品名称</goodsName>"); //商品数量 strXml.Append("<goodsNum>1</goodsNum>"); //已含运费金额 strXml.Append("<carriageAmt></carriageAmt>"); strXml.Append("</subOrderInfo>"); strXml.Append("</subOrderInfoList>"); strXml.Append("</orderInfo>"); strXml.Append("<custom>"); //检验联名标志 取值“1”:客户支付时,网银判断该客户是否与商户联名 strXml.Append("<verifyJoinFlag>" + icmcModel.VerifyJoinFlag + "</verifyJoinFlag>"); //语言版本 取值:“EN_US”为英文版;取值:“ZH_CN”或其他为中文版 strXml.Append("<Language>ZH_CN</Language>"); strXml.Append("</custom>"); strXml.Append("<message>"); //支持订单支付的银行卡种类 strXml.Append("<creditType>2</creditType>"); //通知类型 strXml.Append("<notifyType>" + icmcModel.NotifyType + "</notifyType>"); //结果发送类型 strXml.Append("<resultType>" + icmcModel.ResultType + "</resultType>"); //商户reference strXml.Append("<merReference>" + icmcModel.MerReference + "</merReference>"); //客户端IP 当商户reference项送空时,该项必输 strXml.Append("<merCustomIp>" + icmcModel.MerIP + "</merCustomIp>"); //虚拟商品/实物商品标志位 取值“0”:虚拟商品 取值“1”,实物商品 strXml.Append("<goodsType>0</goodsType>"); //买家用户号 strXml.Append("<merCustomID></merCustomID>"); //买家联系电话 strXml.Append("<merCustomPhone></merCustomPhone>"); //收货地址 strXml.Append("<goodsAddress></goodsAddress>"); //订单备注 strXml.Append("<merOrderRemark></merOrderRemark>"); //商城提示 strXml.Append("<merHint></merHint>"); //备注字段1 strXml.Append("<remark1></remark1>"); //备注字段2 strXml.Append("<remark2></remark2>"); //返回商户URL //strXml.Append("<merURL>http://localhost/</merURL>"); //string url = tools.GetRootVirtualPath();System.Configuration.ConfigurationManager.AppiiciSettings["aa"] string merURL = "http://" + icmcModel.MerIP + "/PayOnline/ReturnPayment.aspx"; strXml.Append("<merURL>" + merURL + "</merURL>"); //返回商户变量 strXml.Append("<merVAR>" + Inhua.Common.Encryption.Encrypt(userIdCardNumber) + "</merVAR>"); strXml.Append("</message>"); strXml.Append("</B2CReq>"); //获取工商银行验证 icmcModel.TranData = strXml.ToString(); CBCOnlinePayment.CBCPayOnline.GetCheckInfo(icmcModel);
public class ICBC { private string _orderPostUrl = "https://B2C.icbc.com.cn/servlet/ICBCINBSEBusinessServlet"; private string _interfaceName = "ICBC_PERBANK_B2C"; private string _interfaceVersion = "1.0.0.11"; private string _orderid; /// <summary> /// 订单金额 /// </summary> private string _amount; /// <summary> /// 支付币种 /// </summary> private string _curType = "001"; /// <summary> /// 商户代码 /// </summary> private string _merID = "向银行申请"; /// <summary> /// 商户账号 /// </summary> private string _merAcct = "交易账号"; /// <summary> /// 检验联名标志 /// 取值“1”:客户支付时,网银判断该客户是否与商户联名,是则按上送金额扣帐,否则展现未联名错误;取值“0”:不检验客户是否与商户联名,按上送金额扣帐。 /// </summary> private string _verifyJoinFlag = "0"; /// <summary> /// 通知类型 /// 在交易转账处理完成后把交易结果通知商户的处理模式。 /// 取值“HS”:在交易完成后实时将通知信息以HTTP协议POST方式,主动发送给商户,发送地址为商户端随订单数据提交的接收工行支付结果的URL即表单中的merURL字段; /// 取值“AG”:在交易完成后不通知商户。商户需使用浏览器登录工行的B2C商户服务网站,或者使用工行提供的客户端程序API主动获取通知信息。 /// </summary> private string _notifyType = "HS"; /// <summary> /// 返回商户URL /// 必须合法的URL,交易结束,将客户引导到商户的此url,即通过客户浏览器post交易结果信息到商户的此URL /// 注意:该URL应使用http协议(不能使用https协议),端口号应为80或不指定。 /// </summary> private string _merURL; /// <summary> /// 结果发送类型 /// 选输 /// 取值“0”:无论支付成功或者失败,银行都向商户发送交易通知信息; /// 取值“1”,银行只向商户发送交易成功的通知信息。 /// 只有通知方式为HS时此值有效,如果使用AG方式,可不上送此项,但签名数据中必须包含此项,取值可为空。 /// </summary> private string _resultType = "1"; /// <summary> /// 支付日期 /// </summary> private string _orderDate = System.DateTime.Now.ToString("yyyyMMddHHmmss"); /// <summary> /// 订单签名数据 /// 必输, ///商户使用工行提供的签名API和商户证书将tranData的xml明文串进行签名,得到二进制签名数据,然后进行BASE64编码后得到可视的merSignMsg; ///注意:签名时是针对tranData的xml明文,不是将tranData进行BASE64编码后的串; /// </summary> private string _merSignMsg; /// <summary> /// 商城证书公钥 /// 商户用二进制方式读取证书公钥文件后,进行BASE64编码后产生的字符串; /// </summary> private string _merCert; /// <summary> /// 商品编号 /// </summary> private string _goodsID = "001"; /// <summary> /// 商品名称 /// </summary> private string _goodsName = ""; /// <summary> /// 商品数量 /// </summary> private string _goodsNum = "1"; /// <summary> /// 已含运费金额 /// </summary> private string _carriageAmt; /// <summary> /// 备注字段1 /// </summary> private string _remark1; /// <summary> /// 备注字段2 /// </summary> private string _remark2; /// <summary> /// 商城提示 /// </summary> private string _merHint; /// <summary> /// 整合所有交易数据形成的xml明文串,并做BASE64编码; /// 具体格式定义见下文; /// 注意: /// 需有xml头属性;整个字段使用BASE64编码; /// xml明文中没有回车换行和多余空格; /// </summary> private string _tranData; /// <summary> /// 上送商户网站域名(支持通配符,例如“*.某B2C商城.com”),如果上送,工行会在客户支付订单时,校验商户上送域名与客户跳转工行支付页面之前网站域名的一致性。 /// </summary> private string _merReference = System.Configuration.ConfigurationManager.AppSettings["WebUrl"]; private string _merIP = System.Configuration.ConfigurationManager.AppSettings["WebIP"]; private bool _isCheck = false; /// <summary> /// 是否检测成功 /// </summary> public bool IsCheck { get { return _isCheck; } set { _isCheck = value; } } /// <summary> /// 服务域名 /// </summary> public string MerReference { get { return _merReference; } set { _merReference = value; } } /// <summary> /// 服务IP /// </summary> public string MerIP { get { return _merIP; } set { _merIP = value; } } /// <summary> /// 报文数据 /// </summary> public string TranData { get { return _tranData; } set { _tranData = value; } } /// <summary> /// 工商支付接口路径 /// </summary> public string OrderPostUrl { get { return _orderPostUrl; } set { _orderPostUrl = value; } } /// <summary> /// 接口名称 /// </summary> public string InterfaceName { get { return _interfaceName; } set { _interfaceName = value; } } /// <summary> /// 接口版本号 /// </summary> public string InterfaceVersion { get { return _interfaceVersion; } set { _interfaceVersion = value; } } /// <summary> /// 订单号 /// </summary> public string Orderid { get { return _orderid; } set { _orderid = value; } } /// <summary> /// 订单金额 /// </summary> public string Amount { get { return _amount; } set { _amount = value; } } /// <summary> /// 支付币种 RMB:001 /// </summary> public string CurType { get { return _curType; } set { _curType = value; } } /// <summary> /// 商户代码 /// </summary> public string MerID { get { return _merID; } set { _merID = value; } } /// <summary> /// 商户账号 /// </summary> public string MerAcct { get { return _merAcct; } set { _merAcct = value; } } /// <summary> /// 检验联名标志 /// 取值“1”:客户支付时,网银判断该客户是否与商户联名,是则按上送金额扣帐,否则展现未联名错误; /// 取值“0”:不检验客户是否与商户联名,按上送金额扣帐。 /// </summary> public string VerifyJoinFlag { get { return _verifyJoinFlag; } set { _verifyJoinFlag = value; } } /// <summary> /// 通知类型 /// 取值“HS”:在交易完成后实时将通知信息以HTTP协议POST方式,主动发送给商户,发送地址为商户端随订单数据提交的接收工行支付结果的URL即表单中的merURL字段; /// 取值“AG”:在交易完成后不通知商户。商户需使用浏览器登录工行的B2C商户服务网站,或者使用工行提供的客户端程序API主动获取通知信息。 /// </summary> public string NotifyType { get { return _notifyType; } set { _notifyType = value; } } /// <summary> /// 返回商户URL /// </summary> public string MerURL { get { return _merURL; } set { _merURL = value; } } /// <summary> /// 结果发送类型 /// </summary> public string ResultType { get { return _resultType; } set { _resultType = value; } } /// <summary> /// 交易日期时间 /// </summary> public string OrderDate { get { return _orderDate; } set { _orderDate = value; } } /// <summary> /// 订单签名数据 /// </summary> public string MerSignMsg { get { return _merSignMsg; } set { _merSignMsg = value; } } /// <summary> /// 商城证书公钥 /// </summary> public string MerCert { get { return _merCert; } set { _merCert = value; } } /// <summary> /// 商品编号 /// </summary> public string GoodsID { get { return _goodsID; } set { _goodsID = value; } } /// <summary> /// 商品名称 /// </summary> public string GoodsName { get { return _goodsName; } set { _goodsName = value; } } /// <summary> /// 商品数量 /// </summary> public string GoodsNum { get { return _goodsNum; } set { _goodsNum = value; } } /// <summary> /// 已含运费金额 /// </summary> public string CarriageAmt { get { return _carriageAmt; } set { _carriageAmt = value; } } /// <summary> /// 备注字段1 /// </summary> public string Remark1 { get { return _remark1; } set { _remark1 = value; } } /// <summary> /// 备注字段2 /// </summary> public string Remark2 { get { return _remark2; } set { _remark2 = value; } } /// <summary> /// 商城提示 /// </summary> public string MerHint { get { return _merHint; } set { _merHint = value; } } }
if (Request.Form["notifyData"] != null) { try { ICBC icbcInfo = new ICBC(); icbcInfo.TranData = Request.Form["notifyData"]; icbcInfo.MerSignMsg = Request.Form["signMsg"].ToString(); icbcInfo = CBCOnlinePayment.CBCPayOnline.GetCheckReturnInfo(icbcInfo); //自定义返回的变量 this.userIdCardNumber = Inhua.Common.Encryption.Decrypt(Request.Form["merVAR"].ToString()); var query = SpringFactory.BusinessFactory.GetStudent(userIdCardNumber); if (icbcInfo.IsCheck) { DataSet myds = new DataSet(); StringReader strReader = new StringReader(icbcInfo.TranData); myds.ReadXml(strReader); DataTable mytable = new DataTable(); mytable = myds.Tables["bank"]; string payDate = myds.Tables["orderInfo"].Rows[0]["orderDate"].ToString().Trim(); string amount = myds.Tables["subOrderInfo"].Rows[0]["amount"].ToString().Trim(); string orderid = myds.Tables["subOrderInfo"].Rows[0]["orderid"].ToString().Trim(); if (null != mytable && mytable.Rows.Count > 0) { if (mytable.Rows[0]["tranStat"].ToString().Trim() == "1") { //这里做成功操作 string s2 = payDate.Substring(0, 4) + "-" + payDate.Substring(4, 2) + "-" + payDate.Substring(6, 2) + " " + payDate.Substring(8, 2) + ":" + payDate.Substring(10, 2); DateTime time1 = DateTime.Parse(s2); query.PaymentSucceed(amount, orderid);//支付成功,修改余额 } else { SpringFactory.BusinessFactory.GetStudent(this.userIdCardNumber).AddOrderLogs("0", false, "", "未知错误"); } } } } catch (Exception ex) { SpringFactory.BusinessFactory.GetStudent(this.userIdCardNumber).AddOrderLogs("0", false, "", ex.Message); } } else { var result = SpringFactory.BusinessFactory.GetBusinessAnonymousUser(); result.AddLogs("银行数据返回失败,请通知管理员!"); } }
public static class CBCPayOnline { private static string amount; /// <summary> /// 银行证书文件地址 /// </summary> static string strCertFN = HttpContext.Current.Server.MapPath("~/ICBCcert/ebb2cpublic.crt"); /// <summary> /// 商户证书文件地址 /// </summary> static string strCertFNM = HttpContext.Current.Server.MapPath("~/ICBCcert/zzjy001.crt"); /// <summary> /// 私钥文件名 /// </summary> static string strKeyFN = HttpContext.Current.Server.MapPath("~/ICBCcert/zzjy001.key"); /// <summary> /// 私钥口令 /// </summary> static string strKey = "12345678"; static string api_url = "https://corporbank.icbc.com.cn/servlet/ICBCINBSEBusinessServlet"; static string post_params = "APIName=EAPI&APIVersion=001.001.002.001&MerReqData="; static string cert_path = HttpContext.Current.Server.MapPath("~/ICBCcert/zzjy001.pfx"); //商户证书 HttpContext.Current.Server.MapPath("~/ICBCcert/rcsc1.crt"); public static void Load() { System.Threading.Thread t = new System.Threading.Thread(CheckOrder); t.Start(); } static CBCPayOnline() { } /// <summary> /// 检查未提交订单 /// </summary> public static void CheckOrder() { var query = SpringFactory.BusinessFactory.GetBusinessAnonymousUser(); while (true) { var list = query.GetOrderPayList(); ICBC icbcInfo = new ICBC(); string outMess = ""; foreach (var l1 in list) { try { var user = SpringFactory.BusinessFactory.GetStudent(l1.userName); string mess = CheckOrder(l1.OrderID, l1.PayDate.ToString("yyyyMMdd"), icbcInfo.MerID, icbcInfo.MerAcct, out outMess); if (mess.Length > 5)//未返回错误编码,返回xml数据 { DataSet myds = new DataSet(); StringReader strReader = new StringReader(mess); myds.ReadXml(strReader); string stat = myds.Tables["out"].Rows[0]["tranStat"].ToString(); if (stat == "1" || stat == "0") { amount = myds.Tables["out"].Rows[0]["amount"].ToString(); user.PaymentSucceed(amount, l1.OrderID); } } else { string pays = ""; switch (mess) { case "40972": pays = "API查询的订单不存在"; break; case "40973": pays = "API查询过程中系统异常"; break; case "40976": pays = "API查询系统异常"; break; case "40977": pays = "商户证书信息错"; break; case "40978": pays = "解包商户请求数据报错"; break; case "40979": pays = "查询的订单不存在"; break; case "40980": pays = "API查询过程中系统异常"; break; case "40981": pays = "给商户打包返回数据错"; break; case "40982": pays = "系统错误"; break; case "40983": pays = "查询的订单不唯一"; break; case "40987": pays = "商户代码或者商城账号有误"; break; case "40947": pays = "给商户打包返回数据错"; break; case "40948": pays = "商城状态非法"; break; case "40949": pays = "商城类别非法"; break; case "40950": pays = "商城应用类别非法"; break; case "40951": pays = "商户证书id状态非法"; break; case "40952": pays = "商户证书id未绑定"; break; case "40953": pays = "商户id权限非法"; break; case "40954": pays = "检查商户状态时数据库异常"; break; } //清除不存在的订单 if (mess == "40972") { if (DateTime.Now.AddMonths(-6) > l1.PayDate) { var result = SpringFactory.BusinessFactory.GetStudent(l1.userName); result.OrderFaild(l1.OrderID); } } else//添加错误日志 { SpringFactory.BusinessFactory.GetBusinessAnonymousUser().AddLogs("错误编码:" + mess + "," + pays, l1.OrderID); } } } catch (Exception e) { SpringFactory.BusinessFactory.GetBusinessAnonymousUser().AddLogs(e.Message, l1.OrderID); throw e; } } System.Threading.Thread.Sleep(1000 * 60 * 30); } } /// <summary> /// 根据订单号查询订单 /// </summary> /// <param name="orderID"></param> /// <returns></returns> public static string ChenkOrder(string orderID, DateTime? payDate, string userIdCardNumber) { if (orderID.Trim().Length != 24) { return "订单号不正确,请输入24位订单号"; } ICBC icbcInfo = new ICBC(); //查询充值日志 var logModel = SpringFactory.BusinessFactory.GetBusinessAnonymousUser().GetPayLogsByOrderId(orderID, userIdCardNumber); if (logModel != null) { return "已经缴费成功。"; } string outMess = ""; string zfrq = orderID.Substring(0, 8);//支付日期 if (payDate != null && payDate != DateTime.MinValue) { zfrq = payDate.Value.ToString("yyyyMMdd"); } var payModel = SpringFactory.BusinessFactory.GetBusinessAnonymousUser().GetOrderModel(orderID, userIdCardNumber); string mess = CheckOrder(orderID, zfrq, icbcInfo.MerID, icbcInfo.MerAcct, out outMess); if (mess.Length > 5)//未返回错误编码,返回xml数据 { DataSet myds = new DataSet(); StringReader strReader = new StringReader(mess); try { myds.ReadXml(strReader); } catch { throw new Exception("错误数据:" + mess); } //查询订单列表 var user = SpringFactory.BusinessFactory.GetStudent(userIdCardNumber); string stat = myds.Tables["out"].Rows[0]["tranStat"].ToString(); amount = myds.Tables["out"].Rows[0]["amount"].ToString(); if (stat == "1" || stat == "0") { if (payModel != null) { user.PaymentSucceed(amount, orderID); return "已经支付成功!\r\n订单号" + orderID + "\r\n支付金额:" + amount; } else { string payTimes = myds.Tables["in"].Rows[0]["tranDate"].ToString(); user.UpdatePaymentInformation(amount, orderID, userIdCardNumber); return "已经支付成功!"; } } else { string pays = ""; if (stat == "2") pays = "支付失败"; else pays = "可疑交易"; //添加错误日志 SpringFactory.BusinessFactory.GetBusinessAnonymousUser().AddLogs("支付失败或可疑交易," + stat, orderID); return pays; } } else { string pays = ""; switch (mess) { case "40972": pays = "API查询的订单不存在"; break; case "40973": pays = "API查询过程中系统异常"; break; case "40976": pays = "API查询系统异常"; break; case "40977": pays = "商户证书信息错"; break; case "40978": pays = "解包商户请求数据报错"; break; case "40979": pays = "查询的订单不存在"; break; case "40980": pays = "API查询过程中系统异常"; break; case "40981": pays = "给商户打包返回数据错"; break; case "40982": pays = "系统错误"; break; case "40983": pays = "查询的订单不唯一"; break; case "40987": pays = "商户代码或者商城账号有误"; break; case "40947": pays = "给商户打包返回数据错"; break; case "40948": pays = "商城状态非法"; break; case "40949": pays = "商城类别非法"; break; case "40950": pays = "商城应用类别非法"; break; case "40951": pays = "商户证书id状态非法"; break; case "40952": pays = "商户证书id未绑定"; break; case "40953": pays = "商户id权限非法"; break; case "40954": pays = "检查商户状态时数据库异常"; break; } //清除不存在的订单 if (mess == "40972") { if (payModel != null) { var result = SpringFactory.BusinessFactory.GetStudent(payModel.userName); result.OrderFaild(orderID); } } else//添加失败失败日志 { if (payModel != null) { SpringFactory.BusinessFactory.GetBusinessAnonymousUser().AddLogs("错误编码:" + mess + pays, orderID); } } return pays; } } /// <summary> /// 获取工商银行验证信息 /// </summary> /// <param name="argIcbc"></param> /// <returns></returns> public static DataTransfer.ICBC GetCheckInfo(DataTransfer.ICBC argIcbc) { string strMerSignMsg = string.Empty; B2CUtil icbcObj = new B2CUtil(); int jg = icbcObj.init(strCertFN, strCertFNM, strKeyFN, strKey); if (jg == 0) { argIcbc.MerSignMsg = icbcObj.signC(argIcbc.TranData, argIcbc.TranData.Length); if (argIcbc.MerSignMsg == "") { int returnCode = icbcObj.getRC(); SpringFactory.BusinessFactory.GetBusinessAnonymousUser().AddLogs("错误编码:" + returnCode + ",签名错误", ""); } argIcbc.MerCert = icbcObj.getCert(1); byte[] bytes = Encoding.Default.GetBytes(argIcbc.TranData); argIcbc.TranData = Convert.ToBase64String(bytes); } else { SpringFactory.BusinessFactory.GetBusinessAnonymousUser().AddLogs(jg.ToString() + ",证书错误或私钥错误编码", ""); } return argIcbc; } /// <summary> /// 获取工商银行验证信息 /// </summary> /// <param name="argIcbc"></param> /// <returns></returns> public static DataTransfer.ICBC GetCheckReturnInfo(DataTransfer.ICBC argIcbc) { string strMerSignMsg = string.Empty; B2CUtil icbcObj = new B2CUtil(); if (icbcObj.init(strCertFN, strCertFNM, strKeyFN, strKey) == 0) { argIcbc.TranData = Decode(argIcbc.TranData); //判断验证银行签名是否成功 if (icbcObj.verifySignC(argIcbc.TranData, argIcbc.TranData.Length, argIcbc.MerSignMsg, argIcbc.MerSignMsg.Length) == 0) { argIcbc.IsCheck = true; } else argIcbc.IsCheck = false;//todo:签名失败 } else { argIcbc.IsCheck = false; } return argIcbc; } /// <summary> /// 加密信息 /// </summary> /// <param name="data"></param> /// <returns></returns> public static string Encode(string data) { try { return Inhua.Common.Encryption.Encrypt(data); } catch (Exception e) { throw new Exception(e.Message); } } /// <summary> /// 解密信息 /// </summary> /// <param name="str"></param> /// <returns></returns> public static string Decode(string str) { byte[] outputb = Convert.FromBase64String(str); string orgStr = Encoding.Default.GetString(outputb); return orgStr; } /// <summary> /// 查询订单 /// </summary> /// <param name="strOrderNum">订单号</param> /// <param name="strTranDate">交易日期</param> /// <param name="strShopCode">商家代码</param> /// <param name="strShopAccount">商城账号</param> /// <param name="errInfo"></param> /// <returns></returns> public static string CheckOrder(string strOrderNum, string strTranDate, string strShopCode, string strShopAccount, out string errInfo) { try { errInfo = string.Empty; StringBuilder sb = new StringBuilder(); sb.Append("<?xml version=\"1.0\" encoding=\"GBK\" standalone=\"no\" ?><ICBCAPI><in><orderNum>"); sb.Append(strOrderNum); sb.Append("</orderNum><tranDate>"); sb.Append(strTranDate); sb.Append("</tranDate><ShopCode>"); sb.Append(strShopCode); sb.Append("</ShopCode><ShopAccount>"); sb.Append(strShopAccount); sb.Append("</ShopAccount></in></ICBCAPI>"); string post_data = post_params + sb.ToString(); string retruenstring = PostDataBySSL(post_data, api_url, cert_path, strKey, out errInfo); if (retruenstring.Length <= 5) { return retruenstring; } return HttpUtility.UrlDecode(retruenstring); } catch (Exception ex) { var result = SpringFactory.BusinessFactory.GetBusinessAnonymousUser(); result.AddLogs(ex.Message, ""); errInfo = ex.Message; return ex.Message; } } /// <summary> /// 发送SSL加密请求 /// </summary> /// <param name="post_data"></param> /// <param name="url"></param> /// <param name="cert_path"></param> /// <param name="cert_password"></param> /// <param name="errInfo"></param> /// <returns></returns> public static string PostDataBySSL(string post_data, string url, string cert_path, string cert_password, out string errInfo) { errInfo = string.Empty; try { ASCIIEncoding encoding = new ASCIIEncoding(); byte[] data = encoding.GetBytes(post_data); if (cert_path != string.Empty) ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate); WebRequest webRequest = WebRequest.Create(url); HttpWebRequest httpRequest = webRequest as HttpWebRequest; if (cert_path.ToLower().EndsWith(".cer")) { httpRequest.ClientCertificates.Add(X509Certificate.CreateFromCertFile(cert_path)); } else { //SpringFactory.BusinessFactory.GetBusinessAnonymousUser().AddLogs(cert_path); httpRequest.ClientCertificates.Add(new X509Certificate2(cert_path, cert_password, X509KeyStorageFlags.MachineKeySet)); } httpRequest.KeepAlive = true; httpRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"; httpRequest.ContentType = "application/x-www-form-urlencoded"; httpRequest.Method = "POST"; httpRequest.ContentLength = data.Length; Stream requestStream = httpRequest.GetRequestStream(); requestStream.Write(data, 0, data.Length); requestStream.Close(); Stream responseStream = null; responseStream = httpRequest.GetResponse().GetResponseStream(); string stringResponse = string.Empty; if (responseStream != null) { using (StreamReader responseReader = new StreamReader(responseStream, Encoding.GetEncoding("GBK"))) { stringResponse = responseReader.ReadToEnd(); } responseStream.Close(); } return stringResponse; } catch (Exception e) { errInfo = e.Message; SpringFactory.BusinessFactory.GetBusinessAnonymousUser().AddLogs(e.Message, ""); return string.Empty; } } public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } }
现在来说一说可能遇到的问题(我本人遇到了以下错误,windows server2012的服务器):
1、发布到服务器后,跳转到支付页面时报下图所示错误:
提问的时候有人说是ICBCEBankUtil.dll没有注册的原因,但事实上我注册过多次,每次都提示注册成功。搜索一番之后终于解决了这个问题,打开IIS 选择,应用程序池-选择你的程序所使用的应用程序池-右键-高级设置-启用32位应用程序项设置为True(默认False)。
如下图所示:
2、做工行查询接口的时候在本地没有问题,发布到服务器上之后一直报错系统找不到指定的文件,而服务器上证书文件是存在的。具体代码如下:
我排查过在执行 httpRequest.ClientCertificates.Add(new X509Certificate2(cert_path, cert_password));这一句代码的时候抛异常了,“系统找不到指定的文件“,但是证书文件我已经上产到服务器上了。折腾了N长时间后终于解决了,把原来的X509Certificate2 cert = new X509Certificate2(cert_path, "12345678");加了一个参数改为:X509Certificate2 cert= new X509Certificate2(cert_path, cert_password, X509KeyStorageFlags.MachineKeySet) 。具体过程参考我的博问http://q.cnblogs.com/q/54288/
这篇文章就写到这里,希望能对大家有所帮助