微信支付開(kāi)發(fā)中Senparc.Weixin.MP的案例分析-創(chuàng)新互聯(lián)

這篇文章主要介紹微信支付開(kāi)發(fā)中Senparc.Weixin.MP的案例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營(yíng)銷推廣、網(wǎng)站重做改版、尼木網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5場(chǎng)景定制商城網(wǎng)站開(kāi)發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為尼木等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。

公眾號(hào)+微信支付 SDK:Senparc.Weixin.MP.dll

企業(yè)號(hào) SDK:Senparc.Weixin.QY.dll

開(kāi)放平臺(tái) SDK:Senparc.Weixin.Open.dll

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

當(dāng)然,我們要完成公眾號(hào)微信支付功能的開(kāi)發(fā),需要使用Senparc.Weixin.MP.dll這個(gè)DLL,查閱了一下官方提供的DEMO以及教程,并沒(méi)有載入微信支付相關(guān)的說(shuō)明,沒(méi)辦法,既然拿到源碼了,自己找吧。

打開(kāi)Senparc.Weixin.MP.sln,根據(jù)英文文件夾名稱的分類,可以初步判斷,關(guān)于微信支付,被封裝在TenPayLib文件夾中,但是我還發(fā)現(xiàn),里面存在名稱叫“TenPayLibV3”的文件夾,那如何選擇呢?網(wǎng)上搜索了一下,得出這個(gè)結(jié)論:2014年9月10號(hào)之前申請(qǐng)的為v2版,之后申請(qǐng)的為v3版。我用來(lái)測(cè)試微信支付的服務(wù)號(hào)是在16年剛申請(qǐng),并且通過(guò)驗(yàn)證的,那么果斷使用V3吧。

打開(kāi)TenPayLibV3文件夾:

微信支付開(kāi)發(fā)中Senparc.Weixin.MP的案例分析

這里發(fā)現(xiàn)多個(gè)類庫(kù),每一個(gè)都是做什么的呢?我們這里不一一敘述,感興趣的朋友可以下載來(lái)看,每一個(gè)類的文件頭都有功能說(shuō)明與描述,對(duì)照微信官方支付說(shuō)明,我們直接開(kāi)始做支付。

進(jìn)入微信公眾號(hào),點(diǎn)擊功能菜單中的微信支付:并相應(yīng)點(diǎn)擊 使用教程-公眾號(hào)支付

微信支付開(kāi)發(fā)中Senparc.Weixin.MP的案例分析微信支付開(kāi)發(fā)中Senparc.Weixin.MP的案例分析

迅速對(duì)文檔內(nèi)容重溫、瀏覽,以方便在Senparc.Weixin.MP.dll中查找相應(yīng)的功能。

微信支付開(kāi)發(fā)中Senparc.Weixin.MP的案例分析

先配置支付授權(quán)目錄,添加支付測(cè)試白名單,支付目錄只支持三個(gè),并且域名必須經(jīng)過(guò)ICP備案。授權(quán)目錄的作用是,如果要發(fā)起微信支付請(qǐng)求,請(qǐng)求的鏈接地址必須在授權(quán)目錄下,否則身份無(wú)效,支付不能成功。測(cè)試白名單中添加的個(gè)人微信號(hào),才能完成微信支付測(cè)試目錄支付的測(cè)試,不在白名單中人員發(fā)起支付申請(qǐng),支付不能成功。

配置完成后,如何調(diào)用呢?我們繼續(xù)看官方說(shuō)明:H5調(diào)起支付API  

“在微信瀏覽器里面打開(kāi)H5網(wǎng)頁(yè)中執(zhí)行JS調(diào)起支付。接口輸入輸出數(shù)據(jù)格式為JSON。

注意:WeixinJSBridge內(nèi)置對(duì)象在其他瀏覽器中無(wú)效。

列表中參數(shù)名區(qū)分大小,大小寫(xiě)錯(cuò)誤簽名驗(yàn)證會(huì)失敗。”

OK,這里說(shuō)明了幾個(gè)事情,第一必須在微信瀏覽器進(jìn)行;第二,參數(shù)區(qū)分大小寫(xiě);第三,數(shù)據(jù)格式為JSON。

官方說(shuō)明,只要在頁(yè)面中調(diào)用如下腳本,即可開(kāi)啟微信支付功能:

function onBridgeReady(){
   WeixinJSBridge.invoke(
       'getBrandWCPayRequest', {
           "appId" : "wx2421b1c4370ec43b",     //公眾號(hào)名稱,由商戶傳入     
           "timeStamp":" 1395712654",         //時(shí)間戳,自1970年以來(lái)的秒數(shù)     
           "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //隨機(jī)串     
           "package" : "prepay_id=u802345jgfjsdfgsdg888",     
           "signType" : "MD5",         //微信簽名方式:     
           "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信簽名 
       },
       function(res){     
           if(res.err_msg == "get_brand_wcpay_request:ok" ) {}     // 使用以上方式判斷前端返回,微信團(tuán)隊(duì)鄭重提示:res.err_msg將在用戶支付成功后返回    ok,但并不保證它絕對(duì)可靠。 
       }
   ); 
}
if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
}

我的調(diào)用代碼:因?yàn)槲乙邳c(diǎn)擊按鈕確認(rèn)支付之后,在調(diào)用微信支付進(jìn)行后續(xù)操作,把官方代碼提出到方法中

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

好吧,那這堆參數(shù)是從哪來(lái)的,都是啥玩意兒?我們逐個(gè)分析一下:

appId:這個(gè)做微信開(kāi)發(fā)都應(yīng)該知道,公眾號(hào)在開(kāi)發(fā)者菜單就能找到

timeStamp:時(shí)間戳,官方描述為“自1970年以來(lái)的秒數(shù)”,不用擔(dān)心,肯定能從支付類庫(kù)里找到

nonceStr:官方解釋是隨機(jī)串“e61463f8efa94090b1f366cccfbbb444”,靠啥玩意兒?詳見(jiàn)隨機(jī)數(shù)生成算法,原來(lái)就是一套加密規(guī)則和算法,做過(guò)URL請(qǐng)求接口的朋友應(yīng)該知道,有些公司JSON串的簽名方式和這比較類似。

package:預(yù)支付ID,調(diào)用官方API統(tǒng)一下單接口可以獲得

signType:字符串"MD5"

paySign:官方解釋是微信簽名“70EA570631E4BB79628FBCA90534C63FF7FADD89”,好吧,我忍了,在看下簽名生成算法,看來(lái)和隨機(jī)串一個(gè)鳥(niǎo)樣

到這里,官方的接口說(shuō)明已經(jīng)了解的很清楚了,那么下面就要解決調(diào)用微信支付的這幾個(gè)參數(shù)了,通過(guò)Senparc.Weixin.MP.dll應(yīng)該如何使用呢?既然需要先調(diào)用統(tǒng)一下單接口獲取預(yù)支付訂單ID,好吧,我們先來(lái)研究一下,如何獲得這個(gè)ID吧。

官方給出了詳細(xì)說(shuō)明,我們不在贅述,各參數(shù)研究按照上述接口的方式自行研究解決,區(qū)別在于,調(diào)用官方接口需要傳入一個(gè)XML,那很好辦,拼接一下就可以了,預(yù)支付調(diào)用方法如下:

//這里通過(guò)官方的一個(gè)實(shí)體,用戶自行使用,我這里是直接讀取的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>
        /// 微信預(yù)支付
        /// </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);
            //微信分配的公眾賬號(hào)ID(企業(yè)號(hào)corpid即為此appId)
            requestHandler.SetParameter("appid", tenPayV3Info.AppId);
            //附加數(shù)據(jù),在查詢API和支付通知中原樣返回,該字段主要用于商戶攜帶訂單的自定義數(shù)據(jù)
            requestHandler.SetParameter("attach", attach);
            //商品或支付單簡(jiǎn)要描述
            requestHandler.SetParameter("body", body);
            //微信支付分配的商戶號(hào)
            requestHandler.SetParameter("mch_id", tenPayV3Info.MchId);
            //隨機(jī)字符串,不長(zhǎng)于32位。
            requestHandler.SetParameter("nonce_str", TenPayUtil.GetNoncestr());
            //接收微信支付異步通知回調(diào)地址,通知url必須為直接可訪問(wèn)的url,不能攜帶參數(shù)。
            requestHandler.SetParameter("notify_url", tenPayV3Info.TenPayV3Notify);
            //trade_type=JSAPI,此參數(shù)必傳,用戶在商戶公眾號(hào)appid下的標(biāo)識(shí)。
            requestHandler.SetParameter("openid", openid);
            //商戶系統(tǒng)內(nèi)部的訂單號(hào),32個(gè)字符內(nèi)、可包含字母,自己生成
            requestHandler.SetParameter("out_trade_no", orderNum);
            //APP和網(wǎng)頁(yè)支付提交用戶端ip,Native支付填調(diào)用微信支付API的機(jī)器IP。
            requestHandler.SetParameter("spbill_create_ip", "127.0.0.1");
            //訂單總金額,單位為分,做過(guò)銀聯(lián)支付的朋友應(yīng)該知道,代表金額為12位,末位分分
            requestHandler.SetParameter("total_fee", price);
            //取值如下:JSAPI,NATIVE,APP,我們這里使用JSAPI
            requestHandler.SetParameter("trade_type", "JSAPI");
            //設(shè)置KEY
            requestHandler.SetKey(tenPayV3Info.Key);

            requestHandler.CreateMd5Sign();
            requestHandler.GetRequestURL();
            requestHandler.CreateSHA1Sign();
            string data = requestHandler.ParseXML();
            requestHandler.GetDebugInfo();

            //獲取并返回預(yù)支付XML信息
            return TenPayV3.Unifiedorder(data);
        }
    }

好的,拿到預(yù)支付訂單的返回?cái)?shù)據(jù),一切又都好辦了,根據(jù)返回參數(shù)的不同,自行解決,我們只關(guān)心調(diào)用正確的過(guò)程,操作繼續(xù),在返回的正確XML數(shù)據(jù)中,我們獲取到了 <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>(官方示例),好的,開(kāi)始在頁(yè)面做支付吧!

這里,我封裝了一個(gè)實(shí)體,用來(lái)傳輸常用的數(shù)據(jù),當(dāng)然,各位也可以參考Senparc.Weixin.MP.dll提供的實(shí)體類。

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

我們繼續(xù),來(lái)看一下支付接口需要用到的參數(shù)如何獲?。?/p>

public static ShareInfo GetPayInfo(string prepayid)
        {
            shareInfo = new ShareInfo();
            //檢查是否已經(jīng)注冊(cè)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;
        }

這樣,支付接口需要用到的參數(shù),就都封裝在ShareInfo里了,好吧,調(diào)用之后,我們回到頁(yè)面的后置代碼中,或者你采用的ORM對(duì)應(yīng)代碼中去,將參數(shù)輸出到頁(yè)面

//處理頁(yè)面支付調(diào)用信息
                    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));

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

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

以上是“微信支付開(kāi)發(fā)中Senparc.Weixin.MP的案例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

文章名稱:微信支付開(kāi)發(fā)中Senparc.Weixin.MP的案例分析-創(chuàng)新互聯(lián)
文章來(lái)源:http://muchs.cn/article38/doddpp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、手機(jī)網(wǎng)站建設(shè)域名注冊(cè)、網(wǎng)站改版、關(guān)鍵詞優(yōu)化企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

小程序開(kāi)發(fā)