1
zj
2025-07-23 b3d754191cd615048cf850734e89e823128ffbfc
src/main/java/com/nq/service/impl/PayServiceImpl.java
@@ -1,39 +1,51 @@
package com.nq.service.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.nq.common.CmcPayConfig;
import com.nq.common.ServerResponse;
import com.nq.dao.*;
import com.nq.pay.PayUtil;
import com.nq.pojo.*;
import com.nq.service.IPayService;
import com.nq.service.IUserService;
import com.nq.service.*;
import com.nq.utils.*;
import com.nq.utils.http.HttpClientUtil;
import com.nq.utils.pay.CmcPayOuterRequestUtil;
import com.nq.utils.pay.CmcPayTool;
import com.nq.utils.timeutil.DateTimeUtil;
import com.nq.utils.translate.GoogleTranslateUtil;
import com.nq.vo.pay.GuoPayVO;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.collections.map.LinkedMap;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import static com.nq.utils.DateTimeUtil.STANDARD_FORMAT;
import static com.nq.utils.timeutil.DateTimeUtil.STANDARD_FORMAT;
@Service("iPayService")
@@ -50,19 +62,180 @@
    UserMapper userMapper;
    @Resource
    SitePayMapper sitePayMapper;
    @Resource
    IUserService userService;
    @Resource
    IUserAssetsServices iUserAssetsServices;
    @Resource
    UserAssetsMapper userAssetsMapper;
    @Resource
    UserWithdrawMapper userWithdrawMapper;
    @Resource
    SiteInfoMapper siteInfoMapper;
    @Autowired
    ISiteInfoService siteInfoService;
    @Resource
    PayChnnelMapper payChnnelMapper;
    @Autowired
    PaymentRechargeService paymentRechargeService;
    public ServerResponse thirdPartyRecharge(HttpServletRequest request, String tradeAmount, Integer type) throws UnsupportedEncodingException, JsonProcessingException, NoSuchAlgorithmException {
        // 支付1
        String reqUrl = "https://api.watchglb.com/pay/web";
        // 支付2
        String uipReqRul = "https://v2.fastechservicepro.com/payin/unifiedorder";
        User user = userService.getCurrentRefreshUser(request);
        if(ObjectUtils.isEmpty(user)){
            GoogleTranslateUtil googleTranslateUtil = new GoogleTranslateUtil();
            String lang = request.getHeader("lang");
            return ServerResponse.createByErrorCodeMsg(401,googleTranslateUtil.translate("请登录",lang ));
        }
        if(type == 1){//支付1
            return getPaymentOne(tradeAmount, reqUrl,user,request);
        }else if(type == 2){//支付2
            return getPaymentTwo(tradeAmount, uipReqRul, user,request);
        }
        return ServerResponse.createByErrorMsg("获取支付方式失败",request);
    }
    @Resource
    AgentUserMapper agentUserMapper;
    //支付2
    private ServerResponse getPaymentTwo(String tradeAmount, String uipReqRul, User user, HttpServletRequest request) throws UnsupportedEncodingException, NoSuchAlgorithmException, JsonProcessingException {
        // 示例参数
        Map<String, String> params = new HashMap<>();
        params.put("merchantid", "T805673557385213"); // 商户号
        params.put("out_trade_no", generatePayOrderId()); // 商户订单号
        // 转换为 BigDecimal
        BigDecimal amount = new BigDecimal(tradeAmount);
        // 保留两位小数,四舍五入
        amount = amount.setScale(2, BigDecimal.ROUND_HALF_UP);
        params.put("total_fee", String.valueOf(amount));         // 交易金额(保留两位小数)
        params.put("notify_url", "https://api.durocaspitall.com/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()));    // 客户姓名
        params.put("customer_mobile", user.getPhone()); // 客户手机号
        params.put("customer_email", "test@gmail.com"); // 客户手机号
        // 生成签名
        String sign = SignatureGeneratorUtil.generateSign(params,"0cfc8e1a446a1e5214b4032f2d6007e2");
        params.put("sign", sign); // 客户邮箱
        // 打印生成的签名
        System.out.println("Generated Sign: " + sign);
        log.info("-------支付2-----:"+params.toString());
        String result = HttpClientUtil.doPost(uipReqRul, params, "utf-8");
        log.info("-------支付2返回参数-----"+result.toString());
        ObjectMapper objectMapper = new ObjectMapper();
        ApiResponse payResponse = objectMapper.readValue(result, ApiResponse.class);
        if(payResponse.getCode() != 0 && !payResponse.getMessage().equals("success")){
            log.error("充值2下单失败:"+params);
            return ServerResponse.createByErrorMsg("获取充值2链接失败",request);
        }
        PaymentRecharge paymentRecharge = new PaymentRecharge();
        paymentRecharge.setUserId(user.getId());
        paymentRecharge.setOrderNo(params.get("out_trade_no"));
        paymentRecharge.setMchOrderNo(payResponse.getData().getOrder_number());
        paymentRecharge.setAmount(new BigDecimal(payResponse.getData().getReal_fee()));
        paymentRecharge.setStatus(1);
        paymentRecharge.setPaymentTime(new Date());
        paymentRecharge.setCreatedAt(new Date());
        paymentRecharge.setNotifyUrl(getOrderTime());
        paymentRecharge.setPayInfo(payResponse.toString());
        paymentRechargeService.save(paymentRecharge);
        return ServerResponse.createBySuccess(payResponse.getData().getUrl());
    }
    //支付1
    private ServerResponse getPaymentOne(String tradeAmount, String reqUrl, User user, HttpServletRequest request) throws JsonProcessingException {
        Map<String, String> params = new TreeMap<String, String>();
        //版本号 需同步返回JSON 必填,固定值 1.0
        params.put("version", "1.0");
        //商品名称
//        params.put("goods_name", "用户:"+user.getId()+",充值");
        params.put("goods_name", "用户充值");
        //商户号  平台分配唯一
        params.put("mch_id", "100789033");
        //商家订单号 保证每笔订单唯一
        params.put("mch_order_no", generatePayOrderId());
        //异步通知地址 不超过 200 字节,支付成功后发起,不能携带参数
        params.put("notify_url", "https://api.durocaspitall.com/user/rechargeCallback.do");
        // 订单时间  时间格式yyyy-MM-dd HH:mm:ss
        params.put("order_date", getOrderTime());
        //支付类型 请查阅商户后台通道编码
        params.put("pay_type", "151");
        //交易金额 以元为单位
        params.put("trade_amount", tradeAmount);
        //商户秘钥必填
        String merchant_key = "6ef36aa4d88a47a9a177c33c7199fff6";
        String signInfo = SignUtil.sortData(params);
        // 签名   signInfo签名参数排序,  merchant_key商户私钥
        String sign = SignAPI.sign(signInfo, merchant_key);
        params.put("sign", sign);
        //固定值 MD5,不参与签名
        params.put("sign_type", "MD5");
        System.out.println("请求参数:" + params.toString());
        String result = HttpClientUtil.doPost(reqUrl, params, "utf-8");
        System.out.println("签名参数排序:" + signInfo.length() + " --> " + signInfo);
        System.out.println("sign值:" + sign.length() + " --> " + sign);
        System.out.println("result值:" + result);
        // 创建 ObjectMapper 实例
        ObjectMapper objectMapper = new ObjectMapper();
        // 将 JSON 字符串转换为实体类对象
        PaymentResponse payResponse = objectMapper.readValue(result, PaymentResponse.class);
        if(payResponse.getRespCode().equals("FAIL")){
            log.error("充值下单失败:"+result);
            return ServerResponse.createByErrorMsg("获取充值链接失败",request);
        }
        PaymentRecharge paymentRecharge = new PaymentRecharge();
        paymentRecharge.setUserId(user.getId());
        paymentRecharge.setOrderNo(payResponse.getOrderNo());
        paymentRecharge.setMchOrderNo(payResponse.getMchOrderNo());
        paymentRecharge.setAmount(new BigDecimal(payResponse.getOriAmount()));
        paymentRecharge.setStatus(1);
        paymentRecharge.setPaymentTime(DateUtil.parse(payResponse.getOrderDate(),"yyyy-MM-dd HH:mm:ss"));
        paymentRecharge.setCreatedAt(new Date());
        paymentRecharge.setNotifyUrl(payResponse.getPayInfo());
        paymentRecharge.setPayInfo(payResponse.toString());
        paymentRechargeService.save(paymentRecharge);
        return ServerResponse.createBySuccess(payResponse.getPayInfo());
    }
    public String generatePayOrderId() {
        // 获取当前时间戳(毫秒)
        long timestamp = System.currentTimeMillis();
        // 生成一个随机的UUID并截取前8位
        String randomUUID = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
        // 将时间戳和随机UUID结合生成订单号
        return timestamp + randomUUID;
    }
    public static String getOrderTime() {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 定义输出格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 格式化当前时间
        return now.format(formatter);
    }
    public ServerResponse juhe1(String payType, String payAmt, HttpServletRequest request) {
@@ -216,54 +389,24 @@
    }
    public ServerResponse flyPay(String payType, String payAmt, String currency, HttpServletRequest request) {
        if( Integer.parseInt(payAmt)>=50000 ||  Integer.parseInt(payAmt)<100){
            return ServerResponse.createByErrorMsg("The maximum top-up amount is 100 and 50000");
        }
        User user = this.iUserService.getCurrentRefreshUser(request);
        if (user == null){
            return ServerResponse.createBySuccessMsg("Please Login");
        }
        if(user.getRealName() == null || user.getRealName().isEmpty()){
            return ServerResponse.createByErrorMsg("Please authenticate with your real name");
        }
    @Transactional
    public ServerResponse flyPay(Integer payType, String payAmt, String currency, HttpServletRequest request) {
        User user = iUserService.getCurrentUser(request);
        SitePay sitePay  = sitePayMapper.selectById(payType);
        UserRecharge userRecharge = new UserRecharge();
        userRecharge.setUserId(user.getId());
        userRecharge.setNickName(user.getRealName());
        userRecharge.setAgentId(user.getAgentId());
        String ordersn = KeyUtils.getRechargeOrderSn();
        userRecharge.setOrderSn(ordersn);
        userRecharge.setPayChannel(payType);
        userRecharge.setPayChannel(sitePay.getChannelName());
        userRecharge.setPayAmt(new BigDecimal(payAmt));
        userRecharge.setOrderStatus(Integer.valueOf(0));
        userRecharge.setAddTime(new Date());
        int insertCount = this.userRechargeMapper.insert(userRecharge);
        if (insertCount > 0) {
            log.info("fly支付,创建支付订单成功!");
        } else {
            log.info("fly支付,创建支付订单失败!");
        }
        PayChnnel payChnnel = payChnnelMapper.selectById(payType);
        if(payChnnel.getChannelName().equals("USDT")){
           AgentUser agentUser =  agentUserMapper.findAgentByAgentId(user.getAgentId());
           return ServerResponse.createBySuccess(agentUser.getOnLineServices());
        }else{
            if(payChnnel.getChannelDesc().equals("wowpay")){
                return rechargMethodWow(ordersn,payAmt);
            }else if(payChnnel.getChannelDesc().equals("dzxum")){
                return rechargMethodDz(ordersn,payAmt);
            }else if(payChnnel.getChannelDesc().equals("qeaepay")){
                return  rechargMethodGe(ordersn,payAmt);
            } else{
                return  rechargMethodTop4(ordersn,payAmt);
            }
        }
        userRecharge.setPayId(payType);
        userRecharge.setImg(currency);
        userRechargeMapper.insert(userRecharge);
        return ServerResponse.createBySuccess( ((SiteInfo)siteInfoService.getInfo(request).getData()).getOnlineService());
    }
@@ -278,7 +421,7 @@
        map.put("mch_order_no",ordersn);
        map.put("pay_type","122");
        map.put("trade_amount",payAmt);
        map.put("order_date",DateTimeUtil.getCurrentDate(STANDARD_FORMAT));
        map.put("order_date", DateTimeUtil.getCurrentDate(STANDARD_FORMAT));
        map.put("goods_name","充值");
        String signStr = SignUtil.sortData(map);
        map.put("sign_type","MD5");
@@ -552,6 +695,51 @@
        return ServerResponse.createByError();
    }
    @Override
    public void rechargeCallback(PaymentResponse vo,HttpServletResponse response) throws IOException {
        log.info("充值回调进来了:"+vo.toString());
        synchronized (vo.getOrderNo()){
            PrintWriter pw = response.getWriter();
            PaymentRecharge paymentRecharge = paymentRechargeService.getOne(new LambdaQueryWrapper<>(PaymentRecharge.class)
                    .eq(PaymentRecharge::getOrderNo, vo.getOrderNo())
                    .eq(PaymentRecharge::getMchOrderNo, vo.getMchOrderNo())
                    .eq(PaymentRecharge::getStatus,1)
                    .last("limit 1")
            );
            if(!vo.getTradeResult().equals("1")){
                paymentRecharge.setStatus(2);
                paymentRecharge.setAmount(new BigDecimal(vo.getOriAmount()));
                paymentRecharge.setPayInfo(vo.toString());
                paymentRechargeService.updateById(paymentRecharge);
                log.error("充值回调失败:"+vo.toString());
                return;
            }
            if(ObjectUtils.isEmpty(paymentRecharge)){
                log.info("未找到充值订单");
                pw.print("error 未找到充值订单");
                return;
            }
            UserAssets userAssets = userAssetsMapper.selectOne(new LambdaQueryWrapper<>(UserAssets.class)
                    .eq(UserAssets::getUserId, paymentRecharge.getUserId())
                    .eq(UserAssets::getAccectType, "IN")
            );
            ServerResponse serverResponse = iUserAssetsServices.updateUserAssets(userAssets.getId(), vo.getOriAmount().toString(), "2");
            if(serverResponse.getStatus() == 0){
                paymentRecharge.setStatus(2);
                paymentRecharge.setAmount(new BigDecimal(vo.getOriAmount()));
                paymentRecharge.setPayInfo(vo.toString());
                paymentRechargeService.updateById(paymentRecharge);
            }
            log.info("充值回调----完成");
            pw.print("success");
            pw.flush();
            pw.close();
        }
    }
    private ServerResponse doSuccess(String orderId, String amount) {
        UserRecharge userRecharge = this.userRechargeMapper.findUserRechargeByOrderSn(orderId);
@@ -559,7 +747,7 @@
            return ServerResponse.createByErrorMsg("后台通知,查不到订单");
        }
        User user = this.userMapper.selectByPrimaryKey(userRecharge.getUserId());
        User user = this.userMapper.selectById(userRecharge.getUserId());
        if (user == null) {
            return ServerResponse.createByErrorMsg("后台通知,查不到用户");
        }
@@ -577,13 +765,7 @@
        int updateCount = this.userRechargeMapper.updateByPrimaryKeySelective(userRecharge);
        if (updateCount > 0) {
            log.info("后台通知,修改订单状态成功");
            BigDecimal total_amt = user.getUserAmt().add(userRecharge.getPayAmt());
            total_amt = total_amt.divide(new BigDecimal(100));
            user.setUserAmt(total_amt);
            BigDecimal total_enable = user.getEnableAmt().add(userRecharge.getPayAmt());
            user.setEnableAmt(total_enable);
            int updateUserCount = this.userMapper.updateByPrimaryKeySelective(user);
            int updateUserCount = this.userMapper.updateById(user);
            if (updateUserCount > 0) {
                return ServerResponse.createBySuccessMsg("后台通知 处理成功");
            }
@@ -720,4 +902,55 @@
        return retMap;
    }
    public void rechargeCallbackTwo(TransactionStatusVo vo, HttpServletResponse response) throws IOException {
        log.info("充值回调进来了:"+vo.toString());
        synchronized (vo.getOut_trade_no()){
            PrintWriter pw = response.getWriter();
            PaymentRecharge paymentRecharge = paymentRechargeService.getOne(new LambdaQueryWrapper<>(PaymentRecharge.class)
                    .eq(PaymentRecharge::getMchOrderNo, vo.getOut_trade_no())
                    .eq(PaymentRecharge::getStatus,1)
                    .last("limit 1")
            );
            if(vo.getStatus().equals("payin_ing")){
                log.error("充值2回调交易中:"+vo.toString());
                return;
            }else if(vo.getStatus().equals("payin_fail")){
                paymentRecharge.setStatus(2);
                paymentRecharge.setAmount(new BigDecimal(vo.getAccount_fee()));
                paymentRecharge.setPayInfo(vo.toString());
                paymentRechargeService.updateById(paymentRecharge);
                log.error("充值回调失败:"+vo.toString());
                return;
            }else if(!vo.getStatus().equals("payin_fail") && !vo.getStatus().equals("payin_ing") && !vo.getStatus().equals("payin_success")){
                log.error("充值回调失败----未知状态:"+vo.toString());
                return;
            }
            if(ObjectUtils.isEmpty(paymentRecharge)){
                log.info("未找到充值订单");
                pw.print("error 未找到充值订单");
                return;
            }
            UserAssets userAssets = userAssetsMapper.selectOne(new LambdaQueryWrapper<>(UserAssets.class)
                    .eq(UserAssets::getUserId, paymentRecharge.getUserId())
                    .eq(UserAssets::getAccectType, "IN")
            );
            ServerResponse serverResponse = iUserAssetsServices.updateUserAssets(userAssets.getId(), vo.getAccount_fee().toString(), "2");
            if(serverResponse.getStatus() == 0){
                paymentRecharge.setStatus(2);
                paymentRecharge.setAmount(new BigDecimal(vo.getAccount_fee()));
                paymentRecharge.setPayInfo(vo.toString());
                paymentRechargeService.updateById(paymentRecharge);
            }
            log.info("充值回调----完成");
            pw.print("success");
            pw.flush();
            pw.close();
        }
    }
}