From 677997551f0de1a8efd754fab1485c02fe560e94 Mon Sep 17 00:00:00 2001
From: zyy <zyy@email.com>
Date: Fri, 13 Mar 2026 17:22:30 +0800
Subject: [PATCH] 1

---
 src/main/java/com/nq/service/impl/PayServiceImpl.java |  166 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 158 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/nq/service/impl/PayServiceImpl.java b/src/main/java/com/nq/service/impl/PayServiceImpl.java
index 0f00c2a..986c2ec 100644
--- a/src/main/java/com/nq/service/impl/PayServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/PayServiceImpl.java
@@ -41,6 +41,9 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import com.nq.vo.pay.PayOutMD5Util;
+import com.nq.vo.pay.PayoutCallbackData;
+import com.nq.vo.pay.PayoutCallbackRequest;
 import net.sf.json.JSON;
 import net.sf.json.JSONObject;
 import okhttp3.*;
@@ -121,9 +124,11 @@
         }else if(type == 2){//支付2
             return getPaymentZero(tradeAmount, uipReqRul, user,request);
         } else if(type == 3){//支付2
-            return getPaymentTwo(tradeAmount, uipReqRul, user,request);
+//            return getPaymentTwo(tradeAmount, uipReqRul, user,request);
+            return ServerResponse.createByErrorMsg("未开启,请选择其他支付方式",request);
         }else if(type == 1){
-            return getPaymentThree(tradeAmount, threeUrl, user,request);
+//            return getPaymentThree(tradeAmount, threeUrl, user,request);
+            return getPaymentOne(tradeAmount, reqUrl,user,request);
         }
         return ServerResponse.createByErrorMsg("获取支付方式失败",request);
     }
@@ -142,8 +147,9 @@
         dataObj.put("customerEmail","123456@qq.com");//需替换
         dataObj.put("customerPhone",user.getPhone());//需替换
         dataObj.put("merchantOrderNo",generatePayOrderId());//自定义订单号
-        dataObj.put("notifyUrl", "https://api.durocapital.top/user/rechargeCallbackZero.do");//回调通知地址
+        dataObj.put("notifyUrl", "https://api.greenbackcaps.top/user/rechargeCallbackZero.do");//回调通知地址
         JSONObject requestObj = new JSONObject();
+        log.info("代收参数:{}", dataObj);
         // 加密数据
         byte[] encryptedData = encrypt(dataObj.toString(), aesKey, aesIv);
         String base64EncodedData = Base64.getEncoder().encodeToString(encryptedData);
@@ -152,6 +158,7 @@
         Headers headers = new Headers.Builder().add("merchant_key", merchantKey).build();//merchant_key需替换
         //请求
         String resp = doPost(url, requestObj.toString(), headers);
+        log.info("代收返回:"+resp);
         Gson gson = new Gson();
         PaymentResponseZero paymentResponse = gson.fromJson(resp, PaymentResponseZero.class);
         if(paymentResponse.getCode() != 0 && !paymentResponse.getMsg().equals("success")){
@@ -239,8 +246,8 @@
         params.put("merchant_order_id", merchantOrderId);
         params.put("amount", amount.toString());
         params.put("pay_channel", payChannel);
-        params.put("notify_url", "https://api.durocapital.top/user/rechargeCallbackThree.do"); // 异步通知地址
-        params.put("page_return_url", "https://stock.durocapital.lat/#/user"); // 前端返回地址
+        params.put("notify_url", "https://api.greenbackcaps.top/user/rechargeCallbackThree.do"); // 异步通知地址
+        params.put("page_return_url", "https://stock.greenbackcaps.top/#/user"); // 前端返回地址
 
         // 可选参数
         if (user != null) {
@@ -333,7 +340,7 @@
         // 保留两位小数,四舍五入
         amount = amount.setScale(2, BigDecimal.ROUND_HALF_UP);
         params.put("total_fee", String.valueOf(amount));         // 交易金额(保留两位小数)
-        params.put("notify_url", "https://api.durocapital.top/user/rechargeCallbackTwo.do"); // 异步通知地址
+        params.put("notify_url", "https://api.greenbackcaps.top/user/rechargeCallbackTwo.do"); // 异步通知地址
         params.put("reply_type", "URL");          // 执行方式
         params.put("timestamp", String.valueOf(System.currentTimeMillis()));     // 时间戳
         params.put("customer_name", StringUtils.isEmpty(UserNameUtil.formatCustomerName(user.getNickName())) ? "IsNotSet" : UserNameUtil.formatCustomerName(user.getNickName()));    // 客户姓名
@@ -395,7 +402,7 @@
         //商家订单号 保证每笔订单唯一
         params.put("mch_order_no", generatePayOrderId());
         //异步通知地址 不超过 200 字节,支付成功后发起,不能携带参数
-        params.put("notify_url", "https://api.durocapital.top/user/rechargeCallback.do");
+        params.put("notify_url", "https://api.greenbackcaps.top/user/rechargeCallback.do");
         // 订单时间  时间格式yyyy-MM-dd HH:mm:ss
         params.put("order_date", getOrderTime());
         //支付类型 请查阅商户后台通道编码
@@ -1421,7 +1428,7 @@
                 transferResponseService.updateById(transferResponse);
                 
                 userWithdraw.setWithStatus(2); // 失败
-                userWithdraw.setWithMsg("代付失败:" + vo.getMsg());
+                userWithdraw.setWithMsg("Withdrawal failed:" + vo.getMsg());
                 userWithdraw.setTransTime(new Date());
                 userWithdrawMapper.updateByPrimaryKeySelective(userWithdraw);
                 
@@ -1480,4 +1487,147 @@
             pw.close();
         }
     }
+
+    public Map<String, Object> payoutCallbackTwo(PayoutCallbackRequest request, HttpServletResponse response) {
+
+
+        String merchantKey = "qqaC1DH/LeR9iPvm";//商户key 需替换
+        String aesKey = "ge6vK40fHNZPFJ4p";//商户aesKey 需替换
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("code", 200);   // 固定返回 200
+
+        try {
+            PayoutCallbackData data = request.getData();
+            String signature = request.getSignature_n();
+
+            // 1. 签名验证
+            String signStr = merchantKey
+                    + nullToEmpty(data.getMessage())
+                    + nullToEmpty(data.getAmount())
+                    + nullToEmpty(data.getStatus())
+                    + nullToEmpty(data.getMerchantOrderNo())
+                    + nullToEmpty(data.getOrderNo())
+                    + aesKey;
+
+            String calculatedSign = PayOutMD5Util.md5(signStr).toLowerCase();
+
+            if (!calculatedSign.equals(signature)) {
+                log.error("代付回调签名验证失败,merchantOrderNo={},本地签名={},回调签名={}",
+                        data.getMerchantOrderNo(), calculatedSign, signature);
+                // 签名失败不处理业务,但依旧返回 200
+                return result;
+            }
+
+            // 2. 查询本地代付记录
+            TransferResponse transfer = transferResponseService.getOne(
+                    new LambdaQueryWrapper<TransferResponse>()
+                            .eq(TransferResponse::getMerTransferId, data.getMerchantOrderNo())
+                            .last("limit 1")
+            );
+
+            if (transfer == null) {
+                log.error("代付回调未找到对应记录,merchantOrderNo={}", data.getMerchantOrderNo());
+                return result;
+            }
+
+            // 3. 防止重复回调
+            if (transfer.getCallbackState() != 0) {
+                log.info("代付回调已处理过,merchantOrderNo={},状态={}", data.getMerchantOrderNo(), transfer.getCallbackState());
+                return result;
+            }
+
+            // 4. 查询提现记录
+            UserWithdraw withdraw = userWithdrawMapper.selectByPrimaryKey(transfer.getWithId());
+            if (withdraw == null) {
+                log.error("代付回调未找到提现记录,withId={}", transfer.getWithId());
+                return result;
+            }
+
+            // 5. 根据状态处理
+            String status = data.getStatus();
+            if ("SUCCESS".equals(status)) {
+                handleSuccess(transfer, withdraw, data, signature);
+            } else if ("FAILURE".equals(status)) {
+                handleFailure(transfer, withdraw, data, signature);
+            } else {
+                log.info("代付回调未知状态:{},暂不处理,merchantOrderNo={}", status, data.getMerchantOrderNo());
+            }
+
+        } catch (Exception e) {
+            log.error("代付回调处理异常", e);
+        }
+
+        return result;
+    }
+
+    /**
+     * 处理成功回调
+     */
+    private void handleSuccess(TransferResponse transfer, UserWithdraw withdraw,
+                               PayoutCallbackData data, String signature) {
+        // 更新代付记录
+        transfer.setTradeResult(1);          // 成功
+        transfer.setCallbackState(1);        // 已处理成功
+        transfer.setRespCode("SUCCESS");
+        transfer.setSignType("MD5");
+        transfer.setSign(signature);
+        transfer.setUpdatedAt(new Date());
+        transferResponseService.updateById(transfer);
+
+        // 更新提现记录
+        withdraw.setWithStatus(1);            // 成功
+        withdraw.setWithMsg("代付成功");
+        withdraw.setTransTime(new Date());
+        userWithdrawMapper.updateByPrimaryKeySelective(withdraw);
+
+        // 扣除冻结资金(提现时已冻结,此处只需将冻结减少,可用余额不变)
+        UserAssets assets = iUserAssetsServices.assetsByTypeAndUserId("IN", withdraw.getUserId());
+        if (assets != null) {
+            assets.setFreezeMoney(assets.getFreezeMoney().subtract(withdraw.getWithAmt()));
+            userAssetsMapper.updateById(assets);
+        }
+
+        log.info("代付成功处理完成,商户订单号={},平台订单号={}", data.getMerchantOrderNo(), data.getOrderNo());
+    }
+
+    /**
+     * 处理失败回调
+     */
+    private void handleFailure(TransferResponse transfer, UserWithdraw withdraw,
+                               PayoutCallbackData data, String signature) {
+        // 更新代付记录
+        transfer.setTradeResult(2);          // 失败
+        transfer.setCallbackState(2);        // 已处理失败
+        transfer.setRespCode("FAIL");
+        transfer.setErrorMsg(data.getMessage());
+        transfer.setSignType("MD5");
+        transfer.setSign(signature);
+        transfer.setUpdatedAt(new Date());
+        transferResponseService.updateById(transfer);
+
+        // 更新提现记录
+        withdraw.setWithStatus(2);            // 失败
+        withdraw.setWithMsg("Withdrawal failed:" + data.getMessage());
+        withdraw.setTransTime(new Date());
+        userWithdrawMapper.updateByPrimaryKeySelective(withdraw);
+
+        // 返还资金:解冻并增加可用余额
+        UserAssets assets = iUserAssetsServices.assetsByTypeAndUserId("IN", withdraw.getUserId());
+        if (assets != null) {
+            assets.setAvailableBalance(assets.getAvailableBalance().add(withdraw.getWithAmt()));
+            assets.setFreezeMoney(assets.getFreezeMoney().subtract(withdraw.getWithAmt()));
+            userAssetsMapper.updateById(assets);
+        }
+
+        log.info("代付失败处理完成,商户订单号={},平台订单号={},失败原因={}",
+                data.getMerchantOrderNo(), data.getOrderNo(), data.getMessage());
+    }
+
+    /**
+     * 将 null 转为空字符串,防止拼接 NPE
+     */
+    private String nullToEmpty(String str) {
+        return str == null ? "" : str;
+    }
 }
\ No newline at end of file

--
Gitblit v1.9.3