因為在弄微信公眾號網(wǎng)頁支付的時候,遇到比較多的坑,而且微信給出的文檔也比較亂。自己在百度的時候也看到很多人遇到相同的問題,但是都沒有得到滿意的答案。
所以就自己寫個日志記錄一下,也算是自己的一個積累。
首先我這里將的微信公眾號網(wǎng)頁支付的方式也就是JS API 網(wǎng)頁支付。是指用戶打開圖文消息戒者掃描二維碼,在微信內(nèi)置瀏覽器打開網(wǎng)頁進行的支付。商戶網(wǎng)頁前端通過使用微信提供的 JS API,調(diào)用微信支付模塊。這種方式,適合需要在商戶網(wǎng)頁進行選購下單的購買流程。
在進行微信公眾支付之前,我們需要申請個公眾好,以及申請微信支付的功能。這些不在之類講述。
申請好了以后,我們需要獲取一下信息。

然后我們再來看一下微信網(wǎng)頁支付的流程圖。 我們先從后端開始。 如下圖:

從流程圖可以看出,我們需要先拿到用戶的openid,這個openid 是用戶在這個公眾號的唯一標識。需要拿到這個openid 是需要用戶做授權(quán)的。
這個獲取用戶openid 的步驟 在微信官方文檔講述的還是比較詳細的。 在這里就不詳細講述。詳情看官方文檔
在我們獲取到用戶的openid 的時候,此時我們就可以生成一個預(yù)支付的訂單。在jsapi 生成預(yù)支付訂單是需要用的openid的。所以一開始獲取用戶 的openid 也就是為了生存預(yù)支付訂單做準備的。接下來我們來看,怎么生成預(yù)支付訂單。
根據(jù)微信的官方文檔,我們需要用微信統(tǒng)一支付接口生成預(yù)支付訂單。
主要有以下幾個步驟:
查看那些參數(shù)必須要上傳的
對需要上傳的參數(shù)進行加密,得到一個加密后的字符串,作為一個參數(shù)上傳。
提交數(shù)據(jù),并接受返回回來的結(jié)果。
需要上傳的參數(shù),因為參數(shù)還是比較多,詳情看微信的官方文檔(注意,參數(shù)是區(qū)分大小寫的)
參數(shù)加密的步驟如下:
第一步:對參數(shù)按照key=value的格式,并按照參數(shù)名ASCII字典序排序如下:
java中可以用如下方法對參數(shù)進行ASCII字典序排序
String [] getPr =
{"appid","mch_id","nonce_str","body","out_trade_no","total_fee","spbill_create_ip","notify_url","trade_type","attach","openid"};
Arrays.sort(getPr);
for(String list :getPr ){
System.out.println(list);
}
stringA=”appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA”;
第二步:拼接API密鑰:(拼接好后,進行MD5加密,然后把加密結(jié)果的小寫字母轉(zhuǎn)化為大寫字母,從而得到加密字符串(sign))
stringSignTemp=”stringA&key=192006250b4c09247ec02edce69f6a2d”
sign=MD5(stringSignTemp).toUpperCase()=”9A0A8659F005D6984697E2CA0A9CF3B7”
最后一步,提交數(shù)據(jù)。注意這里提交數(shù)據(jù)的格式是以xml 的格式提交的。格式如下:
<xml> <appid>wx2421b1c4370ec43b</appid>
<attach>支付測試</attach>
<body>JSAPI支付測試</body>
<mch_id>10000100</mch_id>
<nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
<notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url>
<openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
<out_trade_no>1415659990</out_trade_no>
<spbill_create_ip>14.23.150.211</spbill_create_ip>
<total_fee>1</total_fee>
<trade_type>JSAPI</trade_type>
<sign>0CB01533B8C1EF103065174F50BCA001</sign>
</xml>
然后微信服務(wù)器返回的數(shù)據(jù)也是xml格式的。這個就自己找方法去解析這樣的數(shù)據(jù)。 成功后則返回一下的參數(shù):
返回的參數(shù)了則包含了 prepay_id 也就是支付流程里要我們獲取的一個數(shù)據(jù),其實這個就是預(yù)支付訂單的訂單編號,網(wǎng)頁端就是拿這個訂單編號去支付的。
但是前端要支付也還是要各種加密的。這個是比較惡心的。
現(xiàn)在我們來看前端應(yīng)該怎么寫。
要用微信 的接口,我們首先要做相應(yīng)的權(quán)限配置。 詳情看官方文檔
wx.config({
debug:true,// 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。
appId:'',// 必填,公眾號的唯一標識
timestamp: ,// 必填,生成簽名的時間戳
nonceStr:'',// 必填,生成簽名的隨機串
signature:'',// 必填,簽名,見附錄1
jsApiList: []// 必填,需要使用的JS接口列表,所有JS接口列表見附錄2
});
這里生成signtrue 需要這個頁面的全路徑,不需要帶參數(shù)。這個是需要注意的。
當配置成功后,就可以發(fā)起支付請求了。當使用了支付請求這個接口,是要到微信里去配安全域名的。不然則會失敗。而且測試也是要發(fā)布的這個域名下進行測試。我之前就一直在本地測試,一直不成功,這是我最大的坑。設(shè)置安全域名如下圖:

還要在微信支付里 設(shè)置 支付目錄。

然后就就在前端調(diào)用微信支付請求。
wx.ready(function(res){
$.hideLoading();
WeixinJSBridge.invoke('getBrandWCPayRequest',{
"appId":"${prepay.appId}",//公眾號名稱,由商戶傳入
"timeStamp":"${prepay.timpstamp}",//時間戳,自 1970 年以來的秒數(shù)
"nonceStr":"${prepay.nonceStr}",//隨機串
"package":"prepay_id=${prepay.prepayId}",
"signType":"${prepay.signType}",//微信簽名方式:
"paySign":"${prepay.paySign}"http://微信簽名
},function(res){
console.info(res);
console.debug(res);
if(res.err_msg =="get_brand_wcpay_request:ok") {
}// 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg 將在用戶支付成功后返回 ok,但幵丌保證它絕對可靠。
});
});
paysign 這個簽名生成的方式跟之前預(yù)支付訂單sign 生成的方式是一樣的 參數(shù)是區(qū)分大小寫的。
官方文檔
這樣一個支付就可以了
如果在這方面遇到問題而解決不了的話。歡迎交流。 郵箱xuewenke123@qq.com