
今天剛將小程序的支付調(diào)通,和大家分享下(坑)
源碼下載:https://pan.baidu.com/s/1skQiXPz
包括小程序端、java服務(wù)器端
和其他方式的微信支付方式區(qū)別不大,也都需要經(jīng)過統(tǒng)一下單、支付結(jié)果通知(回調(diào)),具體流程如下:
1、小程序內(nèi)調(diào)用登錄接口,獲取到用戶的openid,api參見公共api【小程序登錄API】
2、商戶server調(diào)用支付統(tǒng)一下單,api參見公共api【統(tǒng)一下單API】
3、商戶server調(diào)用再次簽名,api參見公共api【再次簽名】
4、商戶server接收支付通知,api參見公共api【支付結(jié)果通知API】
5、商戶server查詢支付結(jié)果,api參見公共api【查詢訂單API】
下面結(jié)合源碼詳解下流程:
第一步: 獲取客戶的openid
統(tǒng)一下單中需要用到openid
小程序:
首先需要調(diào)用微信登錄接口獲取用戶的code:
1.var that = this;2.wx.login({3.success: function(res) {4.that.getOpenId(res.code);5.}6.});
通過code獲取openid:
01.//獲取openid02.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.//設(shè)置請求器的配置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);
第二步:統(tǒng)一下單
調(diào)用微信的統(tǒng)一下單接口,返回預(yù)訂單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("統(tǒng)一下單返回 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單位是分,必須是整數(shù),不能是小數(shù)
Trade_type字段對于小程序來說固定寫成JSAPI
第三步:再次簽名
這是小程序的不同之處,要求對拿到的repay_id進(jìn)行再次簽名。
注意這里有坑了:package字段的值是個(gè)鍵值對,格式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());
第四步:調(diào)起支付
最后一步調(diào)起小程序支付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.})之后就等著用戶去輸入支付密碼完成支付了
還有個(gè)接口是查詢訂單,這個(gè)不是必須的,你根據(jù)需要使用