热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

微信小程序微信支付+Java后台接口

微信小程序微信支付Java后台接口这块的内容比较复杂。在网上找了很多的文章,发现很多都不是能在我做的这个项目中跑起来。最终借助公司大佬的力量才勉强的把这块的内容完成

微信小程序 微信支付 + Java后台接口

这块的内容比较复杂。在网上找了很多的文章,发现很多都不是能在我做的这个项目中跑起来。最终借助公司大佬的力量才勉强的把这块的内容完成。实属不易。
https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_10&index=1
上面的链接是微信小程序开发文档关于微信支付的内容。建议看3遍以上

在微信支付之前必须要有下面5样材料

小程序的appid,APPsecret,支付商户号(mch_id),商户密钥(key),付款用户的openid
申请接入微信商户地址:https://pay.weixin.qq.com/static/applyment_guide/applyment_detail_miniapp.shtml

接下来就要贴代码了,首先是小程序端的代码:

//支付方法purchaseMember: function purchaseMember() {wx.showLoading({ title: '正在加载', mask: true });var that = this;var index = that.data.currentIndex;var priceInfo = that.data.priceObj;_utils2.default.requestPayment({url: '/webapi/pay/wxPay.json',data: { priceid: priceInfo[index].id },fail: function fail(res) {wx.showToast({ title: '支付取消', icon: 'none' });},success: function success(res) {wx.showToast({ title: '支付成功' });that.setData({ showGetMemberPopup: false });// 查询支付结果,支付成功后刷新用户缓存that.orderQuery();},callback: function callback(resultData) {wx.hideLoading();// that.data.orderno = resultData.ordernothat.data.orderno = resultData.orderno;}});},orderQuery: function orderQuery() {wx.showLoading({ title: '正在加载', mask: true });var that = this;getApp().GET({ url: "/webapi/pay/orderQuery.json",data: { orderno: that.data.orderno },success: function success(res) {wx.hideLoading();if (res.success && res.data.state == 'SUCCESS') {that.refresh();} else {wx.showToast({ title: res.msg, icon: 'none' });}}});},

统一下单的地址:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1
这里面的参数很重要,要好好比对,必要的参数一定要有
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Java后台代码相当多:
1.首先是支付的代码:
在刚支付的时候我们就要在会员权益表中增加这一条数据了,不管是否支付成功,因为支付失败那是回调之后的失败。

/*** 微信内调起支付* * &#64;param request* &#64;param response* &#64;return*/&#64;RequestMapping(value &#61; "/wxPay", method &#61; { RequestMethod.GET, RequestMethod.POST })&#64;ResponseBodypublic Response wxPay(HttpServletRequest request) {// 根据请求中的token来获取缓存中的用户信息Response resp &#61; new Response<>();Member loginUser &#61; MemberManager.getMember(request);if (loginUser &#61;&#61; null) {resp.setCode(CommonReturnCode.ERROR.code());return resp;}//前台传过来的数据String priceid &#61; ServletRequestUtils.getStringParameter(request, "priceid", null);String latitude &#61; ServletRequestUtils.getStringParameter(request, "payLatitude", null);String longitude &#61; ServletRequestUtils.getStringParameter(request, "payLongitude", null);Validator validator &#61; new Validator();// 获取地址情况 地址错误时不保存地址validator.required(latitude, "位置获取失败");validator.required(longitude, "位置获取失败");validator.number(request, "latitude", "位置获取失败");validator.number(request, "longitude", "位置获取失败");ReverseGeocodingResult RGResult &#61; null;if (!validator.isError()) {RGResult &#61; BaiduMapApi.getReverseGeocoding(latitude, longitude);}MemberPrice memberprice &#61; memberPriceService.selectById(priceid);// 判断订单是否存在SimpleDateFormat sdf &#61; new SimpleDateFormat("yyyyMMddHHmmss");String orderNum &#61; "HYQY" &#43; sdf.format(new Date()) &#43; StringRandom.getRandomNum();BigDecimal amount &#61; memberprice.getPrice();//把值塞进会员购买会员的表中MembershipBuyOrder order &#61; new MembershipBuyOrder();order.setMemberid(loginUser.getId());order.setPriceid(priceid);order.setPricename(memberprice.getName());order.setDuration(memberprice.getDuration());order.setTimeunit(Integer.valueOf(memberprice.getTimeunit()));order.setAmount(amount);order.setPaytype(OrderEnums.PayType.MONEY.getValue());order.setOrderno(orderNum);order.setStatus(1);order.setCreatetime(DateUtils.dateTimeToString(new Date()));PaymentLocation plRecord &#61; null;if (RGResult !&#61; null) {plRecord &#61; new PaymentLocation(PaymentLocation.BusinessType.MEMBERSHIP, order.getId(),RGResult.getFormatted_address(), RGResult.getSematic_description(), RGResult.getAddressComponent(),RGResult.getLocation());}//这些必要的数据是我们表中的数据String appid &#61; ApplicationConfigurer.getStringProperty("wxMiniprogramAppID", "");String mch_id &#61; ApplicationConfigurer.getStringProperty("wxMiniprogramAppMchId", "");String webContext &#61; ApplicationConfigurer.getStringProperty("web.context", "");String paternerKey &#61; ApplicationConfigurer.getStringProperty("wxpayAppKey", "");try {// 组织支付参数信息Map paraMap &#61; new HashMap();// 获取请求ip地址String ip &#61; RequestUtil.getRequestIP(request);// 下单成功的回调&#xff08;很重要&#xff09;String notifyUrl &#61; webContext &#43; "/wxpay/callOrder/memberCallback.json";WXPay wxpay &#61; new WXPay(WXMPPayConfigImpl.getInstance(), notifyUrl, true, false);// 拼接统一下单地址参数paraMap.put("openid", loginUser.getXcx_openid());paraMap.put("out_trade_no", orderNum);// 商品的订单号每次要唯一paraMap.put("fee_type", "CNY");// 化元为分&#xff0c;化小为整paraMap.put("total_fee", String.valueOf(amount.multiply(new BigDecimal(100)).longValue()));paraMap.put("mch_id", mch_id);paraMap.put("spbill_create_ip", ip);// 此路径是微信服务器调用支付结果通知路径paraMap.put("trade_type", "JSAPI");paraMap.put("body", "会员权益购买会员");paraMap.put("notify_url", notifyUrl);// 使用 wxpayAppKey 请求体 生成签名Map resultMap &#61; wxpay.unifiedOrder(paraMap);// 发送post请求"统一下单接口"返回预支付id:prepay_idif (!WXPayConstants.SUCCESS.equals(resultMap.get("result_code"))) {return new Response<>(CommonReturnCode.ERROR, "获取失败&#xff0c;请稍后重试");}String prepay_id &#61; resultMap.get("prepay_id");// 预支付idMap payMap &#61; new HashMap();payMap.put("appId", appid);payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp() &#43; "");payMap.put("nonceStr", WXPayUtil.generateNonceStr());payMap.put("signType", "MD5");payMap.put("package", "prepay_id&#61;" &#43; prepay_id);String paySign &#61; WXPayUtil.generateSignature(payMap, paternerKey, SignType.HMACSHA256);payMap.put("paySign", paySign);boolean result &#61; membershipBuyOrderService.insert(order);Map responseResultMap &#61; new HashMap<>();payMap.remove("appId");responseResultMap.put("payData", payMap);responseResultMap.put("orderno", order.getOrderno());if (result) {if (plRecord !&#61; null) {plRecord.setRecordid(order.getId());// 保证订单支付地址的唯一性Wrapper plWrapper &#61; new EntityWrapper<>();plWrapper.eq("recordid", plRecord.getRecordid()).eq("businesstype", plRecord.getBusinesstype());paymentLocationService.delete(plWrapper);paymentLocationService.insert(plRecord);}return new Response<>(responseResultMap);} else {return new Response<>(CommonReturnCode.ERROR, "购买会员失败");}} catch (Exception e) {e.printStackTrace();}return new Response<>(CommonReturnCode.ERROR, "购买会员失败");}

/*** 向指定 URL 发送POST方法的请求* * &#64;param url* 发送请求的 URL* &#64;param param* 请求参数,请求参数应该是 name1&#61;value1&name2&#61;value2 的形式。* &#64;return 所代表远程资源的响应结果*/public static String sendPost(String url, String param) {PrintWriter out &#61; null;BufferedReader in &#61; null;String result &#61; "";try {URL realUrl &#61; new URL(url);// 打开和URL之间的连接URLConnection conn &#61; realUrl.openConnection();// 设置通用的请求属性conn.setRequestProperty("accept", "*/*");conn.setRequestProperty("connection", "Keep-Alive");conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 发送POST请求必须设置如下两行conn.setDoOutput(true);conn.setDoInput(true);// 获取URLConnection对象对应的输出流out &#61; new PrintWriter(conn.getOutputStream());// 发送请求参数out.print(param);// flush输出流的缓冲out.flush();// 定义BufferedReader输入流来读取URL的响应in &#61; new BufferedReader(new InputStreamReader(conn.getInputStream()));String line;while ((line &#61; in.readLine()) !&#61; null) {result &#43;&#61; line;}} catch (Exception e) {System.out.println("发送 POST 请求出现异常&#xff01;" &#43; e);e.printStackTrace();}// 使用finally块来关闭输出流、输入流finally {try {if (out !&#61; null) {out.close();}if (in !&#61; null) {in.close();}} catch (IOException ex) {ex.printStackTrace();}}return result;}

/*** 微信支付账单查询&#xff1a;该接口不做复杂的业务处理&#xff0c;仅根据商户订单号查询订单情况返回支付结果* * &#64;param request* &#64;param response*/&#64;RequestMapping(value &#61; "/orderQuery", method &#61; { RequestMethod.POST, RequestMethod.GET })&#64;ResponseBodypublic Response orderQuery(HttpServletRequest request, HttpServletResponse response) {String orderno &#61; ServletRequestUtils.getStringParameter(request, "orderno", "");if (StringUtils.isBlank(orderno)) {return new Response<>(CommonReturnCode.ERROR, "订单查询失败");}try {WXPay wxpay &#61; new WXPay(WXMPPayConfigImpl.getInstance());Map data &#61; new HashMap();data.put("out_trade_no", orderno);Map resp &#61; wxpay.orderQuery(data);if (WXPayConstants.SUCCESS.equals(resp.get("result_code"))&& WXPayConstants.SUCCESS.equals(resp.get("return_code"))) {Map resultMap &#61; new HashMap();resultMap.put("state", resp.get("trade_state"));resultMap.put("desc", resp.get("trade_state_desc"));return new Response<>(resultMap);}} catch (Exception e) {e.printStackTrace();}return new Response<>(CommonReturnCode.ERROR, "订单支付失败");}

2.支付回调的方法&#xff08;很重要&#xff09;

/*** 购买会员积分回调* * &#64;param request* &#64;param response* &#64;return*/&#64;RequestMapping(value &#61; "memberCallback", method &#61; { RequestMethod.GET, RequestMethod.POST })&#64;ResponseBodypublic void memberCallback(HttpServletRequest request, HttpServletResponse response) {BufferedReader br &#61; null;String xml &#61; "";try {StringBuilder result &#61; new StringBuilder();br &#61; request.getReader();for (String line; (line &#61; br.readLine()) !&#61; null;) {if (result.length() > 0) {result.append("\n");}result.append(line);}String notifyData &#61; result.toString(); // 支付结果通知的xml格式数据WXPay wxpay &#61; new WXPay(WXMPPayConfigImpl.getInstance());Map notifyMap &#61; WXPayUtil.xmlToMap(notifyData); // 转换成mapif (wxpay.isResponseSignatureValid(notifyMap)) {// 签名正确&#xff0c;处理// 进行处理BigDecimal cash_fee &#61; new BigDecimal(notifyMap.get("cash_fee"));// 根据订单流水号查询会员升级订单Wrapper wrapper &#61; new EntityWrapper<>();wrapper.eq("orderno", notifyMap.get("out_trade_no"));MembershipBuyOrder record &#61; membershipBuyOrderService.selectOne(wrapper);// 比对支付金额是否正确和支付状态if (cash_fee.compareTo(record.getAmount().multiply(new BigDecimal(100))) &#61;&#61; 0&& record.getStatus() &#61;&#61; OrderEnums.Status.TODO.getValue()) {Member member &#61; memberService.selectById(record.getMemberid());//处理复杂的各种表的逻辑if (flag) {xml &#61; "";}}} else {// 签名错误&#xff0c;如果数据里没有sign字段&#xff0c;也认为是签名错误}response.getWriter().write(xml);} catch (Exception e) {e.printStackTrace();} finally {if (br !&#61; null) {try {br.close();} catch (IOException e) {e.printStackTrace();}}}}

再调用的话就可以了 总结就是回调的方法真的非常重要&#xff01;&#xff01;&#xff01;
在这里插入图片描述


推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • PHP中的单例模式与静态变量的区别及使用方法
    本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有