您的位置:首页 > 移动开发 > 微信开发

小程序支付详解+源码(客户端+服务端)

2017-02-11 12:15 183 查看


今天刚将小程序的支付调通,和大家分享下(坑)

源码下载: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.
})


之后就等着用户去输入支付密码完成支付了

还有个接口是查询订单,这个不是必须的,你根据需要使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: