久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    微信支付開發

     昵稱10504424 2016-01-19

      年底了,反而工作更忙了,我從15年11月開始寫《1024伐木累》系列小說和爆笑對白,得到了很多身邊的技術好友的支持,現在爆笑對白已經有越來越多的朋友一起幫著寫段子,整理,包括小說內容的編輯工作等。雖然《1024伐木累》得到的褒貶不一,但是,對我來說,堅持的過程還是快樂的。我一直有一個愿望,也愿意一直堅持著嘗試下去,包括我在公司做技術管理一樣,傳遞給身邊程序員小伙伴的思想只有一個:快快樂樂工作,健健康康編碼。我想能夠參與到技術開發中來的朋友,都希望如此。所以,小說的目的,是希望處于不同開發階段的朋友,找到自己的方向,最終實現自己的人生價值。而爆笑對白的制作,就是想讓更多的程序工作者得到快樂,哪怕只是瞬間的。

      回歸主題,16年1月初我對微信開發比較好奇,由于自己是一個比較喜歡錢的人,所以對支付功能頗為沖動,就用公司信息在微信平臺申請了一個服務號,還給騰訊打賞了300大洋做了下認證,抽空看了下微信支付官方的文檔,大概了解了一下微信支付的流程以及開發過程,說實話,雖然看完了,但是對微信官方提供的文檔有些不滿,感覺不清不楚的,但是大概的支付方式已經了解,這時候,我的懶勁又來了,在網上找到了做微信對接的C#SDK:Senparc.Weixin.MP。這個類庫的封裝,在我看來,還是不錯的,基本囊貨了微信的功能,并且在不斷的完善。類庫是開源的,每個功能都有寫簡單的單元測試,看起來一目了然。主要對接DLL對應的功能如下:

      公眾號+微信支付 SDK:Senparc.Weixin.MP.dll

      企業號 SDK:Senparc.Weixin.QY.dll

      開放平臺 SDK:Senparc.Weixin.Open.dll 

      官方地址:http://weixin./  

      當然,我們要完成公眾號微信支付功能的開發,需要使用Senparc.Weixin.MP.dll這個DLL,查閱了一下官方提供的DEMO以及教程,并沒有載入微信支付相關的說明,沒辦法,既然拿到源碼了,自己找吧。

      打開Senparc.Weixin.MP.sln,根據英文文件夾名稱的分類,可以初步判斷,關于微信支付,被封裝在TenPayLib文件夾中,但是我還發現,里面存在名稱叫“TenPayLibV3”的文件夾,那如何選擇呢?網上搜索了一下,得出這個結論:2014年9月10號之前申請的為v2版,之后申請的為v3版。我用來測試微信支付的服務號是在16年剛申請,并且通過驗證的,那么果斷使用V3吧。

      打開TenPayLibV3文件夾:

      

      這里發現多個類庫,每一個都是做什么的呢?我們這里不一一敘述,感興趣的朋友可以下載來看,每一個類的文件頭都有功能說明與描述,對照微信官方支付說明,我們直接開始做支付。

      進入微信公眾號,點擊功能菜單中的微信支付:并相應點擊 使用教程-公眾號支付

      

      迅速對文檔內容重溫、瀏覽,以方便在Senparc.Weixin.MP.dll中查找相應的功能。

      

      先配置支付授權目錄,添加支付測試白名單,支付目錄只支持三個,并且域名必須經過ICP備案。授權目錄的作用是,如果要發起微信支付請求,請求的鏈接地址必須在授權目錄下,否則身份無效,支付不能成功。測試白名單中添加的個人微信號,才能完成微信支付測試目錄支付的測試,不在白名單中人員發起支付申請,支付不能成功。

      配置完成后,如何調用呢?我們繼續看官方說明:H5調起支付API  

      “在微信瀏覽器里面打開H5網頁中執行JS調起支付。接口輸入輸出數據格式為JSON。

      注意:WeixinJSBridge內置對象在其他瀏覽器中無效。

      列表中參數名區分大小,大小寫錯誤簽名驗證會失敗。”

      OK,這里說明了幾個事情,第一必須在微信瀏覽器進行;第二,參數區分大小寫;第三,數據格式為JSON。

      官方說明,只要在頁面中調用如下腳本,即可開啟微信支付功能:

    復制代碼
     1 function onBridgeReady(){
     2    WeixinJSBridge.invoke(
     3        'getBrandWCPayRequest', {
     4            "appId" : "wx2421b1c4370ec43b",     //公眾號名稱,由商戶傳入     
     5            "timeStamp":" 1395712654",         //時間戳,自1970年以來的秒數     
     6            "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //隨機串     
     7            "package" : "prepay_id=u802345jgfjsdfgsdg888",     
     8            "signType" : "MD5",         //微信簽名方式:     
     9            "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信簽名 
    10        },
    11        function(res){     
    12            if(res.err_msg == "get_brand_wcpay_request:ok" ) {}     // 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功后返回    ok,但并不保證它絕對可靠。 
    13        }
    14    ); 
    15 }
    16 if (typeof WeixinJSBridge == "undefined"){
    17    if( document.addEventListener ){
    18        document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
    19    }else if (document.attachEvent){
    20        document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
    21        document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
    22    }
    23 }else{
    24    onBridgeReady();
    25 }
    復制代碼

      我的調用代碼:因為我要在點擊按鈕確認支付之后,在調用微信支付進行后續操作,把官方代碼提出到方法中

    復制代碼
     function onBridgeReady() {
                WeixinJSBridge.invoke(
                    'getBrandWCPayRequest', {
                        "appId": $('#APPID').val(),     //公眾號名稱,由商戶傳入     
                        "timeStamp": $('#Timestamp').val(),         //時間戳,自1970年以來的秒數     
                        "nonceStr": $('#Noncestr').val(), //隨機串     
                        "package": $('#package').val(),
                        "signType": "MD5",         //微信簽名方式:     
                        "paySign": $('#paySign').val() //微信簽名 
                    },
                    function (res) {
                        if (res.err_msg == "get_brand_wcpay_request:ok") {
                            //支付成功,后續自行處理
                            
                        }
                        else
                        {
                            //支付取消,或者其他錯誤,自行處理
                        }
                    }
                );
            }         
    復制代碼

      好吧,那這堆參數是從哪來的,都是啥玩意兒?我們逐個分析一下:

      appId:這個做微信開發都應該知道,公眾號在開發者菜單就能找到

      timeStamp:時間戳,官方描述為“自1970年以來的秒數”,不用擔心,肯定能從支付類庫里找到

      nonceStr:官方解釋是隨機串“e61463f8efa94090b1f366cccfbbb444”,靠啥玩意兒?詳見隨機數生成算法,原來就是一套加密規則和算法,做過URL請求接口的朋友應該知道,有些公司JSON串的簽名方式和這比較類似。

      package:預支付ID,調用官方API統一下單接口可以獲得

      signType:字符串"MD5"    

      paySign:官方解釋是微信簽名“70EA570631E4BB79628FBCA90534C63FF7FADD89”,好吧,我忍了,在看下簽名生成算法,看來和隨機串一個鳥樣 

      到這里,官方的接口說明已經了解的很清楚了,那么下面就要解決調用微信支付的這幾個參數了,通過Senparc.Weixin.MP.dll應該如何使用呢?既然需要先調用統一下單接口獲取預支付訂單ID,好吧,我們先來研究一下,如何獲得這個ID吧。

      官方給出了詳細說明,我們不在贅述,各參數研究按照上述接口的方式自行研究解決,唯一區別在于,調用官方接口需要傳入一個XML,那很好辦,拼接一下就可以了,預支付調用方法如下:

    復制代碼
    //這里通過官方的一個實體,用戶自行使用,我這里是直接讀取的CONFIG文件
    private static Senparc.Weixin.MP.TenPayLibV3.TenPayV3Info tenPayV3Info = new Senparc.Weixin.MP.TenPayLibV3.TenPayV3Info(ConfigurationManager.AppSettings["corpId"], ConfigurationManager.AppSettings["corpSecret"], ConfigurationManager.AppSettings["mch_id"]
                        , ConfigurationManager.AppSettings["key"], ConfigurationManager.AppSettings["v3url"]);
    
            /// <summary>
            /// 微信預支付
            /// </summary>
            /// <param name="attach"></param>
            /// <param name="body"></param>
            /// <param name="openid"></param>
            /// <param name="price"></param>
            /// <param name="orderNum"></param>
            /// <returns></returns>
            public static string PayInfo(string attach, string body, string openid, string price, string orderNum = "1833431773763549")
            {
                RequestHandler requestHandler = new RequestHandler(HttpContext.Current);
                //微信分配的公眾賬號ID(企業號corpid即為此appId)
                requestHandler.SetParameter("appid", tenPayV3Info.AppId);
                //附加數據,在查詢API和支付通知中原樣返回,該字段主要用于商戶攜帶訂單的自定義數據
                requestHandler.SetParameter("attach", attach);
                //商品或支付單簡要描述
                requestHandler.SetParameter("body", body);
                //微信支付分配的商戶號
                requestHandler.SetParameter("mch_id", tenPayV3Info.MchId);
                //隨機字符串,不長于32位。
                requestHandler.SetParameter("nonce_str", TenPayUtil.GetNoncestr());
                //接收微信支付異步通知回調地址,通知url必須為直接可訪問的url,不能攜帶參數。
                requestHandler.SetParameter("notify_url", tenPayV3Info.TenPayV3Notify);
                //trade_type=JSAPI,此參數必傳,用戶在商戶公眾號appid下的唯一標識。
                requestHandler.SetParameter("openid", openid);
                //商戶系統內部的訂單號,32個字符內、可包含字母,自己生成
                requestHandler.SetParameter("out_trade_no", orderNum);
                //APP和網頁支付提交用戶端ip,Native支付填調用微信支付API的機器IP。
                requestHandler.SetParameter("spbill_create_ip", "127.0.0.1");
                //訂單總金額,單位為分,做過銀聯支付的朋友應該知道,代表金額為12位,末位分分
                requestHandler.SetParameter("total_fee", price);
                //取值如下:JSAPI,NATIVE,APP,我們這里使用JSAPI
                requestHandler.SetParameter("trade_type", "JSAPI");
                //設置KEY
                requestHandler.SetKey(tenPayV3Info.Key);
    
                requestHandler.CreateMd5Sign();
                requestHandler.GetRequestURL();
                requestHandler.CreateSHA1Sign();
                string data = requestHandler.ParseXML();
                requestHandler.GetDebugInfo();
    
                //獲取并返回預支付XML信息
                return TenPayV3.Unifiedorder(data);
            }
        }
    復制代碼

    好的,拿到預支付訂單的返回數據,一切又都好辦了,根據返回參數的不同,自行解決,我們只關心調用正確的過程,操作繼續,在返回的正確XML數據中,我們獲取到了 <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>(官方示例),好的,開始在頁面做支付吧!

    這里,我封裝了一個實體,用來傳輸常用的數據,當然,各位也可以參考Senparc.Weixin.MP.dll提供的實體類。

    復制代碼
    public class ShareInfo
        {
            string corpId = string.Empty;
            public string CorpId
            {
                get { return corpId; }
                set { corpId = value; }
            }
            string ticket = string.Empty;
    
            public string Ticket
            {
                get { return ticket; }
                set { ticket = value; }
            }
            string noncestr = string.Empty;
    
            public string Noncestr
            {
                get { return noncestr; }
                set { noncestr = value; }
            }
            string timestamp = string.Empty;
    
            public string Timestamp
            {
                get { return timestamp; }
                set { timestamp = value; }
            }
    
            private string paySign = string.Empty;
            public string PaySign
            {
                get { return paySign; }
                set { paySign = value; }
            }
    
            private string package = string.Empty;
    
            public string Package
            {
                get { return package; }
                set { package = value; }
            }
        }
    復制代碼

    我們繼續,來看一下支付接口需要用到的參數如何獲取:

    復制代碼
    public static ShareInfo GetPayInfo(string prepayid)
            {
                shareInfo = new ShareInfo();
                //檢查是否已經注冊jssdk
                if (!JsApiTicketContainer.CheckRegistered(corpId))
                {
                    JsApiTicketContainer.Register(corpId, corpSecret);
                }
                JsApiTicketResult jsApiTicket = JsApiTicketContainer.GetTicketResult(corpId);
                JSSDKHelper jssdkHelper = new JSSDKHelper();
                shareInfo.Ticket = jsApiTicket.ticket;
                shareInfo.CorpId = corpId.ToLower();
                shareInfo.Noncestr = JSSDKHelper.GetNoncestr().ToLower();
                shareInfo.Timestamp = JSSDKHelper.GetTimestamp().ToLower();
                shareInfo.Package="prepay_id=" + prepayid.ToLower();
    
                RequestHandler requestHandler = new RequestHandler(HttpContext.Current);
    
                requestHandler.SetParameter("appId", shareInfo.CorpId);
                requestHandler.SetParameter("timeStamp", shareInfo.Timestamp);
                requestHandler.SetParameter("nonceStr", shareInfo.Noncestr);
                requestHandler.SetParameter("package", shareInfo.Package);
                requestHandler.SetParameter("signType", "MD5");
    
                requestHandler.SetKey(tenPayV3Info.Key);
                requestHandler.CreateMd5Sign();
                requestHandler.GetRequestURL();
                requestHandler.CreateSHA1Sign();
                shareInfo.PaySign = (requestHandler.GetAllParameters()["sign"]).ToString();
                return shareInfo;
            }
    復制代碼

    這樣,支付接口需要用到的參數,就都封裝在ShareInfo里了,好吧,調用之后,我們回到頁面的后置代碼中,或者你采用的ORM對應代碼中去,將參數輸出到頁面

    復制代碼
    //處理頁面支付調用信息
                        ShareInfo shareInfo = TenPayModule.GetPayInfo(prepayid);
                        System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"Noncestr\" runat=\"server\" value=\"{0}\" />", shareInfo.Noncestr));
                        System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"Timestamp\" runat=\"server\" value=\"{0}\" />", shareInfo.Timestamp));
                        System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"APPID\" runat=\"server\" value=\"{0}\" />", shareInfo.CorpId));
                        System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"paySign\" runat=\"server\" value=\"{0}\" />", shareInfo.PaySign));
                        System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"package\" runat=\"server\" value=\"{0}\" />", shareInfo.Package));
    復制代碼

    好的,寫到這里,大家參照上面的JS代碼,就可以完成整個的支付功能了。最后,再附送一個生成商家訂單號的方法,代碼如下:

    復制代碼
    public string GetOrderNumber()
            {
                string Number = DateTime.Now.ToString("yyMMddHHmmss");
                return Number + Next(1000, 1).ToString();
            }
            private static int Next(int numSeeds, int length)
            {
                byte[] buffer = new byte[length]; 
                System.Security.Cryptography.RNGCryptoServiceProvider Gen = new System.Security.Cryptography.RNGCryptoServiceProvider();
                Gen.GetBytes(buffer);
                uint randomResult = 0x0; 
                for (int i = 0; i < length; i++)
                {
                    randomResult |= ((uint)buffer[i] << ((length - 1 - i) * 8));
                }
                return (int)(randomResult % numSeeds);
            }
    復制代碼

     

    好了,一切都是這樣的簡單,一兩個小時,微信支付輕松搞定!

      

     

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 一本之道高清乱码少妇| 99精品热在线在线观看视| 国产免费高清69式视频在线观看 | 一区二区中文字幕av| 国产线播放免费人成视频播放| 日韩AV无码免费播放| 日韩少妇人妻vs中文字幕| 国产AV老师黑色丝袜美腿| 无码国产精品一区二区高潮| 亚洲人成网网址在线看| 午夜精品一区二区三区免费视频 | 无码专区 人妻系列 在线| 亚洲一区二区三区无码久久| 久久五月丁香合缴情网| 亚洲中文字幕久久精品无码喷水 | 开心一区二区三区激情| 午夜男女爽爽影院免费视频下载| 欧美亚洲国产一区二区三区| 中文字幕日韩有码一区| 国产成人AV性色在线影院| 天天夜碰日日摸日日澡性色AV| 亚洲精品一区二区天堂| 久久不见久久见免费视频观看| 久久精品一本到99热免费| 东京一本一道一二三区| 上课忘穿内裤被老师摸到高潮| 午夜免费无码福利视频麻豆| 55夜色66夜色国产精品视频| 国产不卡一区二区精品| 中文字幕亚洲一区二区三区| 国产精品不卡区一区二| 无码人妻一区二区三区免费N鬼沢 午夜三级A三级三点在线观看 | 后入内射国产一区二区| 一区二区三区鲁丝不卡| 无码AV岛国片在线播放| 亚洲自偷自拍另类小说| 公天天吃我奶躁我的在线观看| 白色丝袜国产在线视频| 亚洲人成电影在线天堂色| 国产青榴视频在线观看| 日产国产一区二区不卡|