今天剛將小程序的支付調通,和大家分享下(坑)
源碼下載:https://pan.baidu.com/s/1skQiXPz
包括小程序端、java服務器端
和其他方式的微信支付方式區別不大,也都需要經過統一下單、支付結果通知(回調),具體流程如下:
1、小程序內調用登錄接口,獲取到用戶的openid,api參見公共api【小程序登錄API】
2、商戶server調用支付統一下單,api參見公共api【統一下單API】
3、商戶server調用再次簽名,api參見公共api【再次簽名】
4、商戶server接收支付通知,api參見公共api【支付結果通知API】
5、商戶server查詢支付結果,api參見公共api【查詢訂單API】
下面結合源碼詳解下流程:
第一步: 獲取客戶的openid
統一下單中需要用到openid
小程序:
首先需要調用微信登錄接口獲取用戶的code:
1.
var that =
this
;
2.
wx.login({
3.
success: function(res) {
4.
that.getOpenId(res.code);
5.
}
6.
});
通過code獲取openid:
01.
//獲取openid
02.
getOpenId: function(code){
03.
var that =
this
;
04.
wx.request({
05.
url:
'https://www.see-source.com/weixinpay/GetOpenId'
,
06.
method:
'POST'
,
07.
header: {
08.
'content-type'
:
'application/x-www-form-urlencoded'
09.
},
10.
data: {
'code'
:code},
11.
success: function(res) {
12.
var openId = res.data.openid;
13.
that.xiadan(openId);
14.
}
15.
})
16.
}
java:
1.
String code = request.getParameter(
"code"
);
2.
HttpGet httpGet =
new
HttpGet(
"https://api.weixin.qq.com/sns/jscode2session?appid="
+Configure.getAppID()+
"&secret="
+Configure.getSecret()+
"&js_code="
+code+
"&grant_type=authorization_code"
);
3.
//設置請求器的配置
4.
HttpClient httpClient = HttpClients.createDefault();
5.
HttpResponse res = httpClient.execute(httpGet);
6.
HttpEntity entity = res.getEntity();
7.
String result = EntityUtils.toString(entity,
"UTF-8"
);
8.
response.getWriter().append(result);
第二步:統一下單
調用微信的統一下單接口,返回預訂單id(prepay_id)
小程序:
01.
var that =
this
;
02.
wx.request({
03.
url:
'https://www.see-source.com/weixinpay/xiadan'
,
04.
method:
'POST'
,
05.
header: {
06.
'content-type'
:
'application/x-www-form-urlencoded'
07.
},
08.
data: {
'openid'
:openId},
09.
success: function(res) {
10.
var prepay_id = res.data.prepay_id;
11.
console.log(
"統一下單返回 prepay_id:"
+prepay_id);
12.
that.sign(prepay_id);
13.
}
14.
})
java:
01.
String openid = request.getParameter(
"openid"
);
02.
OrderInfo order =
new
OrderInfo();
03.
order.setAppid(Configure.getAppID());
04.
order.setMch_id(Configure.getMch_id());
05.
order.setNonce_str(RandomStringGenerator.getRandomStringByLength(
32
));
06.
order.setBody(
"dfdfdf"
);
07.
order.setOut_trade_no(RandomStringGenerator.getRandomStringByLength(
32
));
08.
order.setTotal_fee(
10
);
09.
order.setSpbill_create_ip(
"123.57.218.54"
);
10.
order.setNotify_url(
"https://www.see-source.com/weixinpay/PayResult"
);
11.
order.setTrade_type(
"JSAPI"
);
12.
order.setOpenid(openid);
13.
order.setSign_type(
"MD5"
);
14.
//生成簽名
15.
String sign = Signature.getSign(order);
16.
order.setSign(sign);
17.
18.
String result = HttpRequest.sendPost(
"https://api.mch.weixin.qq.com/pay/unifiedorder"
, order);
19.
System.out.println(result);
20.
L.info(
"---------下單返回:"
+result);
21.
XStream xStream =
new
XStream();
22.
xStream.alias(
"xml"
, OrderReturnInfo.
class
);
23.
24.
OrderReturnInfo returnInfo = (OrderReturnInfo)xStream.fromXML(result);
25.
JSONObject json =
new
JSONObject();
26.
json.put(
"prepay_id"
, returnInfo.getPrepay_id());
27.
response.getWriter().append(json.toJSONString());
Notify_url 是支付完成后就收微信的通知的,告訴你用戶是否付款了
注意:Total_fee單位是分,必須是整數,不能是小數
Trade_type字段對于小程序來說固定寫成JSAPI
第三步:再次簽名
這是小程序的不同之處,要求對拿到的repay_id進行再次簽名。
注意這里有坑了:package字段的值是個鍵值對,格式prepay_id=12312333333333333
小程序:
01.
var that =
this
;
02.
wx.request({
03.
url:
'https://www.see-source.com/weixinpay/sign'
,
04.
method:
'POST'
,
05.
header: {
06.
'content-type'
:
'application/x-www-form-urlencoded'
07.
},
08.
data: {
'repay_id'
:prepay_id},
09.
success: function(res) {
10.
that.requestPayment(res.data);
11.
12.
}
13.
})
java:
01.
String repay_id = request.getParameter(
"repay_id"
);
02.
SignInfo signInfo =
new
SignInfo();
03.
signInfo.setAppId(Configure.getAppID());
04.
long
time = System.currentTimeMillis()/
1000
;
05.
signInfo.setTimeStamp(String.valueOf(time));
06.
signInfo.setNonceStr(RandomStringGenerator.getRandomStringByLength(
32
));
07.
signInfo.setRepay_id(
"prepay_id="
+repay_id);
08.
signInfo.setSignType(
"MD5"
);
09.
//生成簽名
10.
String sign = Signature.getSign(signInfo);
11.
12.
JSONObject json =
new
JSONObject();
13.
json.put(
"timeStamp"
, signInfo.getTimeStamp());
14.
json.put(
"nonceStr"
, signInfo.getNonceStr());
15.
json.put(
"package"
, signInfo.getRepay_id());
16.
json.put(
"signType"
, signInfo.getSignType());
17.
json.put(
"paySign"
, sign);
18.
L.info(
"-------再簽名:"
+json.toJSONString());
19.
response.getWriter().append(json.toJSONString());
第四步:調起支付
最后一步調起小程序支付api
01.
wx.requestPayment({
02.
'timeStamp'
: obj.timeStamp,
03.
'nonceStr'
: obj.nonceStr,
04.
'package'
: obj.
package
,
05.
'signType'
: obj.signType,
06.
'paySign'
: obj.paySign,
07.
'success'
:function(res){
08.
},
09.
'fail'
:function(res){
10.
}
11.
})
之后就等著用戶去輸入支付密碼完成支付了
還有個接口是查詢訂單,這個不是必須的,你根據需要使用