新版仿ok交易所-后端
zyy
2025-09-13 c51d40152063cd014fa7d444148960f6f9c3282c
U盾充值提现
8 files modified
415 ■■■■■ changed files
trading-order-admin/src/main/java/com/yami/trading/admin/task/IcoTask.java 64 ●●●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/api/UD/UdunClient.java 43 ●●●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/api/UD/UdunUtils.java 4 ●●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWithdrawController.java 134 ●●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiChannelBlockchainController.java 152 ●●●●● patch | view | raw | blame | history
trading-order-admin/src/main/resources/config/system.properties 2 ●●● patch | view | raw | blame | history
trading-order-security-common/src/main/java/com/yami/trading/security/common/enums/CryptoCurrencyEnum.java 11 ●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/service/impl/WithdrawServiceImpl.java 5 ●●●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/admin/task/IcoTask.java
@@ -3,22 +3,31 @@
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yami.trading.api.UD.*;
import com.yami.trading.bean.ico.domain.Ico;
import com.yami.trading.bean.item.domain.Item;
import com.yami.trading.bean.model.ChannelBlockchain;
import com.yami.trading.common.domain.Result;
import com.yami.trading.common.util.ApplicationContextUtils;
import com.yami.trading.common.util.StringUtils;
import com.yami.trading.huobi.data.internal.KlineInitService;
import com.yami.trading.security.common.enums.CryptoCurrencyEnum;
import com.yami.trading.security.common.util.SecurityUtils;
import com.yami.trading.service.ico.IcoService;
import com.yami.trading.service.item.ItemService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
@@ -38,6 +47,55 @@
    @Autowired
    private KlineInitService klineInitService;
    @Autowired
    UdunClient udunClient;
    @Autowired
    RedisTemplate redisTemplate;
    //@Scheduled(cron = "*/5 * * * * ?")
    public void test() {
        String coin = "usdt";
        List<ChannelBlockchain> data = new ArrayList<ChannelBlockchain>();
        Map<String, List<CryptoCurrencyEnum>> allGroupedByCoin = CryptoCurrencyEnum.getAllGroupedByCoin();
        List<CryptoCurrencyEnum> currencyEnums = allGroupedByCoin.get(coin);
        try {
            String partyId = SecurityUtils.getUser().getUserId();
            //获取u盾地址
            //获取商户支持币种
            List<Coin> coinList = udunClient.listSupportCoin(false);
            currencyEnums.forEach((currencyEnum) -> {
                String coinName = currencyEnum.getName();
                Coin c = coinList.stream().filter(x -> x.getName().equals(coinName)).findFirst().orElse(null);
                if (c != null) {
                    ChannelBlockchain rechargeAddressVo = new ChannelBlockchain();
                    //创建地址
                    Address address;
                    String ress = (String)redisTemplate.opsForValue().get(partyId + coinName);
                    if(StringUtils.isNotEmpty(ress)){
                        rechargeAddressVo.setAddress(ress);
                        rechargeAddressVo.setCoin(coinName);
                        rechargeAddressVo.setBlockchain_name(coinName);
                        rechargeAddressVo.setAuto(false);
                        rechargeAddressVo.setImg(null);
                    }else{
                        address = udunClient.createAddress(c.getMainCoinType(),null,null);
                        rechargeAddressVo.setAddress(address.getAddress());
                        rechargeAddressVo.setCoin(coinName);
                        rechargeAddressVo.setBlockchain_name(coinName);
                        rechargeAddressVo.setAuto(false);
                        rechargeAddressVo.setImg(null);
                        redisTemplate.opsForValue().set(partyId + coinName, address.getAddress());
                    }
                    data.add(rechargeAddressVo);
                }
            });
        }catch (Exception e){
            e.printStackTrace();
            log.error("获取充值地址错误:",e);
        }
    }
    /**
     * ico转入产品
     */
trading-order-admin/src/main/java/com/yami/trading/api/UD/UdunClient.java
@@ -6,41 +6,43 @@
import cn.hutool.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class UdunClient implements UdunApi {
    private static Logger logger = LoggerFactory.getLogger(UdunClient.class);
    /**
     * UDUN API Gateway
     */
    private final String gateway;
    /**
     * UDUN Merchant Number
     */
    private final String merchantId;
    private final String gateway =  "https://sig11.udun.io";
    /**
     * UDUN Merchant Key
     */
    private final String merchantKey;
    private final String merchantKey =  "871fb1a18afd7229f5e62e4cba5016a6";
    /**
     * Callback to business system
     * UDUN Merchant Number
     */
    private final String defaultCallBackUrl;
    private final String merchantId =  "321127";
    public UdunClient(String gateway, String merchantId, String merchantKey, String defaultCallBackUrl) {
        this.gateway = gateway;
        this.merchantId = merchantId;
        this.merchantKey = merchantKey;
        this.defaultCallBackUrl = defaultCallBackUrl;
    }
    /**
     * Callback 充值
     */
    private final String defaultCallBackUrl =  "https://syjysapi.yanshiz.com/api/channelBlockchain!rechargeCallback.action";
    /**
     * Callback 提币
     */
    private final String withdrawCallBackUrl =  "https://syjysapi.yanshiz.com/api/withdraw/withdrawCallback.action";
    @Override
    public Address createAddress(String mainCoinType)  throws UdunException {
@@ -56,7 +58,7 @@
    public Address createAddress(String mainCoinType, String alias, String walletId, String callUrl) throws UdunException{
        Map<String, String> params = new HashMap<>();
        params.put("merchantId", merchantId);
        params.put("coinType", mainCoinType);
        params.put("mainCoinType", mainCoinType);
        params.put("callUrl", callUrl);
        params.put("walletId", walletId);
        params.put("alias", alias);
@@ -71,7 +73,7 @@
    @Override
    public ResultMsg withdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo) {
        return withdraw(address, amount, mainCoinType, coinType, businessId, memo, defaultCallBackUrl);
        return withdraw(address, amount, mainCoinType, coinType, businessId, memo, withdrawCallBackUrl);
    }
    @Override
@@ -90,7 +92,7 @@
    @Override
    public ResultMsg autoWithdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo) {
        return autoWithdraw(address, amount, mainCoinType, coinType, businessId, memo, defaultCallBackUrl);
        return autoWithdraw(address, amount, mainCoinType, coinType, businessId, memo, withdrawCallBackUrl);
    }
    @Override
@@ -129,4 +131,9 @@
        }
        return JSONUtil.toList(JSONUtil.parseArray(result.getData()), Coin.class);
    }
    public boolean checkSign(String timestamp, String nonce, String body, String sign) {
        String checkSign = UdunUtils.sign(merchantKey, timestamp, nonce, body);
        return checkSign.equals(sign);
    }
}
trading-order-admin/src/main/java/com/yami/trading/api/UD/UdunUtils.java
@@ -81,8 +81,4 @@
        return SecureUtil.md5(raw);
    }
    public static boolean checkSign(String key, String timestamp, String nonce, String body, String sign) {
        String checkSign = sign(key, timestamp, nonce, body);
        return checkSign.equals(sign);
    }
}
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWithdrawController.java
@@ -1,12 +1,21 @@
package com.yami.trading.api.controller;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yami.trading.api.UD.*;
import com.yami.trading.bean.model.CapitaltWallet;
import com.yami.trading.bean.model.RechargeBlockchainOrder;
import com.yami.trading.bean.model.Withdraw;
import com.yami.trading.common.constants.Constants;
import com.yami.trading.common.domain.Result;
import com.yami.trading.common.exception.BusinessException;
import com.yami.trading.common.exception.YamiShopBindException;
import com.yami.trading.common.util.Arith;
import com.yami.trading.common.util.C2cLock;
import com.yami.trading.common.util.DateUtils;
import com.yami.trading.common.util.StringUtils;
import com.yami.trading.security.common.util.SecurityUtils;
@@ -16,12 +25,14 @@
import com.yami.trading.service.syspara.SysparaService;
import com.yami.trading.service.user.UserService;
import com.yami.trading.service.user.WalletLogService;
import com.yami.trading.sys.model.SysUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
@@ -50,6 +61,9 @@
    @Autowired
    CapitaltWalletService capitaltWalletService;
    @Autowired
    UdunClient udunClient;
    /**
     * 首次进入页面,传递session_token
     */
@@ -77,18 +91,20 @@
    public Result apply(String session_token, String safeword,
                                String amount, String from, String currency,
                                String channel){
        String partyId = SecurityUtils.getUser().getUserId();
        String error = this.verif(amount);
        if (!StringUtils.isNullOrEmpty(error)) {
            throw new YamiShopBindException(error);
        }
        double amount_double = Double.valueOf(amount).doubleValue();
        Result resultObject=new Result();
        try {
            String partyId = SecurityUtils.getUser().getUserId();
            String error = this.verif(amount);
            if (!StringUtils.isNullOrEmpty(error)) {
                throw new YamiShopBindException(error);
            }
            double amount_double = Double.valueOf(amount).doubleValue();
        // 交易所提现是否需要资金密码
        String exchange_withdraw_need_safeword = this.sysparaService.find("exchange_withdraw_need_safeword").getSvalue();
        if(StringUtils.isEmptyString(exchange_withdraw_need_safeword)) {
            throw new YamiShopBindException("系统参数错误");
        }
            // 交易所提现是否需要资金密码
            String exchange_withdraw_need_safeword = this.sysparaService.find("exchange_withdraw_need_safeword").getSvalue();
            if(StringUtils.isEmptyString(exchange_withdraw_need_safeword)) {
                throw new YamiShopBindException("系统参数错误");
            }
//        if ("true".equals(exchange_withdraw_need_safeword)) {
//
@@ -104,25 +120,89 @@
//            }
//        }
        // 获取资金账户(capital)
        CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
                .eq(CapitaltWallet::getUserId, partyId).last(" limit 1 "));
        if(capitaltWallet.getMoney().compareTo(new BigDecimal(amount)) < 0){
            throw new YamiShopBindException("Insufficient available balance for withdrawal!");
        }
            // 获取资金账户(capital)
            CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
                    .eq(CapitaltWallet::getUserId, partyId).last(" limit 1 "));
            if(capitaltWallet.getMoney().compareTo(new BigDecimal(amount)) < 0){
                throw new YamiShopBindException("Insufficient available balance for withdrawal!");
            }
        this.sessionTokenService.del(session_token);
        Withdraw withdraw = new Withdraw();
        withdraw.setUserId(partyId);
        withdraw.setVolume(new BigDecimal(amount_double));
        withdraw.setAddress(from);
        withdraw.setCurrency(currency);
        withdraw.setTx("");
        // 保存
        this.withdrawService.saveApply(withdraw, channel, null);
        return Result.succeed(null);
            this.sessionTokenService.del(session_token);
            Withdraw withdraw = new Withdraw();
            withdraw.setUserId(partyId);
            withdraw.setVolume(new BigDecimal(amount_double));
            withdraw.setAddress(from);
            withdraw.setCurrency(currency);
            withdraw.setTx("");
            //获取商户支持币种
            List<Coin> coinList = udunClient.listSupportCoin(false);
            Coin coin = coinList.stream().filter(x -> x.getName().equals(channel)).findFirst().orElse(null);
            if (coin == null) {
                throw new YamiShopBindException("不支持的提现币种");
            }
            // 保存
            this.withdrawService.saveApply(withdraw, channel, null);
            ResultMsg resultMsg = udunClient.withdraw(from, withdraw.getVolume(), coin.getMainCoinType(),
                    coin.getCoinType(), withdraw.getOrderNo(), null);
            if (resultMsg.getCode() != HttpStatus.HTTP_OK) {
                log.error("withdraw:{}", JSONUtil.toJsonStr(resultMsg));
                throw new UdunException(resultMsg.getCode(), resultMsg.getMessage());
            }
            resultObject.setCode(0);
        } catch (UdunException e) {
            resultObject.setCode(1);
            resultObject.setMsg(e.getMessage());
            log.error("error:" + e.getMessage());
            throw e;
        } catch (Throwable t) {
            resultObject.setCode(1);
            resultObject.setMsg(t.getMessage());
            log.error("error: {}", t.getMessage());
            throw new RuntimeException(t);
        }
        return resultObject;
    }
    @PostMapping("withdrawCallback.action")
    public ResultMsg withdrawCallback(HttpServletRequest request){
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String sign = request.getParameter("sign");
        String body = request.getParameter("body");
        ResultMsg resultMsg = new ResultMsg();
        try{
            boolean flag = udunClient.checkSign(timestamp, nonce, body, sign);
            log.info("===withdrawCallback===sign:{}", flag);
            if (!flag){
                resultMsg.setCode(406);
                resultMsg.setMessage("提现回调验签失败");
                return resultMsg;
            }
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> map = objectMapper.readValue(body, HashMap.class);
            String address = map.get("address").toString();
            String order_no = map.get("businessId").toString();
            Withdraw withdraw = withdrawService.getOne(new LambdaQueryWrapper<>(Withdraw.class)
                    .eq(Withdraw::getOrderNo, order_no).last(" limit 1 "));
            if(ObjectUtil.isEmpty(withdraw) && withdraw.getStatus() != 0 && !withdraw.getAddress().equals(address)){
                log.info("withdraw failed:{}", withdraw);
                resultMsg.setCode(200);
                return resultMsg;
            }
            withdrawService.examineOk(order_no, Long.valueOf(withdraw.getUserId()));
            resultMsg.setCode(200);
        }catch (Exception e){
            resultMsg.setCode(500);
            resultMsg.setMessage("回调处理失败");
        }
        return resultMsg;
    }
    /**
     * 提现订单详情
     * <p>
trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiChannelBlockchainController.java
@@ -9,6 +9,7 @@
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yami.trading.bean.vo.RechargeAddressVo;
import com.yami.trading.security.common.enums.CryptoCurrencyEnum;
import com.yami.trading.security.common.util.LocalKeyStorageAESUtil;
import com.yami.trading.api.UD.*;
@@ -36,6 +37,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -66,13 +68,8 @@
    private SysUserService sysUserService;
    @Autowired
    RechargeBlockchainOrderService rechargeBlockchainOrderService;
    private final String gateway =  "https://sig11.udun.io";
    private final String merchantKey =  "7fd79e4ed59e7c31e1fa2e13d64f7e6c";
    private final String merchantId =  "319563";
    private final String defaultCallBackUrl =  "https://openapi.yanshiz.com/api/channelBlockchain!rechargeCallback.action";
    @Autowired
    UdunClient udunClient;
    /**
     * 获取所有链地址
@@ -123,9 +120,8 @@
     */
    @GetMapping(action + "getBlockchainName.action")
    public Object getBlockchainName(HttpServletRequest request) throws Exception {
        String coin = request.getParameter("coin");
        List<ChannelBlockchain> data = new ArrayList<ChannelBlockchain>();
        /*String coin = request.getParameter("coin");
        List<ChannelBlockchain> data = new ArrayList<>();
        try {
            coin  = coin.toLowerCase();
            Map<String, List<CryptoCurrencyEnum>> allGroupedByCoin = CryptoCurrencyEnum.getAllGroupedByCoin();
@@ -148,11 +144,8 @@
            log.error("获取充值地址错误:",e);
            return Result.failed("充值链暂不可用");
        }
        return Result.succeed(data);
        return Result.succeed(data);*/
//        String partyId =SecurityUtils.getUser().getUserId();
//        User party = userService.getById(partyId);
//        if (0 == this.sysparaService.find("can_recharge").getInteger()) {
//            return Result.failed("请联系客服充值");
@@ -194,7 +187,7 @@
//                data.get(i).setAddress(null);
//            }
//        }
//        String partyId =SecurityUtils.getUser().getUserId();
//        if(!StringUtils.isNotEmpty(partyId)){
//            throw new YamiShopBindException("请登录!");
@@ -202,92 +195,65 @@
//        if (0 == this.sysparaService.find("can_recharge").getInteger()) {
//            return Result.failed("请联系客服充值");
//        }
//        RechargeAddressVo rechargeAddressVo = new RechargeAddressVo();
//
//        //获取u盾地址
//        //获取商户支持币种
//        List<Coin> coinList = listSupportCoin(merchantId,false);
//        //创建地址
//        coinList.forEach(f->{
//            Address address = new Address();
//            if(f.getName().equals("BTC")){
//                String ress = (String)redisTemplate.opsForValue().get(partyId + "BTC");
//                if(StringUtils.isNotEmpty(ress)){
//                    rechargeAddressVo.setAddress(ress);
//                    rechargeAddressVo.setCoin(coin);
//                    rechargeAddressVo.setBlockchainName(coin);
//                }else{
//                    address = createAddress(f.getMainCoinType(),null,null,null);
//                    rechargeAddressVo.setAddress(address.getAddress());
//                    rechargeAddressVo.setCoin(coin);
//                    rechargeAddressVo.setBlockchainName(coin);
//                    redisTemplate.opsForValue().set(partyId + "BTC",address.getAddress());
//                }
//            }else if(f.getName().equals("ETH")){
//                String ress = (String)redisTemplate.opsForValue().get(partyId + "ETH");
//                if(StringUtils.isNotEmpty(ress)){
//                    rechargeAddressVo.setAddress(ress);
//                    rechargeAddressVo.setCoin(coin);
//                    rechargeAddressVo.setBlockchainName(coin);
//                }else{
//                    address = createAddress(f.getMainCoinType(),null,null,null);
//                    rechargeAddressVo.setAddress(address.getAddress());
//                    rechargeAddressVo.setCoin(coin);
//                    rechargeAddressVo.setBlockchainName(coin);
//                    redisTemplate.opsForValue().set(partyId + "ETH",address.getAddress());
//                }
//            }else if(f.getName().equals("USDT")){
//                String ress = (String)redisTemplate.opsForValue().get(partyId + "USDT");
//                if(StringUtils.isNotEmpty(ress)){
//                    rechargeAddressVo.setAddress(ress);
//                    rechargeAddressVo.setCoin(coin);
//                    rechargeAddressVo.setBlockchainName(coin);
//                }else{
//                    address = createAddress(f.getMainCoinType(),null,null,null);
//                    rechargeAddressVo.setAddress(address.getAddress());
//                    rechargeAddressVo.setCoin(coin);
//                    rechargeAddressVo.setBlockchainName(coin);
//                    redisTemplate.opsForValue().set(partyId + "USDT",address.getAddress());
//                }
//            }
//        });
//        return Result.succeed(rechargeAddressVo);
    }
        String coin = request.getParameter("coin");
        coin = coin.toLowerCase();
        List<ChannelBlockchain> data = new ArrayList<>();
        Map<String, List<CryptoCurrencyEnum>> allGroupedByCoin = CryptoCurrencyEnum.getAllGroupedByCoin();
        List<CryptoCurrencyEnum> currencyEnums = allGroupedByCoin.get(coin);
        try {
            String partyId = SecurityUtils.getUser().getUserId();
            //获取u盾地址
            //获取商户支持币种
            List<Coin> coinList = udunClient.listSupportCoin(false);
    public List<Coin> listSupportCoin(String merchantId , boolean showBalance) {
        Map<String, Object> params = new HashMap<>();
        params.put("merchantId", merchantId);
        params.put("showBalance", showBalance);
        ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.SUPPORT_COIN, JSONUtil.toJsonStr(params)), ResultMsg.class);
        if (result.getCode() != HttpStatus.HTTP_OK) {
            Console.error(JSONUtil.toJsonStr(result));
            return null;
            currencyEnums.forEach((currencyEnum) -> {
                String coinName = currencyEnum.getName();
                Coin c = coinList.stream().filter(x -> x.getName().equals(coinName)).findFirst().orElse(null);
                if (c != null) {
                    ChannelBlockchain rechargeAddressVo = new ChannelBlockchain();
                    //创建地址
                    Address address;
                    String ress = (String)redisTemplate.opsForValue().get(partyId + coinName);
                    if(StringUtils.isNotEmpty(ress)){
                        rechargeAddressVo.setAddress(ress);
                    }else{
                        address = udunClient.createAddress(c.getMainCoinType());
                        rechargeAddressVo.setAddress(address.getAddress());
                        redisTemplate.opsForValue().set(partyId + coinName, address.getAddress());
                    }
                    //rechargeAddressVo.setAddress("test" + coinName);
                    rechargeAddressVo.setCoin(currencyEnum.getCoin());
                    rechargeAddressVo.setBlockchain_name(currencyEnum.getChain());
                    rechargeAddressVo.setAuto(false);
                    rechargeAddressVo.setImg(null);
                    data.add(rechargeAddressVo);
                }
            });
        }catch (Exception e){
            log.error("获取充值地址错误:",e);
            return Result.failed("充值链暂不可用");
        }
        return JSONUtil.toList(JSONUtil.parseArray(result.getData()), Coin.class);
        return Result.succeed(data);
    }
    public Address createAddress(String mainCoinType, String alias, String walletId, String callUrl) throws UdunException {
        Map<String, String> params = new HashMap<>();
        params.put("merchantId", merchantId);
        params.put("coinType", mainCoinType);
        params.put("callUrl", defaultCallBackUrl);
        params.put("walletId", walletId);
        params.put("alias", alias);
        ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.CREATE_ADDRESS, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
        if (result.getCode() != HttpStatus.HTTP_OK) {
            throw new UdunException(result.getCode(), result.getMessage());
        }
        return JSONUtil.toBean(result.getData(), Address.class);
    }
    @RequestMapping(action +"rechargeCallback.action")
    @PostMapping(action +"rechargeCallback.action")
    public ResultMsg rechargeCallback(HttpServletRequest request){
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String sign = request.getParameter("sign");
        String body = request.getParameter("body");
        ResultMsg resultMsg = new ResultMsg();
        try{
            boolean flag = udunClient.checkSign(timestamp, nonce, body, sign);
            log.info("===rechargeCallback===sign:{}", flag);
            if (!flag){
                resultMsg.setCode(406);
                resultMsg.setMessage("充值回调验签失败");
                return resultMsg;
            }
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> map = objectMapper.readValue(body, HashMap.class);
            double amounts = Double.parseDouble(map.get("amount").toString());  // 假设 amount 的值为 1000
@@ -295,22 +261,18 @@
            double success_amount  = amounts / Math.pow(10, decimals);
            String address = map.get("address").toString();
            RechargeBlockchainOrder blockchainOrder = rechargeBlockchainOrderService.getOne(new LambdaQueryWrapper<>(RechargeBlockchainOrder.class)
                    .eq(RechargeBlockchainOrder::getSucceeded, 0)
                    .eq(RechargeBlockchainOrder::getChannelAddress, address).last(" limit 1 "));
            if(ObjectUtil.isEmpty(blockchainOrder)){
                ResultMsg resultMsg = new ResultMsg();
                resultMsg.setCode(200);
                return resultMsg;
            }
                SysUser user = sysUserService.getSysUserById( Long.getLong(blockchainOrder.getPartyId()));
            rechargeBlockchainOrderService.manualReceipt(1,blockchainOrder.getPartyId(), BigDecimal.valueOf(success_amount),user.getUsername());
            ResultMsg resultMsg = new ResultMsg();
            resultMsg.setCode(200);
            return resultMsg;
        }catch (Exception e){
            ResultMsg resultMsg = new ResultMsg();
            resultMsg.setCode(500);
            resultMsg.setMessage("回调处理失败");
            return resultMsg;
trading-order-admin/src/main/resources/config/system.properties
@@ -1,5 +1,5 @@
http.server.host=http://127.0.0.1:8080/images/
images.dir=/mydata/img/
images.dir=/www/wwwroot/8.20/img/qr/
admin_url=https://127.0.0.1:8080/admin
web_url=http://127.0.0.1:8080/wap/
trading-order-security-common/src/main/java/com/yami/trading/security/common/enums/CryptoCurrencyEnum.java
@@ -11,13 +11,20 @@
 * @create: 2025-08-06 16:05
 **/
public enum CryptoCurrencyEnum {
    USDT_TRC20("usdt", "TRC20","usdt_trc20"),
    /*USDT_TRC20("usdt", "TRC20","usdt_trc20"),
    USDT_ERC20("usdt", "ERC20","usdt_erc20"),
    ETH("eth", "ETH","eth"),
    BTC("btc", "BTC","btc"),
    USDC_ERC20("usdc", "ERC20(1)","usdc_erc20(1)"),
    USDC_ERC202("usdc", "ERC20(2)","usdc_erc20(2)"),
    USDC_TRC20("usdc", "TRC20","usdc_trc20");
    USDC_TRC20("usdc", "TRC20","usdc_trc20");*/
    USDT_TRC20("usdt", "TRC20","USDT-TRC20"),
    USDT_ERC20("usdt", "ERC20","USDT-ERC20"),
    ETH("eth", "ETH","ETH"),
    BTC("btc", "BTC","BTC"),
    USDC_ERC20("usdc", "ERC20","USDC-ERC20"),
    USDC_TRC20("usdc", "TRC20","USDC-TRC20");
    private final String coin;
trading-order-service/src/main/java/com/yami/trading/service/impl/WithdrawServiceImpl.java
@@ -95,6 +95,8 @@
                symbol = "btc";
            } else if (withdraw.getMethod().indexOf("ETH") != -1) {
                symbol = "eth";
            } else if (withdraw.getMethod().indexOf("USDC") != -1) {
                symbol = "usdc";
            } else {
                symbol = "usdt";
            }
@@ -436,6 +438,9 @@
        } else if (channel.indexOf("ETH") != -1) {
            saveApplyOtherChannel(withdraw, "ethusdt");
            return;
        } else if (channel.indexOf("USDC") != -1) {
            saveApplyOtherChannel(withdraw, "usdcusdt");
            return;
        }
        User party = userService.getById(withdraw.getUserId());
        if (Constants.SECURITY_ROLE_TEST.equals(party.getRoleName())) {