微信退款功能实现

微信退款功能实现

最近做了一个微信退款的功能,遇到了一些坑。网上也找了很多资料,但是发现大多都是微信支付这一块的东西,关于微信退款的很少,所以自己来写一份记录一下。好了,话不多说,我们直接进入主题:

相信大家都看微信支付的官方文档了,微信退款和其他的API接口不一样,它需要认证证书

在这里插入图片描述

我们需要去微信商户平台下载证书,怎么下载我这里就不做叙述了。直接给大家看一下下载之后的文件。

在这里插入图片描述

下载文件之后,我们就需要携带证书发送HTTPS请求微信的API接口了,直接上代码了。

1.把下载好的证书文件放进项目中,或者你的服务器上。我这里是放在项目里的resource文件夹下面。

在这里插入图片描述

2.代码中绑定此证书。
private static CloseableHttpClient noSslHttpClient(String mchId) throws KeyManagementException,
			NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException {
		KeyStore keyStore = KeyStore.getInstance("PKCS12");
		ClassPathResource resource = new ClassPathResource("crt/apiclient_cert.p12");
		
		// 如果你的文件是放在服务器上面可以使用下面的方法
		// 直接写你的服务器文件路径就可以,可能需要注意你服务器文件的访问权限,以避免读取不到文件
		// FileInputStream stream = IoUtil.toStream(new File("/home/crt/apiclient_cert.p12"));
		// keyStore.load(stream, mchId.toCharArray());
		
		// 这里的证书密码默认为微信分配的 商户号
		keyStore.load(resource.getInputStream(), mchId.toCharArray());
		
		// 这里需要注意的一点是,这里调用的loadKeyMaterial方法依旧是传入密码的那个方法,密码还是微信分配的 商户号
		final SSLContext sslContext = new SSLContextBuilder().loadKeyMaterial(keyStore, mchId.toCharArray()).build();
		
		// 这里就算是返回一个已经绑定好正式的CloseableHttpClient对象了
		return HttpClientBuilder.create().setSSLContext(sslContext)
				.setConnectionManager(new PoolingHttpClientConnectionManager(RegistryBuilder
						.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE)
						.register("https", new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE))
						.build()))
				.build();
	}
3.请求微信退款API
Executor executor = null;
		try {
		// 这里调用上面的方法:noSslHttpClient
			executor = Executor.newInstance(noSslHttpClient(wxMchId));
		} catch (CertificateException | UnrecoverableKeyException e1) {
			e1.printStackTrace();
			logger.info("微信证书异常");
			return ResponseData.fail("微信支付退款申请失败");
		}

// 这里是请求对象,就是微信退款API需要的一些参数,请求的格式等,我这里就不做叙述了。微信文档中描述的很清楚
Request request = Request.Post(wxRefundUrl).addHeader("Content-Type", ContentType.APPLICATION_XML.getMimeType())
				.bodyString(XMLUtil.toXml(wxRefundRequestBean, WxRefundRequestBean.class),
						ContentType.create(ContentType.APPLICATION_XML.getMimeType(), "UTF-8"));

		String postResult = null;
		try {
		// 这里发送请求,得到微信的返回值,值得注意的是微信退款的异步回调通知中返回的数据是加密过得
			postResult = executor.execute(request).returnContent().asString();
		} catch (IOException e) {
			logger.error("微信支付退款申请失败:{}", e.getMessage());
			e.printStackTrace();
			return ResponseData.fail("微信支付退款申请失败");
		}
		logger.info(">>>>>>>>>>>>微信申请退款结果返回:{}", postResult);
4.到此微信退款的功能就完毕了,这里主要写的就是证书绑定这一块,其他部分都省略了,望大家谅解。当然,值得注意的是微信退款的异步回调通知中返回的数据是加密过得:

在这里插入图片描述
这里我也贴一下解密的代码吧,相对还是比较简单的

public static String decryptData(String base64Data) throws Exception {
		// 这里的 base64Data 为上图中 req_info 的值
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING, "BC");
        // 这里的 paySign 为微信分配的秘钥key,做微信支付的相信大家都知道
        String key = new SecretKeySpec(MD5Util.MD5Encode(paySign, "UTF-8").toLowerCase().getBytes(), ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return new String(cipher.doFinal(Base64Util.decode(base64Data)));
    }

到这来就全部结束了,希望能给碰到这块问题的人带来一点帮助。

转载请注明出处,谢谢了。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值