From cda724da35beb1ffd84955cc42bda5ab399ebbe1 Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期三, 09 四月 2025 18:27:38 +0800
Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/JiaDianHuiShou

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WxChatPayCallBack.java |  203 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 203 insertions(+), 0 deletions(-)

diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WxChatPayCallBack.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WxChatPayCallBack.java
new file mode 100644
index 0000000..b03e338
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/WxChatPayCallBack.java
@@ -0,0 +1,203 @@
+package com.ruoyi.order.controller;
+
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.core.constant.Constants;
+import com.ruoyi.common.core.constant.WechatConstants;
+import com.ruoyi.common.core.domain.BaseEntity;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.exception.GlobalException;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.core.vo.UserDto;
+import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.ruoyi.order.entity.ChangeDispatch;
+import com.ruoyi.order.entity.Order;
+import com.ruoyi.order.entity.Withdraw;
+import com.ruoyi.order.entity.WithdrawDetail;
+import com.ruoyi.order.request.ChangeDispatchRequest;
+import com.ruoyi.order.service.ChangeDispatchService;
+import com.ruoyi.order.service.OrderService;
+import com.ruoyi.order.service.WithdrawDetailService;
+import com.ruoyi.order.service.WithdrawService;
+import com.ruoyi.order.vx.HttpUtil;
+import com.ruoyi.system.api.RemoteUserService;
+import com.ruoyi.user.api.feignClient.UserClient;
+import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
+import com.wechat.pay.java.core.Config;
+import com.wechat.pay.java.core.RSAAutoCertificateConfig;
+import com.wechat.pay.java.core.notification.NotificationConfig;
+import com.wechat.pay.java.core.notification.NotificationParser;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 商家转账回调
+ * </p>
+ *
+ * @author hjl
+ * @since 2024-05-31
+ */
+@RestController
+@RequestMapping("/wx")
+public class WxChatPayCallBack {
+
+    @Autowired
+    private WithdrawDetailService withdrawDetailService;
+    @Resource
+    private OrderService orderService;
+    @Autowired
+    private WithdrawService withdrawService;
+    @Autowired
+    private UserClient userClient;
+    /**
+     * 微信商户零线转账 - 回调通知
+     * @Context注解  把HTTP请求上下文对象注入进来,HttpServletRequest、HttpServletResponse、UriInfo 等
+     * @return
+     */
+    @PostMapping("/wxChatPay")
+    public String wxPayCallback(HttpServletRequest request) {
+        Map<String, String> map = new HashMap<>();
+        Map<String,String> errMap = new HashMap<>();
+        try { System.err.println("请求"+request);
+            BufferedReader reader = request.getReader();
+            String string1 = reader.toString();
+            System.err.println("请求reader"+string1);
+            StringBuilder requestBody = new StringBuilder();
+            String line;
+            while ((line = reader.readLine()) != null) {
+                requestBody.append(line);
+            }
+            System.err.println("全部请求体"+requestBody);
+            JSONObject jsonObject = JSONObject.parseObject(requestBody.toString());
+            JSONObject resource = jsonObject.getJSONObject("resource");
+
+            AesUtil aesUtil = new AesUtil("TA2npSNWmS0GcB0tFFRWA94rm1M0iSFs".getBytes(StandardCharsets.UTF_8));
+            String decryptedData = aesUtil.decryptToString(resource.getString("associated_data").getBytes(StandardCharsets.UTF_8), resource.getString("nonce").getBytes(StandardCharsets.UTF_8),
+                    resource.getString("ciphertext"));
+            System.err.println("微信解密的字符串信息"+decryptedData);
+            JSONObject jsonInfo = (JSONObject) JSONObject.parse(decryptedData);
+            String transferBillNo = jsonInfo.getString("transfer_bill_no");
+            String outBillNo = jsonInfo.getString("out_bill_no");
+            String state = jsonInfo.getString("state");
+            WithdrawDetail withdrawDetail = withdrawDetailService.lambdaQuery().eq(WithdrawDetail::getOutBatchNo, outBillNo).one();
+            Withdraw withdraw = withdrawService.getById(withdrawDetail.getWithdrawId());
+            Order order = orderService.getById(withdraw.getOrderId());
+            UserDto data = userClient.getUser(order.getUserId()).getData();
+            if (order.getIsWithdrawal()==3){
+                return "SUCCESS";
+            }
+            if ("SUCCESS".equals(state)){
+                order.setIsWithdrawal(3);
+                withdrawDetail.setStatus("SUCCESS");
+                withdrawDetailService.updateById(withdrawDetail);
+                orderService.updateById(order);
+            }else if ("CANCELLED".equals(state)){
+                // 校验提现
+                List<Withdraw> list = withdrawService.lambdaQuery().eq(Withdraw::getUserId, order.getUserId())
+                        .eq(Withdraw::getOrderId, order.getId()).list();
+                List<Integer> stateList = list.stream().map(Withdraw::getState).collect(Collectors.toList());
+                if (stateList.contains(Constants.ONE)) {
+                    throw new GlobalException("当前订单提现申请已通过!");
+                }
+                // 超时未收款 撤销 重新发起转账 更新packageInfo
+                weChatPay(order.getOrderMoney(), data.getOpenId(),list.get(0).getId(),order.getServeName());
+            }
+            map.put("code", "SUCCESS");
+            map.put("message", "成功");
+        } catch (Exception e) {
+            errMap.put("code", "FAIL");
+            errMap.put("message", "服务器内部错误");
+        }
+        return JSON.toJSONString(map);
+
+    }
+    private boolean weChatPay(BigDecimal orderMoney, String openId, String withdrawId, String serverName) {
+        if (StringUtils.isBlank(openId)) {
+            return false;
+        }
+        BigDecimal maxTransferAmount = new BigDecimal("200000"); // 单次转账限额,单位为分
+        int totalTransfers = orderMoney.multiply(new BigDecimal("100")).divide(maxTransferAmount, 0, RoundingMode.UP).intValue();
+        boolean allTransfersSuccessful = true;
+        for (int i = 0; i < totalTransfers; i++) {
+            BigDecimal transferAmount;
+            if (i < totalTransfers - 1) {
+                transferAmount = maxTransferAmount;
+            } else {
+                // 最后一笔转账,金额为剩余金额
+                transferAmount = orderMoney.multiply(new BigDecimal("100")).subtract(maxTransferAmount.multiply(new BigDecimal(i))).setScale(0, RoundingMode.DOWN);
+            }
+
+            Map<String, Object> postMap = new HashMap<>(8);
+            postMap.put(WechatConstants.APP_ID, "wx98563d0ec9cf21c8");
+            // 订单号
+            String s = String.valueOf(UUID.randomUUID()).replaceAll("-", "");
+            postMap.put("out_bill_no", s);
+            System.err.println("====="+postMap.get("out_bill_no"));
+            postMap.put(WechatConstants.OPEN_ID, openId);
+            // 转账金额
+            postMap.put("transfer_amount", transferAmount);
+            // 转账备注
+            postMap.put("transfer_remark", "二手回收提现确认收款");
+            // 回调地址
+            postMap.put("notify_url", "https://hyhsbqgc.com/api/ruoyi-order/wx/wxChatPay");
+            // 转账场景报备信息
+            Map<String, Object> info = new HashMap<>();
+            info.put("info_type","回收商品名称");
+            info.put("info_content",serverName);
+            postMap.put("transfer_scene_report_infos", com.alibaba.fastjson2.JSONObject.toJSONString(info));
+            String result = HttpUtil.postTransBatRequest(
+                    WechatConstants.WE_CHAT_PAY_URL_PRE,
+                    com.alibaba.fastjson2.JSONObject.toJSONString(postMap),
+                    "7EEA04429B006E12AAA421C002EC48BBEED5BE94",
+                    "1665330417",
+                    "/usr/local/vx/apiclient_key.pem", WechatConstants.WE_CHAT_URL_SUF);
+            com.alibaba.fastjson2.JSONObject jsonObject = com.alibaba.fastjson2.JSONObject.parseObject(result);
+//            WithdrawDetail withdrawDetail = new WithdrawDetail();
+//            withdrawDetail.setWithdrawId(withdrawId);
+//            withdrawDetail.setMoney(transferAmount);
+//            withdrawDetail.setOutBatchNo((String) postMap.get(WechatConstants.OUT_BATCH_NO));
+//            withdrawDetailService.save(withdrawDetail);
+            if (jsonObject.containsKey(WechatConstants.CREATE_TIME)) {
+                String string = jsonObject.getString("package_info");
+                Withdraw withdraw = withdrawService.getById(withdrawId);
+                WithdrawDetail one = withdrawDetailService.lambdaQuery().eq(WithdrawDetail::getWithdrawId, withdrawId).last("limit 1").one();
+                if (one!=null){
+                    one.setOutBatchNo(s);
+                    one.setStatus("FAIL");
+                    withdrawDetailService.updateById(one);
+                    Order order = orderService.getById(withdraw.getOrderId());
+                    order.setPackageInfo(string);
+                    order.setIsWithdrawal(2);
+                    orderService.updateById(order);
+                }
+            } else {
+                allTransfersSuccessful = false;
+                break;
+            }
+
+        }
+
+        return allTransfersSuccessful;
+    }
+
+}

--
Gitblit v1.7.1