• 工商银行在线支付接口


    工商银行在线支付接口

    最近做工行的网上支付接口,其中也遇到了不少问题,现在整理一下发布出来希望能对需要的人有所帮助。

    参考了下面博客: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、下面是代码

     支付接口HTML

    <form method="post" action="<%= icmcModel.OrderPostUrl %>" id="order">
    <div style=" 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>

    支付接口HTML

     支付接口后台代码

    //用户账号(身份证)
    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; }
    }
    }

    实体类

     逻辑操作类

    public static class CBCPayOnline
    {
    private static string amount;

    /// <summary>
    /// 银行证书文件地址
    /// </summary>
    static string strCertFN = HttpContext.Current.Server.MapPath("公钥文件");

    /// <summary>
    /// 商户证书文件地址
    /// </summary>
    static string strCertFNM = HttpContext.Current.Server.MapPath("商户证书");

    /// <summary>
    /// 私钥文件名
    /// </summary>
    static string strKeyFN = HttpContext.Current.Server.MapPath("私钥文件");

    /// <summary>
    /// 私钥口令
    /// </summary>
    static string strKey = "私钥口令";
    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("~/..");
    //商户证书 HttpContext.Current.Server.MapPath("~/..");

    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//支付失败
    {
    SpringFactory.BusinessFactory.GetStudent(l1.userName).OrderFaild(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")
    {
    var result = SpringFactory.BusinessFactory.GetStudent(l1.userName);
    result.OrderFaild(l1.OrderID);

    }
    else//添加失败失败日志
    {
    var result = SpringFactory.BusinessFactory.GetStudent(l1.userName);
    result.AddOrderLogs(l1.Amount.ToString(), false, l1.OrderID, "错误编码:" + mess + pays);
    }
    }
    }
    catch (Exception e)
    {

    var result = SpringFactory.BusinessFactory.GetStudent(l1.userName);
    result.AddOrderLogs("0", false, l1.OrderID, e.ToString());
    }
    }

    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.Length != 24)
    {
    return "订单号不正确,请输入24位订单号";
    }
    ICBC icbcInfo = new ICBC();
    //查询订单列表
    var payModel = SpringFactory.BusinessFactory.GetBusinessAnonymousUser().GetOrderModel(orderID, userIdCardNumber);
    //查询充值日志
    var logModel = SpringFactory.BusinessFactory.GetBusinessAnonymousUser().GetPayLogsByOrderId(orderID, userIdCardNumber);
    if (logModel != null)
    {
    return "已缴费成功,请退出系统重新登录。";
    }
    string outMess = "";
    string zfrq = orderID.Substring(0, 8);
    if (payDate != null)
    {
    zfrq = payDate.Value.ToString("yyyyMMdd");
    }
    else
    {
    if (payModel != null)
    {
    zfrq = payModel.PayDate.ToString("yyyyMMdd");
    }
    }
    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(payModel.userName);
    string stat = myds.Tables["out"].Rows[0]["tranStat"].ToString();
    if (stat == "1" || stat == "0")
    {
    if (payModel != null)
    {
    amount = myds.Tables["out"].Rows[0]["amount"].ToString();
    user.PaymentSucceed(amount, orderID);
    return "支付成功! 订单号" + orderID + " 支付金额:" + amount;
    }
    else
    {
    return "支付成功,但未查询到用户";
    }
    }
    else
    {
    string pays = "";
    if (stat == "2")
    pays = "支付失败";
    else
    pays = "可疑交易";
    if (payModel != null)
    {
    var result = SpringFactory.BusinessFactory.GetStudent(payModel.userName);
    result.OrderFaild(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)
    {
    var result = SpringFactory.BusinessFactory.GetStudent(payModel.userName);
    result.AddOrderLogs(payModel.Amount.ToString(), false, orderID, "错误编码:" + mess + pays);
    }
    }
    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 = true;
    }
    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);
    //var result = SpringFactory.BusinessFactory.GetBusinessAnonymousUser();
    //result.AddLogs("返回3:" + (retruenstring.Length > 400 ? retruenstring.Substring(0, 400) : retruenstring));
    if (retruenstring.Length <= 5)
    {
    return retruenstring;
    }
    return HttpUtility.UrlDecode(retruenstring);
    }
    catch (Exception ex)
    {
    var result = SpringFactory.BusinessFactory.GetBusinessAnonymousUser();
    result.AddLogs("返回1:" + "查询缴费接口失败" + ex.Message);
    errInfo = "查询缴费接口失败";

    return "99";
    }
    }

    /// <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;
    }

    }

    逻辑操作类

     银行回调页面代码

    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("银行数据返回失败,请通知管理员!");
    }

    }

    银行回调页面代码

     现在来说一说可能遇到的问题(我本人遇到了一下错误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/

    这篇文章就写到这里,希望能对大家有所帮助

    从别后, 忆相逢, 几会魂梦与汝同。
     
    分类: ASP.Net
    标签: 工行接口
  • 相关阅读:
    【t090】吉祥数
    【u221】分数
    【u212】&&【t036】最大和
    【u125】最大子树和
    【u124】环状最大两段子段和
    【u123】最大子段和
    【u122】迎接仪式
    【u121】教主的花园
    【u118】日志分析
    【u117】队列安排
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3335791.html
Copyright © 2020-2023  润新知