這篇文章主要介紹微信支付開發(fā)中Senparc.Weixin.MP的案例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷推廣、網(wǎng)站重做改版、尼木網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5場景定制、商城網(wǎng)站開發(fā)、集團公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為尼木等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。公眾號+微信支付 SDK:Senparc.Weixin.MP.dll
企業(yè)號 SDK:Senparc.Weixin.QY.dll
開放平臺 SDK:Senparc.Weixin.Open.dll
官方地址:http://weixin.senparc.com/
當然,我們要完成公眾號微信支付功能的開發(fā),需要使用Senparc.Weixin.MP.dll這個DLL,查閱了一下官方提供的DEMO以及教程,并沒有載入微信支付相關(guān)的說明,沒辦法,既然拿到源碼了,自己找吧。
打開Senparc.Weixin.MP.sln,根據(jù)英文文件夾名稱的分類,可以初步判斷,關(guān)于微信支付,被封裝在TenPayLib文件夾中,但是我還發(fā)現(xiàn),里面存在名稱叫“TenPayLibV3”的文件夾,那如何選擇呢?網(wǎng)上搜索了一下,得出這個結(jié)論:2014年9月10號之前申請的為v2版,之后申請的為v3版。我用來測試微信支付的服務(wù)號是在16年剛申請,并且通過驗證的,那么果斷使用V3吧。
打開TenPayLibV3文件夾:
這里發(fā)現(xiàn)多個類庫,每一個都是做什么的呢?我們這里不一一敘述,感興趣的朋友可以下載來看,每一個類的文件頭都有功能說明與描述,對照微信官方支付說明,我們直接開始做支付。
進入微信公眾號,點擊功能菜單中的微信支付:并相應(yīng)點擊 使用教程-公眾號支付
迅速對文檔內(nèi)容重溫、瀏覽,以方便在Senparc.Weixin.MP.dll中查找相應(yīng)的功能。
先配置支付授權(quán)目錄,添加支付測試白名單,支付目錄只支持三個,并且域名必須經(jīng)過ICP備案。授權(quán)目錄的作用是,如果要發(fā)起微信支付請求,請求的鏈接地址必須在授權(quán)目錄下,否則身份無效,支付不能成功。測試白名單中添加的個人微信號,才能完成微信支付測試目錄支付的測試,不在白名單中人員發(fā)起支付申請,支付不能成功。
配置完成后,如何調(diào)用呢?我們繼續(xù)看官方說明:H5調(diào)起支付API
“在微信瀏覽器里面打開H5網(wǎng)頁中執(zhí)行JS調(diào)起支付。接口輸入輸出數(shù)據(jù)格式為JSON。
注意:WeixinJSBridge內(nèi)置對象在其他瀏覽器中無效。
列表中參數(shù)名區(qū)分大小,大小寫錯誤簽名驗證會失敗?!?/p>
OK,這里說明了幾個事情,第一必須在微信瀏覽器進行;第二,參數(shù)區(qū)分大小寫;第三,數(shù)據(jù)格式為JSON。
官方說明,只要在頁面中調(diào)用如下腳本,即可開啟微信支付功能:
function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId" : "wx2421b1c4370ec43b", //公眾號名稱,由商戶傳入 "timeStamp":" 1395712654", //時間戳,自1970年以來的秒數(shù) "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //隨機串 "package" : "prepay_id=u802345jgfjsdfgsdg888", "signType" : "MD5", //微信簽名方式: "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信簽名 }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ) {} // 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功后返回 ok,但并不保證它絕對可靠。 } ); } 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)用代碼:因為我要在點擊按鈕確認支付之后,在調(diào)用微信支付進行后續(xù)操作,把官方代碼提出到方法中
function onBridgeReady() { WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId": $('#APPID').val(), //公眾號名稱,由商戶傳入 "timeStamp": $('#Timestamp').val(), //時間戳,自1970年以來的秒數(shù) "nonceStr": $('#Noncestr').val(), //隨機串 "package": $('#package').val(), "signType": "MD5", //微信簽名方式: "paySign": $('#paySign').val() //微信簽名 }, function (res) { if (res.err_msg == "get_brand_wcpay_request:ok") { //支付成功,后續(xù)自行處理 } else { //支付取消,或者其他錯誤,自行處理 } } ); }
好吧,那這堆參數(shù)是從哪來的,都是啥玩意兒?我們逐個分析一下:
appId:這個做微信開發(fā)都應(yīng)該知道,公眾號在開發(fā)者菜單就能找到
timeStamp:時間戳,官方描述為“自1970年以來的秒數(shù)”,不用擔心,肯定能從支付類庫里找到
nonceStr:官方解釋是隨機串“e61463f8efa94090b1f366cccfbbb444”,靠啥玩意兒?詳見隨機數(shù)生成算法,原來就是一套加密規(guī)則和算法,做過URL請求接口的朋友應(yīng)該知道,有些公司JSON串的簽名方式和這比較類似。
package:預(yù)支付ID,調(diào)用官方API統(tǒng)一下單接口可以獲得
signType:字符串"MD5"
paySign:官方解釋是微信簽名“70EA570631E4BB79628FBCA90534C63FF7FADD89”,好吧,我忍了,在看下簽名生成算法,看來和隨機串一個鳥樣
到這里,官方的接口說明已經(jīng)了解的很清楚了,那么下面就要解決調(diào)用微信支付的這幾個參數(shù)了,通過Senparc.Weixin.MP.dll應(yīng)該如何使用呢?既然需要先調(diào)用統(tǒng)一下單接口獲取預(yù)支付訂單ID,好吧,我們先來研究一下,如何獲得這個ID吧。
官方給出了詳細說明,我們不在贅述,各參數(shù)研究按照上述接口的方式自行研究解決,區(qū)別在于,調(diào)用官方接口需要傳入一個XML,那很好辦,拼接一下就可以了,預(yù)支付調(diào)用方法如下:
//這里通過官方的一個實體,用戶自行使用,我這里是直接讀取的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"]); ////// 微信預(yù)支付 /// /// /// /// /// /// ///public static string PayInfo(string attach, string body, string openid, string price, string orderNum = "1833431773763549") { RequestHandler requestHandler = new RequestHandler(HttpContext.Current); //微信分配的公眾賬號ID(企業(yè)號corpid即為此appId) requestHandler.SetParameter("appid", tenPayV3Info.AppId); //附加數(shù)據(jù),在查詢API和支付通知中原樣返回,該字段主要用于商戶攜帶訂單的自定義數(shù)據(jù) requestHandler.SetParameter("attach", attach); //商品或支付單簡要描述 requestHandler.SetParameter("body", body); //微信支付分配的商戶號 requestHandler.SetParameter("mch_id", tenPayV3Info.MchId); //隨機字符串,不長于32位。 requestHandler.SetParameter("nonce_str", TenPayUtil.GetNoncestr()); //接收微信支付異步通知回調(diào)地址,通知url必須為直接可訪問的url,不能攜帶參數(shù)。 requestHandler.SetParameter("notify_url", tenPayV3Info.TenPayV3Notify); //trade_type=JSAPI,此參數(shù)必傳,用戶在商戶公眾號appid下的標識。 requestHandler.SetParameter("openid", openid); //商戶系統(tǒng)內(nèi)部的訂單號,32個字符內(nèi)、可包含字母,自己生成 requestHandler.SetParameter("out_trade_no", orderNum); //APP和網(wǎng)頁支付提交用戶端ip,Native支付填調(diào)用微信支付API的機器IP。 requestHandler.SetParameter("spbill_create_ip", "127.0.0.1"); //訂單總金額,單位為分,做過銀聯(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ù)支付訂單的返回數(shù)據(jù),一切又都好辦了,根據(jù)返回參數(shù)的不同,自行解決,我們只關(guān)心調(diào)用正確的過程,操作繼續(xù),在返回的正確XML數(shù)據(jù)中,我們獲取到了
這里,我封裝了一個實體,用來傳輸常用的數(shù)據(jù),當然,各位也可以參考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; } } }
我們繼續(xù),來看一下支付接口需要用到的參數(shù)如何獲?。?/p>
public static ShareInfo GetPayInfo(string prepayid) { shareInfo = new ShareInfo(); //檢查是否已經(jīng)注冊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)用之后,我們回到頁面的后置代碼中,或者你采用的ORM對應(yīng)代碼中去,將參數(shù)輸出到頁面
//處理頁面支付調(diào)用信息 ShareInfo shareInfo = TenPayModule.GetPayInfo(prepayid); System.Web.HttpContext.Current.Response.Write(string.Format("", shareInfo.Noncestr)); System.Web.HttpContext.Current.Response.Write(string.Format("", shareInfo.Timestamp)); System.Web.HttpContext.Current.Response.Write(string.Format("", shareInfo.CorpId)); System.Web.HttpContext.Current.Response.Write(string.Format("", shareInfo.PaySign)); System.Web.HttpContext.Current.Response.Write(string.Format("", 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); }
以上是“微信支付開發(fā)中Senparc.Weixin.MP的案例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!