java實現微信H5支付
前面做了app微信支付的回調處理,現在需要做微信公眾號的支付,花了一天多時間,終於折騰出來了!鑒於坑爹的微信官方沒有提供Java版的demo,所以全靠自己按照同樣坑爹的文檔敲敲敲,所以記錄下來,以供自己及後來人參考,不足之處,還請指正。
首先,我們貼出調用支付介面的H5頁面,當然,在這個頁面之前,還需要做很多其他的操作,我們一步一步的來。
pageEncoding="UTF-8"%>
DOCTYPE html>
微信網頁支付
/*wx.config({
debug: true, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會列印。
appId: appid, // 必填,公眾號的唯一標識
timestamp: timestamp, // 必填,生成簽名的時間戳
nonceStr: nonceStr, // 必填,生成簽名的隨機串
signature: ,// 必填,簽名,見附錄1
jsApiList: [chooseWXPay] // 必填,需要使用的JS介面列表,所有JS介面列表見附錄2
});*/
//config信息驗證後會執行ready方法,所有介面調用都必須在config介面獲得結果之後,config是一個客戶端的非同步操作
//所以如果需要在頁面載入時就調用相關介面,則須把相關介面放在ready函數中調用來確保正確執行
//wx.ready(function(){
//參數是後台傳過來的,簽名加密,隨機數,時間戳等全部後台處理好
varappId="$";
vartimeStamp="$";
varnonceStr="$";
varprepay_id="$";//之前參數名叫package,對應api介面,因為package是關鍵字,被坑了一次
varsign="$";
//支付介面
functiononBridgeReady(){
WeixinJSBridge.invoke(
getBrandWCPayRequest ,{
"appId": appId,//公眾號名稱,由商戶傳入
"timeStamp": timeStamp,//時間戳,自1970年以來的秒數 (java需要處理成10位才行,又一坑)
"nonceStr": nonceStr,//隨機串
"package": prepay_id,//拼裝好的預支付標示
"signType":"MD5",//微信簽名方式
"paySign": sign//微信簽名
},
function(res){
//使用以下方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功後返回 ok,但並不保證它絕對可靠。
if(res.err_msg=="get_brand_wcpay_request:ok"){
alert("支付成功");
}else{
alert("支付失敗");
}
}
);
}
if(typeof(WeixinJSBridge)=="undefined"){
if( document.addEventListener ){
document.addEventListener( WeixinJSBridgeReady , onBridgeReady,false);
}elseif(document.attachEvent){
document.attachEvent( WeixinJSBridgeReady , onBridgeReady);
document.attachEvent( onWeixinJSBridgeReady , onBridgeReady);
}
}else{
onBridgeReady();
}
//});
//究竟哪個是支付介面
/*wx.chooseWXPay({
timestamp: timestamp, // 支付簽名時間戳,注意微信jssdk中的所有使用timestamp欄位均為小寫。但最新版的支付後台生成簽名使用的timeStamp欄位名需大寫其中的S字元
nonceStr: nonceStr, // 支付簽名隨機串,不長於 32 位
package: prepay_id , // 統一支付介面返回的prepay_id參數值,提交格式如:prepay_id=***)
signType: MD5 , // 簽名方式,默認為 SHA1 ,使用新版支付需傳入"MD5
paySign: sign, // 支付簽名
success: function (res) {
// 支付成功後的回調函數
//使用以下方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功後返回 ok,但並不保證它絕對可靠。
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
}
}
});*/
上面h5頁面中,支付介面所需的參數都是由後台傳過來的,除此之外,在進行上面一步之前,我們還需要獲取一個預支付標識,下面貼上後台傳參,及獲取預支付標識和參數加密等方法(獲取預支付標識之前需要網頁授權獲取用戶openid,鑒於這個比較簡單,所以不貼代碼了)
首先是後台參數封裝並對其簽名(關鍵部分代碼):
if(payway.equals("1")){
System.out.println("----------支付寶支付-------------");
request.setAttribute("WIDout_trade_no", WIDout_trade_no);//訂單號
request.setAttribute("WIDsubject", WIDsubject);//訂單名稱
request.setAttribute("WIDtotal_fee", WIDtotal_fee);//付款金額
request.setAttribute("WIDshow_url", WIDshow_url);//商品鏈接
request.setAttribute("WIDbody", "");//商品描述,可空
return"alipayapi";
}elseif(payway.equals("2")){
System.out.println("----------微信支付-------------");
//1、通過網頁授權介面,獲取到的openid
String openid=request.getSession().getAttribute("openid")+"";
//處理價格單位為:分(請自行處理)
WIDtotal_fee="1";
String preid=getPrepayid(WIDout_trade_no, WIDtotal_fee, openid);//獲取預支付標示
System.out.println("預支付標示:----------------"+preid);
//APPID
String appId=Common.appid;
request.setAttribute("appId", appId);
//時間戳
String timeStamp=(System.currentTimeMillis()/1000)+"";
request.setAttribute("timeStamp", timeStamp);
//隨機字元串
String nonceStr=Common.randString(16).toString();
request.setAttribute("nonceStr", nonceStr);
//預支付標識
request.setAttribute("prepay_id", "prepay_id="+preid);
//加密方式
request.setAttribute("signType", "MD5");
//組裝map用於生成sign
Map map=newHashMap();
map.put("appId", appId);
map.put("timeStamp", timeStamp);
map.put("nonceStr", nonceStr);
map.put("package", "prepay_id="+preid);
map.put("signType", "MD5");
request.setAttribute("paySign", Common.sign(map, Common.MchSecret));//簽名
return"weixinpay";
}else{
return"error";
}
接下是獲取預支付標識的方法getPrepayid:
/**
* 微信統一下單介面,獲取預支付標示prepay_id
*@paramout_trade_no1 商戶訂單號
*@paramtotal_fee1 訂單金額(單位:分)
*@paramopenid1 網頁授權取到的openid
*@return
*/
@ResponseBody
publicString getPrepayid(String out_trade_no1,String total_fee1,String openid1){
String result = "";
String appid = Common.appid;
String mch_id = Common.mch_id;
String nonce_str = Common.randString(16);//生成隨機數,可直接用系統提供的方法
String body = "E光學-商品訂單";
String out_trade_no = out_trade_no1;
String total_fee = total_fee1;
String spbill_create_ip = "xxx.xxx.38.47";//用戶端ip,這裡隨意輸入的
String notify_url = "網頁鏈接//支付回調地址
String trade_type = "JSAPI";
String openid = openid1;
HashMap map =newHashMap();
map.put("appid", appid);
map.put("mch_id", mch_id);
map.put("attach", "支付測試");
map.put("device_info", "WEB");
map.put("nonce_str", nonce_str);
map.put("body", body);
map.put("out_trade_no", out_trade_no);
map.put("total_fee", total_fee);
map.put("spbill_create_ip", spbill_create_ip);
map.put("trade_type", trade_type);
map.put("notify_url", notify_url);
map.put("openid", openid);
String sign = Common.sign(map, Common.MchSecret);//參數加密
System.out.println("sign秘鑰:-----------"+sign);
map.put("sign", sign);
//組裝xml(wx就這麼變態,非得加點xml在裡面)
String content=Common.MapToXml(map);
//System.out.println(content);
String PostResult=HttpClient.HttpsPost("網頁鏈接);
JSONObject jsonObject=XmlUtil.XmlToJson(PostResult);//返回的的結果
if(jsonObject.getString("return_code").equals("SUCCESS")&&jsonObject.getString("result_code").equals("SUCCESS")){
result=jsonObject.get("prepay_id")+"";//這就是預支付id
}
returnresult;
}
接下是簽名的方法(MD5加密是調用微信一個jar裡面的,你也可以自己寫一個,網上很多參考):
Map轉XML的方法:
![](https://pic.pimg.tw/zzuyanan/1488615166-1259157397.png)
![](https://pic.pimg.tw/zzuyanan/1482887990-2595557020.jpg)
※SpringMVC從入門到精通第七章
※web前端開發學習誤區及 正確學方法
※Java編程語言基礎知識的 要點
※Java-資料庫連接池的選擇 Druid
TAG:java學習吧 |
※增強支付解決能力,PayPal 4億美元收購團體付款平台Hyperwallet
※微軟支付支持Masterpass,Imec發布混合Fin-FET硅光子技術
※華為20款手機支持NFC支付 Huawei Pay支持73家銀行
※eBay將在4月開始支持Google Pay支付
※加量不加價!Garmin vivoactive3 music音樂支付智能腕錶評測
※Endo Teva Teikoku共同支付2.7億美元以圓滿解決 Lidoderm付費延遲訴訟
※Apple Pay 將支持 NFC 支付標籤
※Pentagram為加密貨幣支付平台 Wirex 設計新LOGO
※加拿大支付技術公司Nuvei斥資8.89億美元,現金收購英國同行SafeCharge
※跨境電商實現無縫支付!Magento整合Braintree 、PayPal……
※Snapchat下架P2P支付工具Snapcash
※Google Pay推出更新:支持P2P支付和卡券功能
※Google Pay支持綁定Paypal賬戶 可在Gmail等應用中直接使用Paypal支付
※Google Pay支持購票和登機牌 還有P2P支付
※業務版圖再次擴大,Paysafe收購美國支付服務商iPayment
※Payomat加密貨幣支付平台:白帽黑客Hacken將保護Payomat的加密貨幣支付系統
※Apple Pay 終於可以支付 iTunes、App Store 中的內容了
※終於等到你,華為mate20 pro終實現面容支付
※哈希日報:支付服務公司Circle將以4億美元收購P網;Bitcoin Core 0.16.0版本正式發布全面支持segwit
※Francisco Partners財團34億美元收購商務支付供應商Verifone