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

feature.jpg

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


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

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


还有个接口是查询订单,这个不是必须的,你根据需要使用

  • 9
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值