微信公眾號支付JSAPI 詳細記錄
剛剛除錯通微信公眾號支付,寫個部落格記錄一下。
jsapi必要的幾個引數
微信公眾號的賬戶密碼,微信商戶賬號密碼.
登陸微信公眾號,左下角開發-基本配置,檢視APPID
1、公眾APPID(已經得到)
2、APPSECEPT(已經得到)
進入微信商戶平臺:
https://pay.weixin.qq.com/index.php/partner/public/home
3、微信支付商戶號(獲取到)
API祕鑰在商戶平臺--賬戶中心--API安全裡面,安裝證書後可獲取到API祕鑰
4、API祕鑰(獲取到)
------------------------------------如果拿到四大引數就可以繼續往下看了-------------------------------------------------
二、微信統一下單介面
官方文件地址:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
其中的必填引數
1. appid APPID (已有)
2. mch_id 商戶ID (已有)
3. nonce_str 隨機字串
4. sign 簽名
5. body 所支付的名稱
6. out_trade_no 咱們自己所提供的訂單號,需要唯一
7. total_fee 支付金額
8. spbill_create_ip IP地址
9. notify_url 回撥地址
10. trade_type 支付型別
11. openid 支付人的微信公眾號對應的唯一標識
共有11個引數,兩個已經有,還需要九個引數,我們一個一個來獲取
nonce_str :微信提供的工具類裡面獲得,DEMO下載地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
//獲取隨機字串
String nonce_str = WXPayUtil.generateNonceStr();
sign簽名:我們需要獲得其他十個引數,然後在用工具類來生成(我們後面來做)
body :隨便定義
out_trade_no :隨便定義,唯一即可
total_fee 支付金額
spbill_create_ip 填寫本機區域網地址,不會的在cmd命令裡敲一下ipconfig,回車,得到ip地址
notify_url :支付成功後回撥地址,隨意定義,後面可修改
如果前面的你都搞定了,那麼重點來了 openid,這個引數很難搞。企業號號獲取方式有點區別,企業號請使用【企業號OAuth2.0介面】獲取企業號內成員userid,再呼叫【企業號userid轉openid介面】進行轉換,普通公眾號請往下看:
1、登陸微信公眾號,在公眾號設定--功能設定裡面,新增網頁授權域名
2、記住網頁授權名,用URLEncoder編碼一下
String text1= java.net.URLEncoder.encode("https://www.tes-sys.com","utf-8");
System.out.println(text1);
拿到這種東西:https%3A%2F%2Fwww.tes-sys.com
3、拼接引數
需要修改點appid、redirect_uri。其他都不用變,然後發到你的手機上去吧,在微信瀏覽器中開啟,完成授權
如果進來了你剛輸入的網頁,便是你已經成功了,
4、右上角,複製連結,隨便找個地方複製出來,你會神奇的發現你網址後面跟了引數
https://www.tes-sys.com/?code=011mn0uX0B7GL22xHqtX0ez2uX0mn0u2&state=STATE
我們需要這個code:趕緊記錄下來
011mn0uX0B7GL22xHqtX0ez2uX0mn0u2
5、獲取code後,請求以下連結獲取access_token和openid:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx20ea285ce626dd6f&secret=7883468df98ad41001a9521a2b69c9cc&code=011mn0uX0B7GL22xHqtX0ez2uX0mn0u2&grant_type=authorization_code
需要替換的地方appid、secret、code
在瀏覽器開啟網址,你就能獲取到json字串
折騰這麼久,終於拿到openid,喝個下午茶慶祝一下\(^o^)/~~~~~~
所有引數都已經拿到,就剩下sign簽名了,不急,我們有工具類
首先寫個集合
Map map = new HashMap();
map.put("appid",appid);
map.put("mch_id",mch_id);
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("notify_url",notify_url);
map.put("trade_type",trade_type);
map.put("openid",openid);
//簽名
String sign = WXPayUtil.generateSignature(map, "TesPay20**********ghaiZhenbe");
System.out.println("微信簽名: "+sign);
這個方法裡面前面放map,後面放API祕鑰,拿到微信簽名。記得將sign也放入集合裡面
map.put("sign",sign);
繼續使用工具類,把集合轉化為xml格式的字串
String weChatXML = WXPayUtil.mapToXml(map);
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<sign>DE6698C6AF5315F4F981FB9104BF1943</sign>
<body>測試</body>
<mch_id>1356014002</mch_id>
<spbill_create_ip>192.168.110.124</spbill_create_ip>
<total_fee>1</total_fee>
<notify_url>192.168.110.124:8181/sample/weChat</notify_url>
<appid>wx20e********26dd6f</appid>
<openid>orDFks7S********6CNLnGJpkgnLY</openid>
<out_trade_no>2018013000001</out_trade_no>
<nonce_str>wPo7Ibivx5clIPzInUJipROh0Biwgg8p</nonce_str>
<trade_type>JSAPI</trade_type>
</xml>
傳送post請求,到統一下單介面
String xxxx =HttpClientUtils.ZjsSendPost("https://api.mch.weixin.qq.com/pay/unifiedorder",weChatXML);
如果上述步驟都沒有錯誤的話,你就可以拿到
<package>prepay_id=wx16175508554*****ace6fe0866171705</package>
至此,你已經完成一大半了,還剩下前臺呼叫jsapi程式碼
--------------------------------------------------前臺操作華麗分割線--------------------------------------------------------
前端頁面需要引入微信的js
<script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"></script>
WeixinJSBridge:為微信瀏覽器內建js物件,只有在微信瀏覽器中才有效
if (typeof WeixinJSBridge == "undefined"){
$(document).on('WeixinJSBridgeReady', function() {
//公眾號支付
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":appId, //公眾號名稱,由商戶傳入
"timeStamp":timeStamp, //時間戳,自1970年以來的秒數
"nonceStr":nonceStr, //隨機串
"package":package1,
"signType":signType, //微信簽名方式:
"paySign":paySign //微信簽名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ){
// 使用以上方式判斷前端返回,微信團隊鄭重提示:
//res.err_msg將在使用者支付成功後返回ok,但並不保證它絕對可靠。
}
});
});
}else{
onBridgeReady();
}
上述六個引數是從java端傳過來的
"appId":appId, //公眾號名稱,由商戶傳入 "timeStamp":timeStamp, //時間戳,自1970年以來的秒數 "nonceStr":nonceStr, //隨機串 "package":package1, "signType":signType, //微信簽名方式: "paySign":paySign //微信簽名
在微信瀏覽器裡面開啟H5網頁中執行JS調起支付,文件地址
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
我們需要傳遞的這些引數切勿和之前的弄混。
1、appId(已有)
2、timeStamp,下方給出
String timeStamp = System.currentTimeMillis()/1000+"";
3、nonceStr,
String nonceStr=WXPayUtil.generateNonceStr();
4、package
我們之前獲取到的<package>prepay_id=wx16175508554*****ace6fe0866171705</package>,此時可以用了,注意提交的格式,前面加上prepay_id=
String package1="prepay_id=wx16175508554*****ace6fe0866171705";
5、signType
String signType="MD5";
6、paySign (微信支付簽名,需要我們重新獲取)
獲取方式和之前獲取簽名一樣,新建map集合,將五個引數放進去,拿到簽名之後傳遞到前臺就好了。
//呼叫微信介面,喚起微信支付
String appId="wx20ea285ce626dd6f";
String timeStamp = System.currentTimeMillis()/1000+"";
String nonceStr=WXPayUtil.generateNonceStr();
String package1="prepay_id="+prepay_id;
String signType="MD5";
Map map2 = new HashMap();
map2.put("appId",appId);
map2.put("timeStamp",timeStamp);
map2.put("nonceStr",nonceStr);
map2.put("package",package1);
map2.put("signType",signType);
//第二個引數商戶api祕鑰
String paySign = WXPayUtil.generateSignature(map2, "TesPay201820182018ShanghaiZhenbe");
System.out.println("公眾號支付簽名: "+paySign);
寫到這裡為止,程式碼工作已經完成,我們還有一個授權目錄沒有設定,登陸商戶平臺--產品中心--開發配置--支付授權目錄
新增規則是,我的當前支付頁面是aa.vm,我的訪問路徑是www.xxx.com/sample/code,我是ssm框架,code是我的方法,呼叫次方法返回我的aa.vm頁面,那麼我這裡就應該填寫:www.xxx.com/sample/。