当前位置:   article > 正文

微信支付退款,回调接口_binarywang 退款

binarywang 退款

前期准备

  • Maven依赖

      由于具体是哪个已经分不清了,有些是微信支付要用到的,有些是退款要用到的,有些是解码要用到的。

  1. <dependency>
  2. <groupId>com.github.wxpay</groupId>
  3. <artifactId>wxpay-sdk</artifactId>
  4. <version>0.0.3</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.github.binarywang</groupId>
  8. <artifactId>weixin-java-mp</artifactId>
  9. </dependency>
  10. <dependency>
  11. <groupId>com.github.binarywang</groupId>
  12. <artifactId>weixin-java-common</artifactId>
  13. </dependency>
  14. <dependency>
  15. <groupId>com.github.binarywang</groupId>
  16. <artifactId>weixin-java-pay</artifactId>
  17. </dependency>
  18. <dependency>
  19. <groupId>com.alipay.sdk</groupId>
  20. <artifactId>alipay-sdk-java</artifactId>
  21. <version>4.9.5.ALL</version>
  22. </dependency>
  23. <dependency>
  24. <groupId>com.github.wxpay</groupId>
  25. <artifactId>wxpay-sdk</artifactId>
  26. <version>0.0.3</version>
  27. </dependency>
  28. <dependency>
  29. <groupId>com.github.binarywang</groupId>
  30. <artifactId>weixin-java-pay</artifactId>
  31. <version>3.1.0</version>
  32. </dependency>
  33. <!-- 微信支付sdk -->
  34. <!-- Apache Commons Codec库 -->
  35. <dependency>
  36. <groupId>commons-codec</groupId>
  37. <artifactId>commons-codec</artifactId>
  38. <version>1.15</version>
  39. </dependency>
  •   微信支付工具类

       这个类是配置微信支付的基本信息的如appId,mchId这些,建议用我的,因为后面要用到这个配置类。

       注意:除了一般用到的appid这些东西外,还得去官网申请证书,如apiclient_cert.p12,pem这些。路径配置可以配置本地的地址或者服务器下的地址,按我下面那样子配置就可以。

  1. public class PayConfig implements WXPayConfig{
  2. private byte[] certData;
  3. public PayConfig() throws Exception {
  4. //服务器的路径,按照你自己的来
  5. File file = new File("/usr/local/cert/apiclient_cert.p12");
  6. // 本地测试的路径,按照你自己的来
  7. // File file = new File("D:\\*****\\*****\\*****\\apiclient_cert.p12");
  8. InputStream certStream = new FileInputStream(file);
  9. this.certData = new byte[(int) file.length()];
  10. certStream.read(this.certData);
  11. certStream.close();
  12. }
  13. public String getAppID() {
  14. return "****************";
  15. }
  16. public String getMchID() {
  17. return "********";
  18. }
  19. public String getKey() {
  20. return "************";
  21. }
  22. public InputStream getCertStream() {
  23. ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
  24. return certBis;
  25. }
  26. public int getHttpConnectTimeoutMs() {
  27. return 8000;
  28. }
  29. public int getHttpReadTimeoutMs() {
  30. return 10000;
  31. }
  32. }
  • 解码类

     拿来用就可以 ,是用于解密退款回调返回的信息req_info。第一个decrypt方法是解密手机号的,这里用不到,只是顺便贴一下,要用可以拿去用。

  1. public class AesUtil {
  2. public static String decrypt(String encryptedData, String sessionKey, String iv) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidParameterSpecException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
  3. // 初始化加密库
  4. Security.addProvider(new BouncyCastleProvider());
  5. byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData);
  6. byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKey);
  7. byte[] ivBytes = Base64.getDecoder().decode(iv);
  8. // 构造解密器
  9. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
  10. SecretKeySpec keySpec = new SecretKeySpec(sessionKeyBytes, "AES");
  11. AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
  12. params.init(new IvParameterSpec(ivBytes));
  13. cipher.init(Cipher.DECRYPT_MODE, keySpec, params);
  14. byte[] decryptedDataBytes = cipher.doFinal(encryptedDataBytes);
  15. return new String(decryptedDataBytes, StandardCharsets.UTF_8);
  16. }
  17. public static String aesDecrypt(String secretInfo, String rawKey) throws Exception {
  18. try {
  19. SecretKeySpec key = new SecretKeySpec(DigestUtils.md5Hex(getContentBytes(rawKey, "utf-8")).toLowerCase().getBytes(), "AES");
  20. Security.addProvider(new BouncyCastleProvider());
  21. Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "BC");
  22. cipher.init(Cipher.DECRYPT_MODE, key);
  23. return new String(cipher.doFinal(Base64.getDecoder().decode(secretInfo)),"UTF-8");
  24. } catch (Exception e) {
  25. throw new RuntimeException(e);
  26. }
  27. }
  28. private static byte[] getContentBytes(String content, String charset) {
  29. if (charset == null || "".equals(charset)) {
  30. return content.getBytes();
  31. }
  32. try {
  33. return content.getBytes(charset);
  34. } catch (UnsupportedEncodingException e) {
  35. throw new RuntimeException("MD5签名过程中出现错误" + charset);
  36. }
  37. }
  38. }

退款接口

  @注解按需添加 

  transactionId为微信支付订单号,money表示你要退款的钱,reason表示原因。

  1. @Data
  2. @Accessors(chain = true)
  3. public class ConfirmCancel{
  4. private Long transactionId;
  5. private String money;
  6. private String reason;
  7. }

微信退款以分为单位,不论是总额还是要退款的钱。 (有些字段和微信官方提供的不同,是因为版本不一样,用就行了

  1. @Log
  2. @ApiOperation(value = "退款")
  3. @PostMapping("confirmCancel")
  4. public Object confirmCancel(@RequestBody ConfirmCancel confirmCancel) throws Exception {//serviceOrderId
  5. if (poDto != null){
  6. String transactionId = confirmCancel.getTransactionId();
  7. Double stringMonry = Double.valueOf(confirmCancel.getMoney());
  8. //退款以分为单位,且为int类型,不能有小数点。前端输入的money也得按这个来。如0.01元就得是1分
  9. //totalMoney为总额,你可以从之前支付订单存的数据库里面取,也可以直接从前端传,我这里取的是数据库里的,按你自己的来
  10. Double totalMoney = *****Dto.get******Vo().getTotalMoney()*100;
  11. Integer intToalMoney = totalMoney.intValue();
  12. Double refundMoney = stringMonry*100;
  13. Integer intRefundMoney = refundMoney.intValue();
  14. String url = "https://(填写域名)/(填写回调接口url)"; //如果你需要回调的话
  15. if (stringMonry <= totalMoney) {
  16. PayConfig config = new PayConfig();
  17. WXPay wxpay = new WXPay(config);
  18. String refundNo = String.valueOf(UUID.randomUUID());
  19. Map<String, String> map = new HashMap<>();
  20. map.put("appid", config.getAppID());
  21. map.put("mch_id", config.getMchID());
  22. map.put("refund_desc", confirmCancel.getReason()); //退款原因
  23. map.put("nonce_str", WXPayUtil.generateNonceStr());
  24. map.put("transaction_id", transactionId);
  25. map.put("out_refund_no", refundNo);
  26. map.put("total_fee", intToalMoney + ""); //总价格
  27. map.put("refund_fee", intRefundMoney + ""); //退款价格
  28. map.put("notify_url",url); //回调地址
  29. String sign = WXPayUtil.generateSignature(map, config.getKey());
  30. map.put("sign", sign);
  31. Map<String, String> refund = wxpay.refund(map);
  32. System.out.println(refund); //返回的详情,可以根据这个来看成没成功
  33. String return_code = refund.get("return_code");
  34. String return_msg = refund.get("return_msg");
  35. } else {
  36. return buildFailure("超出原有金额");
  37. }
  38. }
  39. return buildFailure("失败");
  40. }

实现效果        

                                                                 请求参数

 回调接口

    注意:如果使用回调,得先在退款的接口中,设置你的notify_url,这个url为你的回调接口地址

再次提醒,@注解按需求添加。

  1. @Log
  2. @PostMapping("refundNotifyResult")
  3. public Object refundNotifyResult(@RequestBody String xmlData) throws Exception {
  4. System.out.println("进入回调");
  5. //TODO 具体业务处理
  6. logger.info(xmlData); //回调接收到的是xml格式的数据
  7. PayConfig config = new PayConfig();
  8. Map<String, String> xmlMap = WXPayUtil.xmlToMap(xmlData); //转为map格式
  9. System.out.println("xmlMap==>" + xmlMap);
  10. //退款成功后返回一个加密字段req_info,以下为解密
  11. //解密的方法在上述准备工作的AesUtil类里
  12. String req_info = xmlMap.get("req_info");
  13. String resultStr = AesUtil.aesDecrypt(req_info,config.getKey());
  14. Map<String, String> reqInfo = WXPayUtil.xmlToMap(resultStr);
  15. System.out.println("reqInfo===>" + reqInfo);
  16. String out_trade_no = reqInfo.get("out_trade_no");
  17. String return_code = xmlMap.get("return_code");
  18. Map<String,Object> parm = new HashMap<>();
  19. if (StringUtils.isNotBlank(return_code) && StringUtils.equals(return_code, SUCCESS)) {
  20. //你自己的业务操作
  21. *********************************
  22. parm.put("return_code",SUCCESS);
  23. parm.put("req_info",reqInfo);
  24. }
  25. return parm; //返回给前端的参数
  26. }

以下为打印的数据,因为涉及隐私,所以大部分都打码了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/874197
推荐阅读
相关标签
  

闽ICP备14008679号