欢迎来到258分享网,纯净的网络源码分享基地!

258资源分享网

全部作品
全部作品
网站源码
微信源码
素材特效
源码插件
视频教程
建站学院
热门搜索: 织梦  农业种植  农业  安全设置  官方
258资源分享 > 建站学院 > 微信开发 > 玩转小程序支付之付款(统一下单)

推荐下载

HTML5响应式自适应网咯设计

2020-05-12   浏览:740

高端HTML5响应式企业通用网

2020-05-06   浏览:521

html5响应式外贸网站英文版

2020-05-08   浏览:510

HTML5自适应律师工作室类网

2020-04-04   浏览:504

HTML5影视传媒文化公司类网

2020-05-12   浏览:500

玩转小程序支付之付款(统一下单)

发布时间:2021-01-01  

小程序的业务流程如下

玩转小程序支付之付款(统一下单)

商户系统和微信支付系统主要交互说明:

步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。

步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。参见【统一下单API】。

步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appid,partnerid,prepayid,noncestr,timestamp,package。注意:package的值格式为Sign=WXPay

步骤4:商户APP调起微信支付。api参见本章节【app端开发步骤说明】

步骤5:商户后台接收支付通知。api参见【支付结果通知API】

步骤6:商户后台查询支付结果。,api参见【查询订单API】

API链接:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3

支付的流程为:先调用统一下单API---->接着在小程序wx.requestPayment发起支付---->支付完之后会调用支付结果通知

小程序端代码

玩转小程序支付之付款(统一下单)

/** * 支付 */ var pay = function (event, that) { if (that.data.detail.fee.indexOf("免费")>-1){ goApply(event, that) }else{ wx.request({ url: app.globalData.server + 'requestPay/', method: "POST", data: { activityId: event.currentTarget.dataset.activityid, userId: app.globalData.userInfo.id, sessionThirdKey: wx.getStorageSync('sessionThirdKey'), money: that.data.detail.fee, describe: that.data.detail.name, detail: '报名活动费用' }, header: { "Content-Type": "application/x-www-form-urlencoded" }, success: function (res) { console.info(res); //发起微信支付 wx.requestPayment({ 'timeStamp': res.data.timeStamp, 'nonceStr': res.data.nonceStr, 'package': res.data.package_, 'signType': 'MD5', 'paySign': res.data.paySign, success: function (res) { console.info(res) //报名 goApply(event, that) }, fail: function (res) { console.info(res) }, complete: function (res) { console.info(res) } }) } }) } }

后台Java代码:(基于SpringBoot)

@RestController public class PayApi { @Value("${wxapp.appid}") private String appId; @Value("${wxapp.secret}") private String secret; @Value("${wxapp.url.jscode2session}") private String jscode2session; @Value("${wx.mch.id}") private String mchId; @Value("${wx.unified.order.url}") private String createOrderURL; @Value("${wx.pay.api.key}") private String key; @Value("${wx.bill.create.ip}") private String spBillCreateIp; @Value("${wx.server.url}") private String baseUrl; @Autowired private RedisClient redisClient; @Resource(name = "wxappUserServiceImpl") private IWxappUserService wxappUserService; @Resource(name = "wxappActivityServiceImpl") private IWxappActivityService wxappActivityService; @Resource(name = "wxappActivityApplyServiceImpl") private IWxappActivityApplyService wxappActivityApplyService; @Resource(name = "wxappPayServiceImpl") private IWxappPayService wxappPayService; @RequestMapping(value = "/requestPay",method = RequestMethod.POST) public WxappPayDto requestPay(String userId, String activityId, String sessionThirdKey, String money, String describe, String detail) throws Exception { WxappPayDto dto = new WxappPayDto(); //获取保存的sessionThirdKey(里面保存了openId) String sessionKey = redisClient.get(sessionThirdKey); String openId = sessionKey.split("w#w#w")[0]; //订单号 String orderNo="wx"+userId+"_"+System.currentTimeMillis(); dto = prePay(userId,activityId,openId,orderNo,money,describe,detail); return dto; } /** * 统一下单 * @param userId * @param activityId * @param openId * @param orderNo * @param money * @param describe * @param detail * @return */ private WxappPayDto prePay(String userId,String activityId,String openId,String orderNo,String money,String describe,String detail){ money = String.valueOf(Long.valueOf(money.substring(0, money.length()-1))*100); String currTime = PayUtils.getCurrTime(); //8位日期 String strTime = currTime.substring(8, currTime.length()); //四位随机数 String strRandom = PayUtils.buildRandom(4) + ""; //10位序列号,可以自行调整。 String nonceStr = strTime + strRandom; //这里notify_url是 支付完成后微信发给该链接信息,可以判断会员是否支付成功,改变订单状态等。 String notifyUrl = baseUrl+"/notify"; //附加数据,以一定格式保存userId和activityId。原样返回。 String attach = userId+"#wx#"+activityId; SortedMap<String, String> packageParams = new TreeMap<String, String>(); packageParams.put("appid", appId); packageParams.put("attach", attach);//附加数据 packageParams.put("body", describe);//商品描述 packageParams.put("detail", detail); packageParams.put("mch_id", mchId);//商户号 packageParams.put("nonce_str", nonceStr);//随机数 packageParams.put("notify_url", notifyUrl); packageParams.put("openid", openId); packageParams.put("out_trade_no", orderNo);//商户订单号 packageParams.put("spbill_create_ip", spBillCreateIp);//订单生成的机器 IP packageParams.put("total_fee", money);//总金额 packageParams.put("trade_type", "JSAPI"); String sign = PayUtils.createSign(packageParams,key); String xml="<xml>"+ "<appid>"+appId+"</appid>"+ "<attach>"+attach+"</attach>"+ "<body><![CDATA["+describe+"]]></body>"+ "<detail><![CDATA["+detail+"]]></detail>"+ "<mch_id>"+mchId+"</mch_id>"+ "<nonce_str>"+nonceStr+"</nonce_str>"+ "<sign>"+sign+"</sign>"+ "<notify_url>"+notifyUrl+"</notify_url>"+ "<openid>"+openId+"</openid>"+ "<out_trade_no>"+orderNo+"</out_trade_no>"+ "<spbill_create_ip>"+spBillCreateIp+"</spbill_create_ip>"+ "<total_fee>"+money+"</total_fee>"+ "<trade_type>JSAPI</trade_type>"+ "</xml>"; String prepay_id=""; try { prepay_id = PayUtils.getPayNo(createOrderURL, xml); if(prepay_id.equals("")){ //错误提示 System.out.println("统一支付接口获取预支付订单出错"); } } catch (Exception e1) { e1.printStackTrace(); } SortedMap<String, String> finalpackage = new TreeMap<String, String>(); String timestamp = PayUtils.getTimeStamp(); String packages = "prepay_id="+prepay_id; finalpackage.put("appId", appId); finalpackage.put("nonceStr", nonceStr); finalpackage.put("package", packages); finalpackage.put("signType", "MD5"); finalpackage.put("timeStamp", timestamp); String finalsign = PayUtils.createSign(finalpackage,key); WxappPayDto dto = new WxappPayDto(); dto.setNonceStr(nonceStr); dto.setPackage_(packages); dto.setPaySign(finalsign); dto.setSignType("MD5"); dto.setTimeStamp(timestamp); return dto; } /** * 支付完成通知 * @param request * @param response * @return * @throws Exception */ @RequestMapping(value = "/notify",method = RequestMethod.POST) public String notify(HttpServletRequest request, HttpServletResponse response) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream)request.getInputStream())); String line = null; StringBuilder sb = new StringBuilder(); while((line = br.readLine())!=null){ sb.append(line); } //解析并给微信发回收到通知确认 Map map = PayUtils.doXMLParse(sb.toString()); String returnCode = map.get("return_code").toString(); if(returnCode.equals("SUCCESS")){ String resultCode = map.get("result_code").toString(); if(resultCode.equals("SUCCESS")){ SortedMap<String, String> packageParams = new TreeMap<String, String>(); packageParams.put("appid", map.get("appid").toString()); packageParams.put("attach", map.get("attach").toString()); packageParams.put("bank_type", map.get("bank_type").toString()); packageParams.put("cash_fee", map.get("cash_fee").toString()); packageParams.put("fee_type", map.get("fee_type").toString()); packageParams.put("is_subscribe", map.get("is_subscribe").toString()); packageParams.put("mch_id", map.get("mch_id").toString()); packageParams.put("nonce_str", map.get("nonce_str").toString()); packageParams.put("openid", map.get("openid").toString()); packageParams.put("out_trade_no", map.get("out_trade_no").toString()); packageParams.put("result_code", map.get("result_code").toString()); packageParams.put("return_code", map.get("return_code").toString()); packageParams.put("time_end", map.get("time_end").toString()); packageParams.put("total_fee", map.get("total_fee").toString()); packageParams.put("trade_type", map.get("trade_type").toString()); packageParams.put("transaction_id", map.get("transaction_id").toString()); String sign = PayUtils.createSign(packageParams,key); String originSign = map.get("sign").toString(); if(sign.equals(originSign)){ //签名一致,保存支付流水 String xml="<xml>" +"<return_code>SUCCESS</return_code>" +"<return_msg>OK</return_msg>" +"</xml>"; ShopPayLog payLog = new ShopPayLog(); payLog.setCreatedAt(new Date()); payLog.setSource(Source.WeiXin); DecimalFormat df = new DecimalFormat("######0.00"); payLog.setTotalFee(String.valueOf(df.format((Double.valueOf(map.get("total_fee").toString())/100)))); payLog.setTradeNo(map.get("out_trade_no").toString()); payLog.setTransactionId(map.get("transaction_id").toString()); String attach = map.get("attach").toString();//userId+"#wx#"+activityId payLog.setUserId(attach.split("#wx#")[0]); payLog = wxappPayService.save(payLog); WxappUser user = wxappUserService.find(Long.valueOf(attach.split("#wx#")[0])); WxappActivity activity = wxappActivityService.find(Long.valueOf(attach.split("#wx#")[1])); WxappActivityApply activityApply = wxappActivityApplyService.findActivityApplyByUserAndActivity(user, activity); //在活动申请表中关联上支付流水的id activityApply.setPayLogId(String.valueOf(payLog.getId())); wxappActivityApplyService.save(activityApply); return xml; }else{ String xml="<xml>" +"<return_code>FAIL</return_code>" +"<return_msg>签名不一致</return_msg>" +"</xml>"; return xml; } }else{ String xml="<xml>" +"<return_code>FAIL</return_code>" +"<return_msg>支付通知失败</return_msg>" +"</xml>"; return xml; } } else { String xml="<xml>" +"<return_code>FAIL</return_code>" +"<return_msg>支付通知失败</return_msg>" +"</xml>"; return xml; } }

PayUtils.java