热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

Java开发SSM框架微信退款的实现

这篇文章是Java微信退款的教程,退款之前用户需要先进行支付,支付之后才可以使用退款,非常具有实用价值,感兴趣的小伙伴们可以参考一下

这篇文章是Java微信退款的教程,退款之前用户需要先进行支付,支付之后才可以使用退款。做到退款的同学应该已经是完成了支付了,我写的退款和支付的流程很相似只是所需的参数有所不同。

    String outTradeNo = request.getParameter("outTradeNo");// 获取商户订单号
 
 Integer totalFee = Integer.parseInt(request.getParameter("totalFee"));// 获取支付金额
 
 Map getMap = new HashMap();
 // 获得当前目录
 String path = request.getSession().getServletContext().getRealPath("/");
 
 Date now = new Date();
 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");// 可以方便地修改日期格式
 String outRefundNo = "NO" + dateFormat.format(now);

提供的参数有订单号这个是支付成功之后生成的唯一号码,然后是获取到用户支付的金额这两个参数都是由支付之后的订单上面获得的。下面那个path则是保存微信安全证书文件的位置,这里提一下要实现微信退款和微信企业转账功能是需要到微信商户平台去下载安全证书的,然后把证书放在项目的WEB-INF/目录下即可。

    RefundReqData refundReqData = new RefundReqData();
 refundReqData.setAppid(Configure.getAppID());
 refundReqData.setMch_id(Configure.getMch_id());
 refundReqData.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
 refundReqData.setOut_trade_no(outTradeNo);
 refundReqData.setOut_refund_no(outRefundNo);
 refundReqData.setTotal_fee(totalFee);
 refundReqData.setRefund_fee(refundFee);
 refundReqData.setOp_user_id(Configure.getMch_id());
 refundReqData.setNotify_url("https://weixin.qq.com/notify/");
    String sign = Signature.getSign(refundReqData);// 生成签名
 refundReqData.setSign(sign);

获取到需要的参数之后呢,我在这里使用了一个退款的实体类把这些参数保存到了我的实体类里面方便后面的签名加密。

ArrayList list = new ArrayList();
    @SuppressWarnings("rawtypes")
 Class cls = o.getClass();
    Field[] fields = cls.getDeclaredFields();
    for (Field f : fields) {
      f.setAccessible(true);
      if (f.get(o) != null && f.get(o) != "") {
       String name = f.getName();
       XStreamAlias anno = f.getAnnotation(XStreamAlias.class);
       if(anno != null)
       name = anno.value();
        list.add(name + "=" + f.get(o) + "&");
      }
    }
    int size = list.size();
    String [] arrayToSort = list.toArray(new String[size]);
    Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
    StringBuilder sb = new StringBuilder();
    for(int i = 0; i 

这个是我签名加密的方法,把数据加密之后会成为一个很长的字符串,但是官方提供的退款接口是没办法解析你这个超长字符串的数据的,所以我们要把这个字符串变成官方接口认识的数据格式也就是xml格式。

private static XStream xstream = new XStream(new XppDriver() {
     public HierarchicalStreamWriter createWriter(Writer out) {
       return new PrettyPrintWriter(out) {
         // 对所有xml节点的转换都增加CDATA标记
         boolean cdata = true;
 
         //@SuppressWarnings("unchecked")
         public void startNode(String name, Class clazz) {
           super.startNode(name, clazz);
         }
 
         protected void writeText(QuickWriter writer, String text) {
           if (cdata) {
             writer.write("");
           } else {
             writer.write(text);
           }
         }
       };
     }
   });

这一段代码是我把字符串格式的数据转换成xml格式的方法。再把xml格式的数据保存在一个字符串里面,这个时候我们开始向官方接口发送数据。

 public String httpsRequest(String url, String xmlObj, String path) throws Exception {
 // 加载证书
 initCert(path);
 
 String result = null;
 
 HttpPost httpPost = new HttpPost(url);
 
 // 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
 StringEntity postEntity = new StringEntity(xmlObj, "UTF-8");
 httpPost.addHeader("Content-Type", "text/xml");
 httpPost.setEntity(postEntity);
 
 // 设置请求器的配置
 httpPost.setConfig(requestConfig);
 
 try {
  HttpResponse respOnse= httpClient.execute(httpPost);
 
  HttpEntity entity = response.getEntity();
 
  result = EntityUtils.toString(entity, "UTF-8");
 
 } catch (ConnectionPoolTimeoutException e) {
  e.printStackTrace();
 } catch (ConnectTimeoutException e) {
  e.printStackTrace();
 
 } catch (SocketTimeoutException e) {
  e.printStackTrace();
 
 } catch (Exception e) {
  e.printStackTrace();
 
 } finally {
  httpPost.abort();
 }
 
 return result;
 }

通过Https往API post xml数据。

RefundRequest refundRequest = new RefundRequest();
  String result = refundRequest.httpsRequest("https://api.mch.weixin.qq.com/secapi/pay/refund", info, path);
 
  getMap = MobiMessage.parseXml(new String(result.toString().getBytes(), "utf-8"));
  System.out.println(getMap + "............getMap");
  json.put("return_msg", getMap.get("return_msg"));
  json.put("return_code", getMap.get("return_code"));
  json.put("outTradeNo", outTradeNo);

这一段就是给接口发送数据的代码(官方api接口,xml数据,证书的位置),然后我们接受接口返回的信息通过返回的return_msg和return_code来判断是否退款成功。

好了,微信退款就是这样完全可以照着代码把流程读出来很清晰明了也很简单,代码能力稍强的都看得懂,我主要是给大家提供一个思路。如果有同学没看懂也没关系下面是该项目的源码地址大家可以去下载退款的源代码都在里面:wechat_jb51.rar

PS:总结一下我在做微信退款的时候遇到的问题:
1.遇到了一个"Keystore password was incorrect"这个问题,原因这个退款所需要的证书不正确,这个证书是需要从微信平台去下载这个证书;
2.一定要注意在支付时的订单号码和退款时的订单号码是一致的,我碰到的这个问题是在支付时,把订单号码和微信返回的交易号码存数据库时弄反了,导致微信找不到这笔订单;
3.另外碰到的问题是退款在获取证书的时候,证书的路径不对,导致没有获取到证书,所以退款失败,所以还要检查证书是否存在,证书的路径是否正确,还要留意服务器上能否获取到证书。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 在Kubernetes上部署JupyterHub的步骤和实验依赖
    本文介绍了在Kubernetes上部署JupyterHub的步骤和实验所需的依赖,包括安装Docker和K8s,使用kubeadm进行安装,以及更新下载的镜像等。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
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社区 版权所有