Java开发SSM框架微信退款

这篇教程详细介绍了如何使用Java和SSM框架进行微信退款操作。在退款前需确保用户已完成支付。退款过程中涉及的关键步骤包括:使用订单号和支付金额作为参数,保存并使用微信安全证书,数据签名加密并转化为XML格式,最后通过HTTPS向微信API发送XML数据并接收退款状态反馈。提供完整的源代码下载链接以供参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

        String outTradeNo = request.getParameter("outTradeNo");// 获取商户订单号

		Integer totalFee = Integer.parseInt(request.getParameter("totalFee"));// 获取支付金额

		Map<String, String> getMap = new HashMap<String, String>();
		// 获得当前目录
		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<String> list = new ArrayList<String>();
        @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 < size; i ++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + Configure.getKey();
        System.out.println("签名数据:"+result);
        result = MD5Util.MD5Encode(result,"utf-8").toUpperCase();
        return result;

这个是我签名加密的方法,把数据加密之后会成为一个很长的字符串,但是官方提供的退款接口是没办法解析你这个超长字符串的数据的,所以我们要把这个字符串变成官方接口认识的数据格式也就是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("<![CDATA[");
	                        writer.write(text);
	                        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来判断是否退款成功。

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

大家有任何的疑问建议欢迎在博客下方评论留言,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值