工商銀行在線支付接口


最近做工行的網上支付接口,其中也遇到了不少問題,現在整理一下發布出來希望能對需要的人有所幫助。

參考了下面博客: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>
支付接口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; }
        }
    }
實體類
  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/

這篇文章就寫到這里,希望能對大家有所幫助


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM