C#手機充值系統開發(基於聚合數據)

来源:http://www.cnblogs.com/zy1411/archive/2016/07/14/5670779.html
-Advertisement-
Play Games

說是手機充值系統有點裝了,其實就是調用了聚合數據的支付介面,其實挺簡單的事 但是我發現博客園竟然沒有類似文章,我就個出頭鳥把我的代碼貢獻出來吧 首先說準備工作: 去聚合數據申請賬號-添加手機支付的認證-認證通過後為賬戶充值。 上述工作完成後,開始準備開發要用到的必要參數: appid:在個人中心-我 ...


說是手機充值系統有點裝了,其實就是調用了聚合數據的支付介面,其實挺簡單的事 但是我發現博客園竟然沒有類似文章,我就個出頭鳥把我的代碼貢獻出來吧 

首先說準備工作:

去聚合數據申請賬號-添加手機支付的認證-認證通過後為賬戶充值。

上述工作完成後,開始準備開發要用到的必要參數:

appid:在個人中心-我的數據中可找到對應的APPKEY(每個不同的介面都需要使用對應的appkey)

openid:個人中心-用戶中心-賬戶信息(這個是唯一的程式中會使用到)

 

 

對應的介面都有比較詳細的數據接收已經返回參數的說明,具體開發中會用到,具體的請查看鏈接:https://www.juhe.cn/docs/api/id/85

接下來要準備開發中的用到幾個輔助函數,在對應的API文檔中有示例代碼,也可以使用下麵的:

  1    /// <summary>
  2         /// Http (GET/POST)
  3         /// </summary>
  4         /// <param name="url">請求URL</param>
  5         /// <param name="parameters">請求參數</param>
  6         /// <param name="method">請求方法</param>
  7         /// <returns>響應內容</returns>
  8         static string sendPost(string url, IDictionary<string, string> parameters, string method)
  9         {
 10             if (method.ToLower() == "post")
 11             {
 12                 HttpWebRequest req = null;
 13                 HttpWebResponse rsp = null;
 14                 System.IO.Stream reqStream = null;
 15                 try
 16                 {
 17                     req = (HttpWebRequest)WebRequest.Create(url);
 18                     req.Method = method;
 19                     req.KeepAlive = false;
 20                     req.ProtocolVersion = HttpVersion.Version10;
 21                     req.Timeout = 5000;
 22                     req.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
 23                     byte[] postData = Encoding.UTF8.GetBytes(BuildQuery(parameters, "utf8"));
 24                     reqStream = req.GetRequestStream();
 25                     reqStream.Write(postData, 0, postData.Length);
 26                     rsp = (HttpWebResponse)req.GetResponse();
 27                     Encoding encoding = Encoding.GetEncoding(rsp.CharacterSet);
 28                     return GetResponseAsString(rsp, encoding);
 29                 }
 30                 catch (Exception ex)
 31                 {
 32                     return ex.Message;
 33                 }
 34                 finally
 35                 {
 36                     if (reqStream != null) reqStream.Close();
 37                     if (rsp != null) rsp.Close();
 38                 }
 39             }
 40             else
 41             {
 42                 //創建請求
 43                 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + "?" + BuildQuery(parameters, "utf8"));
 44 
 45                 //GET請求
 46                 request.Method = "GET";
 47                 request.ReadWriteTimeout = 5000;
 48                 request.ContentType = "text/html;charset=UTF-8";
 49                 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 50                 Stream myResponseStream = response.GetResponseStream();
 51                 StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
 52 
 53                 //返回內容
 54                 string retString = myStreamReader.ReadToEnd();
 55                 return retString;
 56             }
 57         }
 58         /// <summary>
 59         /// 把響應流轉換為文本。
 60         /// </summary>
 61         /// <param name="rsp">響應流對象</param>
 62         /// <param name="encoding">編碼方式</param>
 63         /// <returns>響應文本</returns>
 64         static string GetResponseAsString(HttpWebResponse rsp, Encoding encoding)
 65         {
 66             System.IO.Stream stream = null;
 67             StreamReader reader = null;
 68             try
 69             {
 70                 // 以字元流的方式讀取HTTP響應
 71                 stream = rsp.GetResponseStream();
 72                 reader = new StreamReader(stream, encoding);
 73                 return reader.ReadToEnd();
 74             }
 75             finally
 76             {
 77                 // 釋放資源
 78                 if (reader != null) reader.Close();
 79                 if (stream != null) stream.Close();
 80                 if (rsp != null) rsp.Close();
 81             }
 82         }
 83         /// <summary>
 84         /// 組裝普通文本請求參數。
 85         /// </summary>
 86         /// <param name="parameters">Key-Value形式請求參數字典</param>
 87         /// <returns>URL編碼後的請求數據</returns>
 88         static string BuildQuery(IDictionary<string, string> parameters, string encode)
 89         {
 90             StringBuilder postData = new StringBuilder();
 91             bool hasParam = false;
 92             IEnumerator<KeyValuePair<string, string>> dem = parameters.GetEnumerator();
 93             while (dem.MoveNext())
 94             {
 95                 string name = dem.Current.Key;
 96                 string value = dem.Current.Value;
 97                 // 忽略參數名或參數值為空的參數
 98                 if (!string.IsNullOrEmpty(name))//&& !string.IsNullOrEmpty(value)
 99                 {
100                     if (hasParam)
101                     {
102                         postData.Append("&");
103                     }
104                     postData.Append(name);
105                     postData.Append("=");
106                     if (encode == "gb2312")
107                     {
108                         postData.Append(HttpUtility.UrlEncode(value, Encoding.GetEncoding("gb2312")));
109                     }
110                     else if (encode == "utf8")
111                     {
112                         postData.Append(HttpUtility.UrlEncode(value, Encoding.UTF8));
113                     }
114                     else
115                     {
116                         postData.Append(value);
117                     }
118                     hasParam = true;
119                 }
120             }
121             return postData.ToString();
122         }
123         /// <summary>  
124         /// 獲取時間戳  
125         /// </summary>  
126         /// <returns></returns>  
127         public static string GetTimeStamp()
128         {
129             TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
130             return Convert.ToInt64(ts.TotalSeconds).ToString();
131         } 
View Code

 

這幾個函數具體的功能就不用說了 ,是代碼很簡單,都是網路鏈接發送請求和接受請求是時用的,我主要介紹的是點中未提供的一些

示例代碼中用到了JsonObject這個類 代碼中提供的是CSDN的鏈接,竟然還要2積分才能下載,坑爹啊 在這裡我給大家分享出來吧 http://pan.baidu.com/s/1hsqF51y

在項目中應用DLL加入using Xfrog.Net;命名空間

準備工作結束

 

接下來就進入正式編碼階段了 ,開始前我準備說一下重點,其實介面的代碼並不複雜,我想說了還是思路吧

1.驗證當前賬戶餘額是否夠本次充值:調用 http://op.juhe.cn/ofpay/mobile/yue 具體參數參看:https://www.juhe.cn/docs/api/id/85

2.檢測手機號是否可以充值:調用http://op.juhe.cn/ofpay/mobile/telcheck    具體參數參看:https://www.juhe.cn/docs/api/id/85/aid/213

3.調用手機直衝介面:   http://op.juhe.cn/ofpay/mobile/onlineorder       具體參數參看: https://www.juhe.cn/docs/api/id/85/aid/214

4.調用訂單查詢介面:http://op.juhe.cn/ofpay/mobile/ordersta                具體參數參看:https://www.juhe.cn/docs/api/id/85/aid/586

5.編寫回調處理頁面:QQ上搜索聚合數據的客服,給他賬號和回調地址後,讓他幫助設置,具體的回調地址接受參數查看:http://code.juhe.cn/docs/detail/id/1565

 

具體代碼貼出:

 

            //1.賬戶餘額查詢
            string url1 = "http://op.juhe.cn/ofpay/mobile/yue";

            var parameters1 = new Dictionary<string, string>();

            string timestamp = GetTimeStamp();
            parameters1.Add("timestamp", timestamp); //當前時間戳,如:1432788379
            parameters1.Add("key", appkey);//你申請的key
            string signstr =openid+ appkey+timestamp;
            parameters1.Add("sign", CommonManager.String.EncryptMD5SystemDefaultMethod(signstr, false, true)); //校驗值,md5(&lt;b&gt;OpenID&lt;/b&gt;+key+timestamp),OpenID在個人中心查詢

            string result1 = sendPost(url1, parameters1, "get");

            JsonObject newObj1 = new JsonObject(result1); 
            String errorCode1 = newObj1["error_code"].Value;

            //查詢餘額是否成功
            if (errorCode1 == "0")
            {

                //判斷餘額是否夠本次充值
                if (double.Parse(newObj1["result"]["money"].Value) > double.Parse(Integrals))
    
                {
                     //msg.InnerText="餘額充足!";

                    //5.檢測手機號碼是否能充值
                    string url5 = "http://op.juhe.cn/ofpay/mobile/telcheck";

                    var parameters5 = new Dictionary<string, string>();

                    parameters5.Add("phoneno", phone); //手機號碼
                    parameters5.Add("cardnum", Integrals); //充值金額,目前可選:5、10、20、30、50、100、300
                    parameters5.Add("key", appkey);//你申請的key

                    string result5 = sendPost(url5, parameters5, "get");

                    JsonObject newObj5 = new JsonObject(result5);
                    String errorCode5 = newObj5["error_code"].Value;

                    if (errorCode5 == "0")
                    {
                         //可以充值
                        //7.手機直充介面
                        string url7 = "http://op.juhe.cn/ofpay/mobile/onlineorder";

                        var parameters7 = new Dictionary<string, string>();
                        parameters7.Add("phoneno", phone); //手機號碼
                        parameters7.Add("cardnum", Integrals); //充值金額,目前可選:5、10、20、30、50、100、300
                        parameters7.Add("orderid", orderstr); //商家訂單號,8-32位字母數字組合
                        parameters7.Add("key", appkey);//你申請的key
                        string md5str = openid + appkey + phone + Integrals + orderstr;
                        parameters7.Add("sign", CommonManager.String.EncryptMD5SystemDefaultMethod(md5str, false, true)); //校驗值,md5(&lt;b&gt;OpenID&lt;/b&gt;+key+phoneno+cardnum+orderid),OpenID在個人中心查詢

                    
                        string result7 = sendPost(url7, parameters7, "get");

                        JsonObject newObj7 = new JsonObject(result7);
                        String errorCode7 = newObj7["error_code"].Value;

                        if (errorCode7 == "0")
                        {
                            msg.InnerText = "充值訂單創建成功,等待商戶充值後查看訂單狀態!";

                            DbSession.Default.FromSql(
                            @"UPDATE TOP(1) TPropLog SET Jhorderid=@Jhorderid,PropStatus=@PropStatus WHERE ID = @ID")
                            .AddInputParameter("@ID", DbType.Int32, id)
                            .AddInputParameter("@PropStatus", DbType.Int32, 3)
                            .AddInputParameter("@Jhorderid", DbType.String, newObj7["result"]["sporder_id"].Value)
                            .Execute();
                            status.SelectedValue = "3";
                        }
                        else
                        {
                            msg.InnerText = "充值訂單失敗!失敗原因:" + newObj7["reason"].Value;
                        }
 
                    }
                    else
                    {
                        msg.InnerText = "手機號不能充值!原因:" + newObj1["reason"].Value;
                    }

      
                }
                else
                {
                    msg.InnerText = "餘額不足請充值!當前賬戶餘額為:" + newObj1["result"]["money"].Value;
                }

            }
            else
            {
                 msg.InnerText="餘額查詢失敗!";

            }

裡面有幾個點註意一下:

1.需要sign簽名的幾個介面需要按照格式使用MD5進行一個轉換,MD5轉換的函數網上一大把相信你的項目中也有了我就不提供了 ,按照他提供的格式組織簽名就行了

2.我的訂單查詢介面是寫在另外一個函數里的,因為我的邏輯充值後單獨可以查詢,可根據情況自行更改。

3.回調頁面是POST方式傳值,所以接受的時候按照他提供的參數接收就行了,根據返回的訂單號跟新本地數據

        //聚合話費充值回調頁面,頁面的設置需要聯繫聚合客服更改
        protected void Page_Load(object sender, EventArgs e)
        {

            var sporder_id = CommonManager.Web.Request("sporder_id", "");//聚合訂單ID
            var orderid = CommonManager.Web.Request("orderid", "");      //鼎鼎訂單ID
            var sta = CommonManager.Web.Request("sta", "");               //充值狀態1:成功 9:失敗
            if (sta == "1")
            { 
               //更新訂單狀態為充值成功
                DbSession.Default.FromSql(
                        @"UPDATE TOP(1) TPropLog SET PropStatus=@PropStatus WHERE Jhorderid = @Jhorderid")
                        .AddInputParameter("@PropStatus", DbType.Int32, 4)
                        .AddInputParameter("@Jhorderid", DbType.String, sporder_id)
                        .Execute();
                Response.Clear();
                Response.Write("success");
                Response.End();
            }
            if (sta == "9")
            {
                //更新訂單狀態為充值成功
                DbSession.Default.FromSql(
                        @"UPDATE TOP(1) TPropLog SET PropStatus=@PropStatus WHERE Jhorderid = @Jhorderid")
                        .AddInputParameter("@PropStatus", DbType.Int32, 5)
                        .AddInputParameter("@Jhorderid", DbType.String, sporder_id)
                        .Execute();
                Response.Clear();
                Response.Write("success");
                Response.End();
                //更新訂單狀態為充值失敗
            }

        }

重點回顧:

1.JsonObject.DLL下載

2.簽名順序和字元要按照提供的做

3.回調地址要找客服設置

4.單個手機號每天有充值數量和次數的限制,超過次數會導致訂單一直提示進行中,最後失敗,失敗也會有回調提示的

5.測試的時候可以將vs自帶的iis調試工具配合ngrok映射到外網,這樣直接就可以調試回調頁面,改天我會寫一個簡單的教程,如何使用vs預設的iis映射到外網進行調試(微信的外網調試也可以這麼做,非常方便哦)

 


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

-Advertisement-
Play Games
更多相關文章
  • 定義這樣一個方法,然後接收前臺傳過來的值,調用這個方法就行了.. ...
  • 這篇文章我們開始看一下ActionFilter,從名字上其實就大概知道ActionFilter就是Action上的Filter,對吧,那麼Action上的Filter大概有幾個呢??? 這個問題其實還是蠻簡單的,因為我們聽說Mvc本身就是一個擴展性極強的框架,自然就是層層有攔截,層層有過濾,對吧,比 ...
  • 前言: 你先得知道HelpPageConfig文件,不知道說明你現在不需要這個,所以下文就不用看了,等知道了再看也不急.當然如果你很知道這個,下文也不用看了,因為你會了. 方法一: 方法二: 自定義一個支持從目錄載入xml文檔的XmlDocumentationProvider 使用方法: 使用方法: ...
  • 首個基於NHibernate的應用程式 Your first NHibernate based application 原文地址:http://www.nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx 本文涉 ...
  • 1. Tamcat 的安裝,此不介紹 路徑:F:\SolrTest\apache-tomcat-8.0.18 2. 解壓 solr 5.3.2 路徑:F:\Tool\solr-5.3.2 3. 複製solr5.3.2 webapp到tomcat 路徑:“F:\Tool\solr-5.3.2\serv ...
  • 本文適合初學者,老鳥請點贊即走,謝謝。 文字功底有限,表述不恰當的地方,請各位多多包涵。 一,核心 現在ORM已經很多了,功能也齊全了,大家說我這是乾無聊的事,造的連車輪子都還不算,反正我就當學習。 還有就是,下麵這個不算正在的ORM,離真正在ORM差的很遠的。 主要思想 二,實例測試 1,基礎數據 ...
  • 下麵給出了Remoting的小實例,主要功能是將客戶端的數據寫入到服務端。 分析圖: 程式代碼為2個控制台應用程式(1個客戶端,1個伺服器端)和1個類庫,如下所示。 客戶端代碼: using RemotingObjects; using System; using System.Collection ...
  • 起因 最近在對接一個第三方平臺。該平臺只提供了Java版本的SDK,C#版本的還處於敬請期待狀態。由於C#可以復用絕大部分代碼,便考慮找一個Java到C#的轉換器,在試用了幾個軟體之後,發現還是Java to C# Converter(下文簡稱Converter)好用一點。然而基本版功能受限(文件夾 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...