工行ICBC_WAPB_B2C支付介面

来源:http://www.cnblogs.com/cai-niao/archive/2016/12/29/6231428.html
-Advertisement-
Play Games

一、 前期準備 Ps:工行運營提供開發文檔時,沒有直接提供支付組件ICBCEBankUtil.dll和infosecapi.dll,工行運營說有這個組件在文檔中,但是沒有找到,工行沒有技術提供支持,後來在網上自己找的。 二、 環境搭配 Ps:本人使用的是64位系統,支付組件是放在System64文件 ...


一、 前期準備

  1. 手機銀行(WAP)B2C線上支付介面說明V1.0.0.6.doc
  2. 手機銀行移動生活商戶及門戶網站js介面API.doc
  3. 支付組件ICBCEBankUtil.dll和infosecapi.dll
  4. 工行聯測環境時間查看工具ICBCTime_V20141011.exe
  5. 測試公鑰、商戶公鑰和私鑰
  6. 個人銀行測試帳號

 

Ps:工行運營提供開發文檔時,沒有直接提供支付組件ICBCEBankUtil.dll和infosecapi.dll,工行運營說有這個組件在文檔中,但是沒有找到,工行沒有技術提供支持,後來在網上自己找的。

二、 環境搭配

  1. 複製支付組件ICBCEBankUtil.dll和infosecapi.dll到C盤中System32或System64文件夾下,在DOS視窗下切換目錄System32或System64文件夾下 中運行regsvr32 ICBCEBankUtil.dll註冊組件,併在項目中引用組件。
  2. IIS下解析項目,在程式池中修改啟用32應用程式

 

Ps:本人使用的是64位系統,支付組件是放在System64文件夾下的,如果系統是32位,支付組件要放在System32文件夾下。使用DOS命令請使用管理員許可權運行,否則註冊失敗。

三、編碼

定義訂單實體類:

  1    //基本信息
  2     public class B2CReq
  3     {
  4         /// <summary>
  5         /// 介面名稱
  6         /// </summary>
  7         public string interfaceName { get; set; }
  8         /// <summary>
  9         /// 介面版本號
 10         /// </summary>
 11         public string interfaceVersion { get; set; }
 12      
 13     }
 14 
 15     /// <summary>
 16     /// 訂單信息
 17     /// </summary>
 18     public class OrderInfo
 19     {
 20         /// <summary>
 21         /// 交易日期時間
 22         /// </summary>
 23         public string orderDate { get; set; }
 24         /// <summary>
 25         /// 訂單號
 26         /// </summary>
 27         public string orderid { get; set; }
 28         /// <summary>
 29         /// 訂單金額
 30         /// </summary>
 31         public string amount { get; set; }
 32         /// <summary>
 33         /// 分期付款期數
 34         /// </summary>
 35         public string installmentTimes { get; set; }
 36         /// <summary>
 37         /// 支付幣種
 38         /// </summary>
 39         public string curType { get; set; }
 40         /// <summary>
 41         /// 商戶代碼
 42         /// </summary>
 43         public string merID { get; set; }
 44         /// <summary>
 45         /// 商戶賬號
 46         /// </summary>
 47         public string merAcct { get; set; }
 48     }
 49     /// <summary>
 50     /// 客戶信息
 51     /// </summary>
 52     public class Custom
 53     {
 54         /// <summary>
 55         /// 聯名校驗標誌  
 56         /// </summary>
 57         public string verifyJoinFlag { get; set; }
 58         /// <summary>
 59         /// 語言版本
 60         /// </summary>
 61         public string Language { get; set; }
 62     }
 63 
 64     /// <summary>
 65     /// 信息
 66     /// </summary>
 67     public class Message
 68     {
 69         /// <summary>
 70         /// 商品編號
 71         /// </summary>
 72         public string goodsID { get; set; }
 73         /// <summary>
 74         /// 商品名稱
 75         /// </summary>
 76         public string goodsName { get; set; }
 77         /// <summary>
 78         /// 商品數量
 79         /// </summary>
 80         public string goodsNum { get; set; }
 81         /// <summary>
 82         /// 已含運費金額
 83         /// </summary>
 84         public string carriageAmt { get; set; }
 85         /// <summary>
 86         /// 商城提示
 87         /// </summary>
 88         public string merHint { get; set; }
 89         /// <summary>
 90         /// 備註欄位1
 91         /// </summary>
 92         public string remark1 { get; set; }
 93         /// <summary>
 94         /// 備註欄位2
 95         /// </summary>
 96         public string remark2 { get; set; }
 97         /// <summary>
 98         /// 通知商戶URL
 99         /// </summary>
100         public string merURL { get; set; }
101         /// <summary>
102         /// 返回商戶變數
103         /// </summary>
104         public string merVAR { get; set; }
105         /// <summary>
106         /// 通知類型
107         /// </summary>
108         public string notifyType { get; set; }
109         /// <summary>
110         /// 結果發送類型
111         /// </summary>
112         public string resultType { get; set; }
113         /// <summary>
114         /// 備用欄位1
115         /// </summary>
116         public string backup1 { get; set; }
117         /// <summary>
118         /// 備用欄位2
119         /// </summary>
120         public string backup2 { get; set; }
121         /// <summary>
122         /// 備用欄位3
123         /// </summary>
124         public string backup3 { get; set; }
125         /// <summary>
126         /// 備用欄位4
127         /// </summary>
128         public string backup4 { get; set; }
129     }
View Code

幫助類

 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;
        }
    }
View Code

 組裝支付報文信息

#region 訂單信息

            //在此自定義加密驗證
            string merVAR = "";//訂單加密數據
            string Url = "http://localhost:8076/Pay/Notify";//支付成功通知地址
            string No = DateTime.Now.ToString("TestyyyyMMddHHmmssfff");//訂單號
            string PayPrice = "100";//訂單金額以分為單位
            string ProName = "充值卡";//產品名稱
            string merID = "";//商戶號
            string merAcct = "";//開戶帳號



            ///基本信息
            B2CReq req = new B2CReq();
            req.interfaceName = "ICBC_WAPB_B2C";
            req.interfaceVersion = "1.0.0.6";

            //訂單信息
            OrderInfo order = new OrderInfo();
            order.orderDate = Convert.ToDateTime("2016/12/31 0:47:55").ToString("yyyyMMddHHmmss");
            order.orderid = No;
            order.amount = PayPrice;
            order.installmentTimes = "1";
            order.curType = "001";
            order.merID = merID;
            order.merAcct = merAcct;

            //客戶信息
            Custom custom = new Custom();
            custom.verifyJoinFlag = "0";
            custom.Language = "zh_CN";

            //信息
            Message message = new Message();
            message.goodsID = "";
            message.goodsName = ProName;
            message.goodsNum = "";
            message.carriageAmt = "";
            message.merHint = "";
            message.remark1 = "";
            message.remark2 = "";
            message.merURL = Url;
            message.merVAR = merVAR;
            message.notifyType = "HS";
            message.resultType = "1";
            message.backup1 = "";
            message.backup2 = "";
            message.backup3 = "";
            message.backup4 = "";

            #endregion

            #region 組裝XML報文內容



            //組裝xml報文內容
            StringBuilder tranDataContent = new StringBuilder();
            tranDataContent.Append("<?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"), "12345678") == 0)
            {
                merSignMsg = icbcObj.signC(tranDataContent.ToString(), tranDataContent.Length);//生成簽名 
            }
            //BASE64商城證書公鑰
            merCert = icbcObj.getCert(1);

            #endregion

            #region 數據準完成,發送至頁面
            //參數傳至HTML
            ViewBag.interfaceName = req.interfaceName;
            ViewBag.interfaceVersion = req.interfaceVersion;
            ViewBag.clientType = "0";
            ViewBag.tranData = tranData;
            ViewBag.merSignMsg = merSignMsg;
            ViewBag.merCert = merCert;
            #endregion
View Code

發起支付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>
View Code

 發起支付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>
View Code

 

Ps:

1.在使用測試帳號的時候,訂單日期必須與測試伺服器一致,可以使用工行提供的工具獲取伺服器當前時間。

2.運行項目時需要啟用32應用程式。

3.測試期間一般是使用H5支付,正式商戶號申請完成之後,H5嵌入工行APP,使用工行APP支付。

 

 

組件下載

http://pan.baidu.com/s/1c2yyjWO

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Redis緩存伺服器是一款key/value資料庫,讀110000次/s,寫81000次/s,因為是記憶體操作所以速度飛快,常見用法是存用戶token、簡訊驗證碼等 官網顯示Redis本身並沒有Windows版本的,微軟官方開發了基於Windows的Redis伺服器:MSOpenTech/redis ...
  • 觸發器在之前的項目中, 應用的著實不多, 沒有辦法的時候, 才會去用這個. 因為這個東西在後期並不怎麼好維護, 也容易造成紊亂. 我最近的項目中, 由於資料庫設計(別人設計的)原因, 導致一些最簡單功能, 查詢起來, 都很麻煩和複雜. 牽涉表非常多, 表與表之間又互有部分關係. 我想說, 這是我見過 ...
  • 比如有一個表,我們需要些一個語句像SELECT OtherID, SplitData WHERE SomeID = 'abcdef-.......' , 然後就能返回分割成單獨的行。 原表: | SomeID | OtherID | Data + + + | abcdef-..... | cdef1 ...
  • 第六節 Linux系統基礎優化 標簽(空格分隔):Linux實戰教學筆記 陳思齊 第1章 基礎環境 ![QQ20161227 [email protected] 60.5kB][1] 第2章 使用網易163鏡像做yum源 預設國外的yum源速度很慢,所以換成國內的。 第一步:先備份 mkdir backup ...
  • 我們在 "Linux設備管理(一)_kobject, kset,ktype分析" 一文中介紹了kobject的相關知識,在 "Linux設備管理(二)_從cdev_add說起" 和 "Linux設備管理(三)_匯流排設備的掛接" 舉例介紹了內核中是如何進行設備管理的,併在 "Linux設備管理(四)_ ...
  • 本人在官網下的是這個 CentOS-7-x86_64-DVD-1611.iso ,然後用UltraISO 9.6製作的U盤啟動盤,不過在安裝的時候出現了這個錯誤, 然後也是搜了好久,試了一下,下麵這個方法,是正確可行的.在最後我會解釋原因 第一步: 製作完成之後,將U盤的標簽名字改掉,隨便改成什麼, ...
  • linux許可權位 Linux文件或目錄的許可權位是由9個許可權位來控制,每三位為一組,它們分別是文件屬主許可權、屬組許可權、其他用戶許可權。 r:read可讀許可權,對應數字4; w:write可寫許可權,對應數字2; x:execute執行許可權,對應數字1; -:沒有任何許可權,對應數字0。 #創建一個用戶組 [... ...
  • 前面講到,使用非阻塞方式有許多的缺點。主要是單線程,一直占用CPU資源,其他程式無法執行,造成資源的浪費。只能用於較簡單迴圈的場所。而線程靈活,CPU占用率小,適用於大部分場合。 1.條件變數的使用 條件變數是用來通知共用數據的狀態信息的機制。由於涉及共用數據,所以一般和互斥量配合使用。 1.1創建 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...