From 370c0e6d54be9222fcaa416fdd605f09e3c49e8a Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Sun, 25 May 2025 17:14:45 +0800
Subject: [PATCH] 1

---
 src/main/java/project/blockchain/AdminRechargeBlockchainOrderService.java              |    2 
 src/main/java/project/blockchain/internal/AdminRechargeBlockchainOrderServiceImpl.java |    9 
 src/main/java/project/web/api/ApiPath.java                                             |   12 
 .idea/encodings.xml                                                                    |    1 
 src/main/java/project/blockchain/internal/RechargeBlockchainServiceImpl.java           |  552 ++++++++++++++++++------
 src/main/java/project/web/api/UserWalletAddressController.java                         |  123 ++++-
 src/main/java/project/blockchain/RechargeBlockchainService.java                        |    1 
 pom.xml                                                                                |   15 
 src/main/java/project/web/api/Coin.java                                                |   78 +++
 src/main/java/project/web/api/Address.java                                             |   31 +
 src/main/java/project/web/api/UdunApi.java                                             |  108 ++++
 src/main/java/project/web/api/UdunClient.java                                          |  132 ++++++
 src/main/java/project/web/api/UdunUtils.java                                           |   88 ++++
 src/main/java/project/web/admin/AdminRechargeBlockchainOrderController.java            |   24 +
 src/main/java/project/web/api/filter/AllRequestFilter.java                             |    1 
 src/main/java/project/web/api/UdunException.java                                       |   28 +
 src/main/java/project/web/admin/ResultMsg.java                                         |   40 +
 src/main/java/project/web/api/ResultMsg.java                                           |   40 +
 18 files changed, 1,107 insertions(+), 178 deletions(-)

diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index 2bccb6e..0d8116c 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -2,5 +2,6 @@
 <project version="4">
   <component name="Encoding">
     <file url="file://$PROJECT_DIR$/../../Backup/Downloads/LocalUserController.class01" charset="GBK" />
+    <file url="file://$PROJECT_DIR$/../../Backup/Downloads/RechargeBlockchainServiceImpl.class01" charset="GBK" />
   </component>
 </project>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9f0fe23..8f4e341 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,7 +15,22 @@
       <version>8.5.100</version>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>cn.hutool</groupId>
+      <artifactId>hutool-all</artifactId>
+      <version>5.4.0</version>
+    </dependency>
 
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>1.7.32</version> <!-- 使用与你的SLF4J版本匹配的版本 -->
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>1.7.32</version> <!-- 或其他绑定,如slf4j-log4j12或slf4j-logback -->
+    </dependency>
     <!--springmvc组件-->
     <dependency>
       <groupId>javax.servlet</groupId>
diff --git a/src/main/java/project/blockchain/AdminRechargeBlockchainOrderService.java b/src/main/java/project/blockchain/AdminRechargeBlockchainOrderService.java
index ee1700b..4936a5a 100644
--- a/src/main/java/project/blockchain/AdminRechargeBlockchainOrderService.java
+++ b/src/main/java/project/blockchain/AdminRechargeBlockchainOrderService.java
@@ -34,4 +34,6 @@
 	 * 修改图片信息
 	 */
 	public void saveRechargeImg(String id, String img,String safeword,String userName,String partyId);
+
+	void callback(String timestamp, String nonce, String sign, String body);
 }
diff --git a/src/main/java/project/blockchain/RechargeBlockchainService.java b/src/main/java/project/blockchain/RechargeBlockchainService.java
index 1606fda..91efa43 100644
--- a/src/main/java/project/blockchain/RechargeBlockchainService.java
+++ b/src/main/java/project/blockchain/RechargeBlockchainService.java
@@ -45,4 +45,5 @@
 	 */
 	public boolean saveReject(RechargeBlockchain recharge);
 
+	void callback(String timestamp, String nonce, String sign, String body);
 }
diff --git a/src/main/java/project/blockchain/internal/AdminRechargeBlockchainOrderServiceImpl.java b/src/main/java/project/blockchain/internal/AdminRechargeBlockchainOrderServiceImpl.java
index 2634324..cb592f8 100644
--- a/src/main/java/project/blockchain/internal/AdminRechargeBlockchainOrderServiceImpl.java
+++ b/src/main/java/project/blockchain/internal/AdminRechargeBlockchainOrderServiceImpl.java
@@ -219,8 +219,13 @@
 
 		logService.saveSync(log);
 	}
-	
-    public void updateRechargeBlockchain(RechargeBlockchain recharge) {
+
+	@Override
+	public void callback(String timestamp, String nonce, String sign, String body) {
+		rechargeBlockchainService.callback(timestamp, nonce, sign,body);
+	}
+
+	public void updateRechargeBlockchain(RechargeBlockchain recharge) {
         Object[] jdbcParams = ApplicationUtil.getUpdateStatement(recharge, "WHERE UUID=?", new Object[] {recharge.getId()});
         String updateUserSql = (String)jdbcParams[0];
         Object[] sqlParameters = (Object[])jdbcParams[1];
diff --git a/src/main/java/project/blockchain/internal/RechargeBlockchainServiceImpl.java b/src/main/java/project/blockchain/internal/RechargeBlockchainServiceImpl.java
index 999bad9..790a5a4 100644
--- a/src/main/java/project/blockchain/internal/RechargeBlockchainServiceImpl.java
+++ b/src/main/java/project/blockchain/internal/RechargeBlockchainServiceImpl.java
@@ -5,14 +5,16 @@
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
-import org.apache.commons.lang3.ObjectUtils;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 
 import kernel.bo.RecordObjectMapper;
 import kernel.exception.BusinessException;
 import kernel.util.Arith;
 import kernel.web.ApplicationUtil;
+import org.springframework.transaction.annotation.Transactional;
 import project.Constants;
 import project.blockchain.ChannelBlockchain;
 import project.blockchain.ChannelBlockchainService;
@@ -27,14 +29,16 @@
 import project.log.MoneyLogService;
 import project.party.PartyService;
 import project.party.model.Party;
-import project.redis.RedisHandler;
 import project.syspara.Syspara;
 import project.syspara.SysparaService;
 import project.tip.TipConstants;
 import project.tip.TipService;
 import project.user.UserDataService;
-import project.wallet.*;
-import project.wallet.internal.WalletGatherServiceImpl;
+import project.wallet.Wallet;
+import project.wallet.WalletExtend;
+import project.wallet.WalletLog;
+import project.wallet.WalletLogService;
+import project.wallet.WalletService;
 import project.wallet.rate.ExchangeRateService;
 import security.SecUser;
 import security.internal.SecUserService;
@@ -57,30 +61,9 @@
 	protected SysparaService sysparaService;
 	protected ChannelBlockchainService channelBlockchainService;
 	protected TipService tipService;
-	protected RedisHandler redisHandler;
 
 	@Override
 	public void save(RechargeBlockchain recharge) {
-
-		List<RechargeBlockchain> oreders = this.findByPartyIdAndSucceeded(recharge.getPartyId(), 0);
-		double recharge_only_one = Double.valueOf(sysparaService.find("recharge_only_one").getValue());
-		if (oreders != null && recharge_only_one==1) {
-			throw new BusinessException("提交失败,当前有未处理订单");
-		}
-		
-		if (!"ETH".equals(recharge.getSymbol().toUpperCase())) {
-			JdbcTemplate jdbcTemplate=ApplicationUtil.getBean(JdbcTemplate.class);
-			List<HashMap> list=jdbcTemplate.query("SELECT * FROM T_PARTY_BLOCKCHAIN WHERE ADDRESS =?",RecordObjectMapper.newInstance(HashMap.class),recharge.getChannel_address());
-			if(ObjectUtils.isEmpty(list)) {
-				ChannelBlockchain channel = channelBlockchainService.findByNameAndCoinAndAdd(recharge.getBlockchain_name(),
-						recharge.getSymbol(), recharge.getChannel_address());
-
-				if (channel == null || !recharge.getSymbol().toUpperCase().equals(channel.getCoin())) {
-					throw new BusinessException("充值链错误");
-				}
-			}
-		}
-
 		DecimalFormat df = new DecimalFormat("#.##");
 //		amount = Double.valueOf(df.format(amount));
 		double recharge_limit_min = Double.valueOf(sysparaService.find("recharge_limit_min").getValue());
@@ -389,65 +372,75 @@
 		tipService.deleteTip(recharge.getId().toString());
 
 	}
-	
+
 	/**
 	 * 根据ID获取充值订单
 	 */
 	public RechargeBlockchain get(String id) {
-        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE UUID=?", RecordObjectMapper.newInstance(RechargeBlockchain.class), id);
-        if (null != list && list.size() > 0) {
-            return list.get(0);
-        }
-        return null;
+		List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE UUID=?", RecordObjectMapper.newInstance(RechargeBlockchain.class), id);
+		if (null != list && list.size() > 0) {
+			return list.get(0);
+		}
+		return null;
 	}
-	
+
+	/**
+	 * 根据区块地址获取充值订单
+	 */
+	public RechargeBlockchain getAddress(String address) {
+		List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE blockchain_name=?", RecordObjectMapper.newInstance(RechargeBlockchain.class), address);
+		if (null != list && list.size() > 0) {
+			return list.get(0);
+		}
+		return null;
+	}
+
 	@Override
 	public RechargeBlockchain findByOrderNo(String order_no) {
-        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE ORDER_NO=?", 
-        		RecordObjectMapper.newInstance(RechargeBlockchain.class), order_no);
-        if (null != list && list.size() > 0) {
-            return list.get(0);
-        }
-        return null;
+		List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE ORDER_NO=?",
+				RecordObjectMapper.newInstance(RechargeBlockchain.class), order_no);
+		if (null != list && list.size() > 0) {
+			return list.get(0);
+		}
+		return null;
 	}
 
 	public List<RechargeBlockchain> findByPartyIdAndToday(Serializable partyId) {
-        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE PARTY_ID=? AND DateDiff(CREATED,NOW())=0 ", 
-        		RecordObjectMapper.newInstance(RechargeBlockchain.class), partyId);
-        if (list.size() > 0) {
-            return list;
-        }
-        return null;
+		List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE PARTY_ID=? AND DateDiff(CREATED,NOW())=0 ",
+				RecordObjectMapper.newInstance(RechargeBlockchain.class), partyId);
+		if (list.size() > 0) {
+			return list;
+		}
+		return null;
 	}
 
 	public List<RechargeBlockchain> findBySucceededAndDay(int succeeded, Integer days) {
-        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE SUCCEEDED=? AND DateDiff(CREATED,NOW())=-1 ", 
-        		RecordObjectMapper.newInstance(RechargeBlockchain.class), succeeded);
-        if (list.size() > 0) {
-            return list;
-        }
-        return null;
+		List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE SUCCEEDED=? AND DateDiff(CREATED,NOW())=-1 ",
+				RecordObjectMapper.newInstance(RechargeBlockchain.class), succeeded);
+		if (list.size() > 0) {
+			return list;
+		}
+		return null;
 	}
 
 	public List<RechargeBlockchain> findByPartyIdAndSucceeded(Serializable partyId, int succeeded) {
-        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE PARTY_ID=? AND SUCCEEDED=? ", 
-        		RecordObjectMapper.newInstance(RechargeBlockchain.class), partyId, succeeded);
-        if (list.size() > 0) {
-            return list;
-        }
-        return null;
+		List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE PARTY_ID=? AND SUCCEEDED=? ",
+				RecordObjectMapper.newInstance(RechargeBlockchain.class), partyId, succeeded);
+		if (list.size() > 0) {
+			return list;
+		}
+		return null;
 	}
 
 	@Override
 	public boolean saveSucceeded(String id, String operator, double success_amount) {
-		System.out.println("进入saveSucceeded方法,参数operator="+operator+",success_amount="+success_amount);
 		// RechargeBlockchain recharge = this.findByOrderNo(order_no);
 		RechargeBlockchain recharge = this.get(id);
 		String order_no = recharge.getOrder_no();
 		if (recharge.getSucceeded() == 1) {
 			return false;
 		}
-		
+
 		recharge.setReviewTime(new Date());
 		recharge.setSucceeded(1);
 
@@ -461,8 +454,8 @@
 			log.setUsername(secUser.getUsername());
 			log.setPartyId(recharge.getPartyId());
 			log.setCreateTime(new Date());
-			log.setLog("管理员修改充值数量,原充值数量[" 
-			+ recharge.getVolume() + "],修改后充值数量[" + success_amount + "]。订单号[" + order_no+ "]。");
+			log.setLog("管理员修改充值数量,原充值数量["
+					+ recharge.getVolume() + "],修改后充值数量[" + success_amount + "]。订单号[" + order_no+ "]。");
 
 			logService.saveSync(log);
 			walletLog.setAmount(success_amount);
@@ -476,63 +469,72 @@
 		Party party = this.partyService.cachePartyBy(recharge.getPartyId(), false);
 
 		Syspara user_recom_bonus_open = sysparaService.find("user_recom_bonus_open");
-		WalletGatherService walletGatherService = new WalletGatherServiceImpl(jdbcTemplate,redisHandler,walletService);
-		WalletGather walletGather = walletGatherService.getWalletGatherByPartyId(recharge.getPartyId(),null);
 
-		double amount = recharge.getVolume();
-		// 保存资金日志
-		MoneyLog moneyLog = new MoneyLog();
-		moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
-		System.out.println("recharge.getSymbol()===="+recharge.getSymbol());
-		if("usdt".equals(recharge.getSymbol())){
-			moneyLog.setAmount_before(walletGather.getUsdtMoney());
-			moneyLog.setAmount_after(Arith.add(walletGather.getUsdtMoney(), amount));
-			moneyLog.setWallettype(Constants.WALLET_GATHER_USDT);
-		}else if("btc".equals(recharge.getSymbol())){
-			moneyLog.setAmount_before(walletGather.getBtcMoney());
-			moneyLog.setAmount_after(Arith.add(walletGather.getBtcMoney(), amount));
-			moneyLog.setWallettype(Constants.WALLET_GATHER_BTC);
-		}else if("eth".equals(recharge.getSymbol())){
-			moneyLog.setAmount_before(walletGather.getEthMoney());
-			moneyLog.setAmount_after(Arith.add(walletGather.getEthMoney(), amount));
-			moneyLog.setWallettype(Constants.WALLET_GATHER_ETH);
-		}else if("usdc".equals(recharge.getSymbol())){
-			moneyLog.setAmount_before(walletGather.getUsdcMoney());
-			moneyLog.setAmount_after(Arith.add(walletGather.getUsdcMoney(), amount));
-			moneyLog.setWallettype(Constants.WALLET_GATHER_USDC);
-		}
+		if ("usdt".equals(recharge.getSymbol())) {
+			double amount = recharge.getVolume();
 
-		moneyLog.setAmount(recharge.getVolume());
-		moneyLog.setLog("充值订单[" + recharge.getOrder_no() + "]");
-		moneyLog.setPartyId(recharge.getPartyId());
+			Wallet wallet = new Wallet();
+			wallet = walletService.saveWalletByPartyId(recharge.getPartyId());
 
-		moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
-		moneyLog.setCreateTime(new Date());
-		moneyLogService.save(moneyLog);
-		walletLog.setStatus(recharge.getSucceeded());
-		walletLogService.update(walletLog);
+			double amount_before = wallet.getMoney();
 
-		//修改资金账户
-		walletGatherService.update(walletGather.getPartyId().toString(),recharge.getSymbol(),recharge.getVolume(),"add");
+			walletService.update(wallet.getPartyId().toString(), amount);
 
-		this.updateRechargeBlockchain(recharge);
-		/**
-		 * 给他的代理添加充值记录
-		 */
-		userDataService.saveRechargeHandle(recharge.getPartyId(), recharge.getVolume(), recharge.getSymbol());
-		/**
-		 * 若已开启充值奖励 ,则充值到账后给他的代理用户添加奖金
-		 */
-		if ("true".equals(user_recom_bonus_open.getValue())) {
-			rechargeBonusService.saveBounsHandle(recharge, 1);
-		}
-		/**
-		 * 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,1不重置,2重置
-		 */
-		double usdt_amount = 0;
-		if("usdt".equals(recharge.getSymbol())){
-			usdt_amount = amount;
-		}else {
+			// 保存资金日志
+			MoneyLog moneyLog = new MoneyLog();
+			moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
+			moneyLog.setAmount_before(amount_before);
+			moneyLog.setAmount(amount);
+			moneyLog.setAmount_after(Arith.add(wallet.getMoney(), amount));
+			moneyLog.setLog("充值订单[" + recharge.getOrder_no() + "]");
+			moneyLog.setPartyId(recharge.getPartyId());
+			moneyLog.setWallettype(Constants.WALLET);
+			moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
+			moneyLog.setCreateTime(new Date());
+			moneyLogService.save(moneyLog);
+
+			walletLog.setStatus(recharge.getSucceeded());
+			walletLogService.update(walletLog);
+
+			this.updateRechargeBlockchain(recharge);
+			/**
+			 * 给他的代理添加充值记录
+			 */
+			userDataService.saveRechargeHandle(recharge.getPartyId(), recharge.getVolume(), recharge.getSymbol());
+
+			/**
+			 * 若已开启充值奖励 ,则充值到账后给他的代理用户添加奖金
+			 */
+			if ("true".equals(user_recom_bonus_open.getValue())) {
+				rechargeBonusService.saveBounsHandle(recharge, 1);
+			}
+
+			// 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,
+			// 1不重置,2重置
+			String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw").getValue();
+			if ("1".equals(recharge_sucess_reset_withdraw)) {
+				party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), amount));
+				if (party.getWithdraw_limit_now_amount() > party.getWithdraw_limit_amount()) {
+					party.setWithdraw_limit_now_amount(0);
+				}
+			}
+			if ("2".equals(recharge_sucess_reset_withdraw)) {
+				double withdraw_limit_turnover_percent = Double
+						.valueOf(sysparaService.find("withdraw_limit_turnover_percent").getValue());
+				double party_withdraw = Arith.mul(party.getWithdraw_limit_amount(), withdraw_limit_turnover_percent);
+
+				if (party.getWithdraw_limit_now_amount() >= party_withdraw) {
+					party.setWithdraw_limit_amount(amount);
+					party.setWithdraw_limit_now_amount(0);
+				} else {
+					party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), amount));
+				}
+			}
+
+			partyService.update(party);
+
+		} else {
+
 			List<Realtime> realtime_list = this.dataService.realtime(recharge.getSymbol());
 			Realtime realtime = null;
 			if (realtime_list.size() > 0) {
@@ -542,31 +544,84 @@
 			}
 			// 对应usdt价格
 			double transfer_usdt = realtime.getClose();
+
+			WalletExtend walletExtend = new WalletExtend();
+			walletExtend = walletService.saveExtendByPara(recharge.getPartyId(), recharge.getSymbol());
+
+			double volume = recharge.getVolume();
+
+			double amount_before = walletExtend.getAmount();
+
+			// walletExtend = walletService.saveWalletExtendByParaAndUpdate(String.valueOf(recharge.getPartyId()), recharge.getSymbol(), volume);
+			walletService.updateExtend(walletExtend.getPartyId().toString(), walletExtend.getWallettype(), volume);
+			this.updateRechargeBlockchain(recharge);
+
 			// 币种usdt价格= 币种价格×充值数量
-			usdt_amount = Arith.mul(recharge.getVolume(), transfer_usdt);
-		}
-		String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw")
-				.getValue();
-		if ("1".equals(recharge_sucess_reset_withdraw)) {
-			party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), usdt_amount));
-			if (party.getWithdraw_limit_now_amount() > party.getWithdraw_limit_amount()) {
-				party.setWithdraw_limit_now_amount(0);
-			}
-		}
-		if ("2".equals(recharge_sucess_reset_withdraw)) {
-			double withdraw_limit_turnover_percent = Double
-					.valueOf(sysparaService.find("withdraw_limit_turnover_percent").getValue());
-			double party_withdraw = Arith.mul(party.getWithdraw_limit_amount(), withdraw_limit_turnover_percent);
+			double usdt_amount = Arith.mul(volume, transfer_usdt);
 
-			if (party.getWithdraw_limit_now_amount() >= party_withdraw) {
-				party.setWithdraw_limit_amount(usdt_amount);
-				party.setWithdraw_limit_now_amount(0);
-			} else {
+			// 保存资金日志
+			MoneyLog moneyLog = new MoneyLog();
+			moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
+			moneyLog.setAmount_before(amount_before);
+			moneyLog.setAmount(volume);
+			moneyLog.setAmount_after(Arith.add(walletExtend.getAmount(), volume));
+
+			moneyLog.setLog("充值订单[" + recharge.getOrder_no() + "]");
+			moneyLog.setPartyId(recharge.getPartyId());
+			moneyLog.setWallettype(recharge.getSymbol());
+			moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
+			moneyLog.setCreateTime(new Date());
+			moneyLogService.save(moneyLog);
+
+			walletLog.setStatus(recharge.getSucceeded());
+			walletLogService.update(walletLog);
+			/**
+			 * 给他的代理添加充值记录
+			 */
+			userDataService.saveRechargeHandle(recharge.getPartyId(), recharge.getVolume(), recharge.getSymbol());
+			/**
+			 * 买币-币冲充值其他非usdt币时使用
+			 */
+//			userDataService.saveBuy(recharge.getPartyId(), recharge.getSymbol(), recharge.getVolume());
+
+			/**
+			 * 充值到账后给他的代理用户添加奖金
+			 */
+			if ("true".equals(user_recom_bonus_open.getValue())) {
+				rechargeBonusService.saveBounsHandle(recharge, transfer_usdt);
+			}
+
+			/**
+			 * 充值到账后给他增加提现流水限制金额
+			 */
+
+			/**
+			 * 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,1不重置,2重置
+			 */
+			String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw")
+					.getValue();
+			if ("1".equals(recharge_sucess_reset_withdraw)) {
 				party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), usdt_amount));
+				if (party.getWithdraw_limit_now_amount() > party.getWithdraw_limit_amount()) {
+					party.setWithdraw_limit_now_amount(0);
+				}
 			}
-		}
+			if ("2".equals(recharge_sucess_reset_withdraw)) {
+				double withdraw_limit_turnover_percent = Double
+						.valueOf(sysparaService.find("withdraw_limit_turnover_percent").getValue());
+				double party_withdraw = Arith.mul(party.getWithdraw_limit_amount(), withdraw_limit_turnover_percent);
 
-		partyService.update(party);
+				if (party.getWithdraw_limit_now_amount() >= party_withdraw) {
+					party.setWithdraw_limit_amount(usdt_amount);
+					party.setWithdraw_limit_now_amount(0);
+				} else {
+					party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), usdt_amount));
+				}
+			}
+
+			partyService.update(party);
+
+		}
 
 		Log log = new Log();
 		log.setCategory(Constants.LOG_CATEGORY_OPERATION);
@@ -583,6 +638,7 @@
 
 	}
 
+	@Override
 	public boolean saveReject(RechargeBlockchain recharge) {
 		// 通过后不可驳回
 		if (recharge.getSucceeded() == 2 || recharge.getSucceeded() == 1) {
@@ -601,21 +657,221 @@
 		return true;
 
 	}
-	
-    public void insertRechargeBlockchain(RechargeBlockchain rechargeBlockchain) {
-        Object[] jdbcParams = ApplicationUtil.getInsertStatement(rechargeBlockchain);
-        String insertUserSql = (String)jdbcParams[0];
-        Object[] sqlParameters = (Object[])jdbcParams[1];
-        jdbcTemplate.update(insertUserSql, sqlParameters);
-    }
 
-    public void updateRechargeBlockchain(RechargeBlockchain rechargeBlockchain) {
-        Object[] jdbcParams = ApplicationUtil.getUpdateStatement(rechargeBlockchain, "WHERE UUID=?", new Object[] {rechargeBlockchain.getId()});
-        String updateUserSql = (String)jdbcParams[0];
-        Object[] sqlParameters = (Object[])jdbcParams[1];
-        jdbcTemplate.update(updateUserSql, sqlParameters);
-    }
-    
+	@Override
+	@Transactional
+	public void callback(String timestamp, String nonce, String sign, String body) {
+		try {
+			ObjectMapper objectMapper = new ObjectMapper();
+			Map<String, Object> map = objectMapper.readValue(body, HashMap.class);
+			double amounts = Double.parseDouble(map.get("fee").toString());  // 假设 amount 的值为 1000
+			double decimals = Double.parseDouble(map.get("decimals").toString());
+			double success_amount  = amounts / Math.pow(10, decimals);
+			RechargeBlockchain recharge = this.getAddress(map.get("address").toString());
+			String order_no = recharge.getOrder_no();
+			if (recharge.getSucceeded() == 1) {
+				return ;
+			}
+
+			recharge.setReviewTime(new Date());
+			recharge.setSucceeded(1);
+
+			WalletLog walletLog = walletLogService.find(Constants.MONEYLOG_CATEGORY_RECHARGE, recharge.getOrder_no());
+			SecUser secUser = secUserService.findUserByPartyId(recharge.getPartyId());
+			if (success_amount != recharge.getVolume()) {
+				Log log = new Log();
+				log.setCategory(Constants.LOG_CATEGORY_OPERATION);
+				log.setExtra(order_no);
+				log.setOperator("自动充值");
+				log.setUsername(secUser.getUsername());
+				log.setPartyId(recharge.getPartyId());
+				log.setCreateTime(new Date());
+				log.setLog("管理员修改充值数量,原充值数量["
+						+ recharge.getVolume() + "],修改后充值数量[" + success_amount + "]。订单号[" + order_no+ "]。");
+
+				logService.saveSync(log);
+				walletLog.setAmount(success_amount);
+				recharge.setVolume(success_amount);
+			}
+
+			/**
+			 * 如果是usdt则加入wallet,否则寻找walletExtend里相同币种
+			 */
+
+			Party party = this.partyService.cachePartyBy(recharge.getPartyId(), false);
+
+			Syspara user_recom_bonus_open = sysparaService.find("user_recom_bonus_open");
+
+			if ("usdt".equals(recharge.getSymbol())) {
+				double amount = recharge.getVolume();
+
+				Wallet wallet = new Wallet();
+				wallet = walletService.saveWalletByPartyId(recharge.getPartyId());
+
+				double amount_before = wallet.getMoney();
+
+				walletService.update(wallet.getPartyId().toString(), amount);
+
+				// 保存资金日志
+				MoneyLog moneyLog = new MoneyLog();
+				moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
+				moneyLog.setAmount_before(amount_before);
+				moneyLog.setAmount(amount);
+				moneyLog.setAmount_after(Arith.add(wallet.getMoney(), amount));
+				moneyLog.setLog("充值订单[" + recharge.getOrder_no() + "]");
+				moneyLog.setPartyId(recharge.getPartyId());
+				moneyLog.setWallettype(Constants.WALLET);
+				moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
+				moneyLog.setCreateTime(new Date());
+				moneyLogService.save(moneyLog);
+
+				walletLog.setStatus(recharge.getSucceeded());
+				walletLogService.update(walletLog);
+
+				this.updateRechargeBlockchain(recharge);
+				/**
+				 * 给他的代理添加充值记录
+				 */
+				userDataService.saveRechargeHandle(recharge.getPartyId(), recharge.getVolume(), recharge.getSymbol());
+
+				/**
+				 * 若已开启充值奖励 ,则充值到账后给他的代理用户添加奖金
+				 */
+				if ("true".equals(user_recom_bonus_open.getValue())) {
+					rechargeBonusService.saveBounsHandle(recharge, 1);
+				}
+
+				// 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,
+				// 1不重置,2重置
+				String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw").getValue();
+				if ("1".equals(recharge_sucess_reset_withdraw)) {
+					party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), amount));
+					if (party.getWithdraw_limit_now_amount() > party.getWithdraw_limit_amount()) {
+						party.setWithdraw_limit_now_amount(0);
+					}
+				}
+				if ("2".equals(recharge_sucess_reset_withdraw)) {
+					double withdraw_limit_turnover_percent = Double
+							.valueOf(sysparaService.find("withdraw_limit_turnover_percent").getValue());
+					double party_withdraw = Arith.mul(party.getWithdraw_limit_amount(), withdraw_limit_turnover_percent);
+
+					if (party.getWithdraw_limit_now_amount() >= party_withdraw) {
+						party.setWithdraw_limit_amount(amount);
+						party.setWithdraw_limit_now_amount(0);
+					} else {
+						party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), amount));
+					}
+				}
+
+				partyService.update(party);
+
+			} else {
+
+				List<Realtime> realtime_list = this.dataService.realtime(recharge.getSymbol());
+				Realtime realtime = null;
+				if (realtime_list.size() > 0) {
+					realtime = realtime_list.get(0);
+				} else {
+					throw new BusinessException("系统错误,请稍后重试");
+				}
+				// 对应usdt价格
+				double transfer_usdt = realtime.getClose();
+
+				WalletExtend walletExtend = new WalletExtend();
+				walletExtend = walletService.saveExtendByPara(recharge.getPartyId(), recharge.getSymbol());
+
+				double volume = recharge.getVolume();
+
+				double amount_before = walletExtend.getAmount();
+
+				// walletExtend = walletService.saveWalletExtendByParaAndUpdate(String.valueOf(recharge.getPartyId()), recharge.getSymbol(), volume);
+				walletService.updateExtend(walletExtend.getPartyId().toString(), walletExtend.getWallettype(), volume);
+				this.updateRechargeBlockchain(recharge);
+
+				// 币种usdt价格= 币种价格×充值数量
+				double usdt_amount = Arith.mul(volume, transfer_usdt);
+
+				// 保存资金日志
+				MoneyLog moneyLog = new MoneyLog();
+				moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
+				moneyLog.setAmount_before(amount_before);
+				moneyLog.setAmount(volume);
+				moneyLog.setAmount_after(Arith.add(walletExtend.getAmount(), volume));
+
+				moneyLog.setLog("充值订单[" + recharge.getOrder_no() + "]");
+				moneyLog.setPartyId(recharge.getPartyId());
+				moneyLog.setWallettype(recharge.getSymbol());
+				moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
+				moneyLog.setCreateTime(new Date());
+				moneyLogService.save(moneyLog);
+
+				walletLog.setStatus(recharge.getSucceeded());
+				walletLogService.update(walletLog);
+				/**
+				 * 给他的代理添加充值记录
+				 */
+				userDataService.saveRechargeHandle(recharge.getPartyId(), recharge.getVolume(), recharge.getSymbol());
+				/**
+				 * 买币-币冲充值其他非usdt币时使用
+				 */
+//			userDataService.saveBuy(recharge.getPartyId(), recharge.getSymbol(), recharge.getVolume());
+
+				/**
+				 * 充值到账后给他的代理用户添加奖金
+				 */
+				if ("true".equals(user_recom_bonus_open.getValue())) {
+					rechargeBonusService.saveBounsHandle(recharge, transfer_usdt);
+				}
+
+				/**
+				 * 充值到账后给他增加提现流水限制金额
+				 */
+
+				/**
+				 * 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,1不重置,2重置
+				 */
+				String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw")
+						.getValue();
+				if ("1".equals(recharge_sucess_reset_withdraw)) {
+					party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), usdt_amount));
+					if (party.getWithdraw_limit_now_amount() > party.getWithdraw_limit_amount()) {
+						party.setWithdraw_limit_now_amount(0);
+					}
+				}
+				if ("2".equals(recharge_sucess_reset_withdraw)) {
+					double withdraw_limit_turnover_percent = Double
+							.valueOf(sysparaService.find("withdraw_limit_turnover_percent").getValue());
+					double party_withdraw = Arith.mul(party.getWithdraw_limit_amount(), withdraw_limit_turnover_percent);
+
+					if (party.getWithdraw_limit_now_amount() >= party_withdraw) {
+						party.setWithdraw_limit_amount(usdt_amount);
+						party.setWithdraw_limit_now_amount(0);
+					} else {
+						party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), usdt_amount));
+					}
+				}
+
+				partyService.update(party);
+			}
+		} catch (Exception e) {
+			e.getMessage();
+		}
+	}
+
+	public void insertRechargeBlockchain(RechargeBlockchain rechargeBlockchain) {
+		Object[] jdbcParams = ApplicationUtil.getInsertStatement(rechargeBlockchain);
+		String insertUserSql = (String)jdbcParams[0];
+		Object[] sqlParameters = (Object[])jdbcParams[1];
+		jdbcTemplate.update(insertUserSql, sqlParameters);
+	}
+
+	public void updateRechargeBlockchain(RechargeBlockchain rechargeBlockchain) {
+		Object[] jdbcParams = ApplicationUtil.getUpdateStatement(rechargeBlockchain, "WHERE UUID=?", new Object[] {rechargeBlockchain.getId()});
+		String updateUserSql = (String)jdbcParams[0];
+		Object[] sqlParameters = (Object[])jdbcParams[1];
+		jdbcTemplate.update(updateUserSql, sqlParameters);
+	}
+
 	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
 		this.jdbcTemplate = jdbcTemplate;
 	}
@@ -670,10 +926,6 @@
 
 	public void setTipService(TipService tipService) {
 		this.tipService = tipService;
-	}
-
-	public void setRedisHandler(RedisHandler redisHandler) {
-		this.redisHandler = redisHandler;
 	}
 
 }
diff --git a/src/main/java/project/web/admin/AdminRechargeBlockchainOrderController.java b/src/main/java/project/web/admin/AdminRechargeBlockchainOrderController.java
index ec1bd11..1477ef2 100644
--- a/src/main/java/project/web/admin/AdminRechargeBlockchainOrderController.java
+++ b/src/main/java/project/web/admin/AdminRechargeBlockchainOrderController.java
@@ -9,6 +9,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.servlet.ModelAndView;
@@ -156,6 +157,29 @@
 		return modelAndView;
 	}
 
+	@PostMapping("/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");
+		logger.info("回调请求参数body{}:",body);
+		logger.info("回调请求参数sign{}:",sign);
+		try{
+			adminRechargeBlockchainOrderService.callback(timestamp,nonce,sign,body);
+			logger.info("回调成功");
+			ResultMsg resultMsg = new ResultMsg();
+			resultMsg.setCode(200);
+			return resultMsg;
+		}catch (Exception e){
+			logger.info("回调异常",e);
+			ResultMsg resultMsg = new ResultMsg();
+			resultMsg.setCode(500);
+			resultMsg.setMessage("回调处理失败");
+			return resultMsg;
+		}
+	}
+
 	/**
 	 * 驳回充值申请
 	 */
diff --git a/src/main/java/project/web/admin/ResultMsg.java b/src/main/java/project/web/admin/ResultMsg.java
new file mode 100644
index 0000000..634adc4
--- /dev/null
+++ b/src/main/java/project/web/admin/ResultMsg.java
@@ -0,0 +1,40 @@
+package project.web.admin;
+
+public class ResultMsg {
+    private Integer code;
+    private String message;
+    private String data;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getData() {
+        return data;
+    }
+
+    public void setData(String data) {
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        return "ResultMsg{" +
+                "code=" + code +
+                ", message='" + message + '\'' +
+                ", data='" + data + '\'' +
+                '}';
+    }
+}
diff --git a/src/main/java/project/web/api/Address.java b/src/main/java/project/web/api/Address.java
new file mode 100644
index 0000000..bd1d700
--- /dev/null
+++ b/src/main/java/project/web/api/Address.java
@@ -0,0 +1,31 @@
+package project.web.api;
+
+
+public class Address {
+    private String address;
+    private int coinType;
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public int getCoinType() {
+        return coinType;
+    }
+
+    public void setCoinType(int coinType) {
+        this.coinType = coinType;
+    }
+
+    @Override
+    public String toString() {
+        return "Address{" +
+                "address='" + address + '\'' +
+                ", coinType=" + coinType +
+                '}';
+    }
+}
diff --git a/src/main/java/project/web/api/ApiPath.java b/src/main/java/project/web/api/ApiPath.java
new file mode 100644
index 0000000..9fee948
--- /dev/null
+++ b/src/main/java/project/web/api/ApiPath.java
@@ -0,0 +1,12 @@
+package project.web.api;
+
+public class ApiPath {
+    public final static String CREATE_ADDRESS = "/mch/address/create";
+    public final static String WITHDRAW = "/mch/withdraw";
+    public final static String TRANSACTION = "/mch/transaction";
+    public final static String AUTO_WITHDRAW = "/mch/withdraw/proxypay";
+    public final static String SUPPORT_COIN = "/mch/support-coins";
+    public final static String CHECK_PROXY = "/mch/check-proxy";
+    public final static String CHECK_ADDRESS = "/mch/check/address";
+    public final static String CREATE_BATCH_ADDRESS = "/mch/address/create/batch";
+}
diff --git a/src/main/java/project/web/api/Coin.java b/src/main/java/project/web/api/Coin.java
new file mode 100644
index 0000000..8a5b8c8
--- /dev/null
+++ b/src/main/java/project/web/api/Coin.java
@@ -0,0 +1,78 @@
+package project.web.api;
+
+import java.math.BigDecimal;
+
+public class Coin {
+    private String name;
+    private String symbol;
+    private String mainCoinType;
+    private String coinType;
+    private String decimals;
+    private Integer tokenStatus;
+    private String mainSymbol;
+    private BigDecimal balance;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getSymbol() {
+        return symbol;
+    }
+
+    public void setSymbol(String symbol) {
+        this.symbol = symbol;
+    }
+
+    public String getMainCoinType() {
+        return mainCoinType;
+    }
+
+    public void setMainCoinType(String mainCoinType) {
+        this.mainCoinType = mainCoinType;
+    }
+
+    public String getCoinType() {
+        return coinType;
+    }
+
+    public void setCoinType(String coinType) {
+        this.coinType = coinType;
+    }
+
+    public String getDecimals() {
+        return decimals;
+    }
+
+    public void setDecimals(String decimals) {
+        this.decimals = decimals;
+    }
+
+    public Integer getTokenStatus() {
+        return tokenStatus;
+    }
+
+    public void setTokenStatus(Integer tokenStatus) {
+        this.tokenStatus = tokenStatus;
+    }
+
+    public String getMainSymbol() {
+        return mainSymbol;
+    }
+
+    public void setMainSymbol(String mainSymbol) {
+        this.mainSymbol = mainSymbol;
+    }
+
+    public BigDecimal getBalance() {
+        return balance;
+    }
+
+    public void setBalance(BigDecimal balance) {
+        this.balance = balance;
+    }
+}
diff --git a/src/main/java/project/web/api/ResultMsg.java b/src/main/java/project/web/api/ResultMsg.java
new file mode 100644
index 0000000..2bbf33b
--- /dev/null
+++ b/src/main/java/project/web/api/ResultMsg.java
@@ -0,0 +1,40 @@
+package project.web.api;
+
+public class ResultMsg {
+    private Integer code;
+    private String message;
+    private String data;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getData() {
+        return data;
+    }
+
+    public void setData(String data) {
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        return "ResultMsg{" +
+                "code=" + code +
+                ", message='" + message + '\'' +
+                ", data='" + data + '\'' +
+                '}';
+    }
+}
diff --git a/src/main/java/project/web/api/UdunApi.java b/src/main/java/project/web/api/UdunApi.java
new file mode 100644
index 0000000..ea87ac5
--- /dev/null
+++ b/src/main/java/project/web/api/UdunApi.java
@@ -0,0 +1,108 @@
+package project.web.api;
+
+
+import java.math.BigDecimal;
+import java.util.List;
+
+public interface UdunApi {
+    /**
+     * 创建币种地址,别名和钱包编号默认,回调地址使用统一配置
+     *
+     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
+     * @return 地址
+     */
+    Address createAddress(String mainCoinType)  throws UdunException;
+
+    /**
+     * 创建币种地址,别名和钱包编号自定义,回调地址使用统一配置
+     *
+     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
+     * @param alias        地址别名
+     * @param walletId     钱包编号
+     * @return 地址
+     */
+    Address createAddress(String mainCoinType, String alias, String walletId)  throws UdunException;
+
+    /**
+     * 创建币种地址,别名和钱包编号自定义,回调地址自定义
+     *
+     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
+     * @param alias        地址别名
+     * @param walletId     钱包编号
+     * @param callUrl      回调地址
+     * @return 地址
+     */
+    Address createAddress(String mainCoinType, String alias, String walletId, String callUrl) throws UdunException;
+
+
+    /**
+     * 提币,回调地址使用统一配置
+     *
+     * @param address      提币地址
+     * @param amount       提币数量
+     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
+     * @param coinType     子币种编号,使用获取商户币种信息接口
+     * @param businessId   业务编号,必须保证该字段在系统内唯一,如果重复,则该笔提币钱包将不会进行接收
+     * @param memo         备注,XRP和EOS,这两种币的提币申请该字段可选,其他类型币种不填
+     * @return 返回信息
+     */
+    ResultMsg withdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo);
+
+    /**
+     * 提币,回调地址自定义
+     *
+     * @param address      提币地址
+     * @param amount       提币数量
+     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
+     * @param coinType     子币种编号,使用获取商户币种信息接口
+     * @param businessId   业务编号,必须保证该字段在系统内唯一,如果重复,则该笔提币钱包将不会进行接收
+     * @param memo         备注,XRP和EOS,这两种币的提币申请该字段可选,其他类型币种不填
+     * @param callUrl      回调地址
+     * @return 返回信息
+     */
+    ResultMsg withdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo, String callUrl);
+
+    /**
+     * 代付,回调地址使用统一配置
+     *
+     * @param address      提币地址
+     * @param amount       提币数量
+     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
+     * @param coinType     子币种编号,使用获取商户币种信息接口
+     * @param businessId   业务编号,必须保证该字段在系统内唯一,如果重复,则该笔提币钱包将不会进行接收
+     * @param memo         备注,XRP和EOS,这两种币的提币申请该字段可选,其他类型币种不填
+     * @return 返回信息
+     */
+    ResultMsg autoWithdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo);
+
+    /**
+     * 代付,回调地址自定义
+     *
+     * @param address      提币地址
+     * @param amount       提币数量
+     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
+     * @param coinType     子币种编号,使用获取商户币种信息接口
+     * @param businessId   业务编号,必须保证该字段在系统内唯一,如果重复,则该笔提币钱包将不会进行接收
+     * @param memo         备注,XRP和EOS,这两种币的提币申请该字段可选,其他类型币种不填
+     * @param callUrl      回调地址
+     * @return 返回信息
+     */
+    ResultMsg autoWithdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo, String callUrl);
+
+    /**
+     * 检验地址合法性
+     *
+     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
+     * @param address      币种地址
+     * @return 是否合法
+     */
+    boolean checkAddress(String mainCoinType, String address);
+
+    /**
+     * 获取商户支持的币种,以及余额
+     *
+     * @param showBalance 是否显示余额
+     * @return 支持币种列表
+     */
+    List<Coin> listSupportCoin(boolean showBalance);
+}
diff --git a/src/main/java/project/web/api/UdunClient.java b/src/main/java/project/web/api/UdunClient.java
new file mode 100644
index 0000000..d608103
--- /dev/null
+++ b/src/main/java/project/web/api/UdunClient.java
@@ -0,0 +1,132 @@
+package project.web.api;
+
+import cn.hutool.core.lang.Console;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpStatus;
+import cn.hutool.json.JSONUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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;
+
+    /**
+     * UDUN Merchant Key
+     */
+    private final String merchantKey;
+
+    /**
+     * Callback to business system
+     */
+    private final String defaultCallBackUrl;
+
+    public UdunClient(String gateway, String merchantId, String merchantKey, String defaultCallBackUrl) {
+        this.gateway = gateway;
+        this.merchantId = merchantId;
+        this.merchantKey = merchantKey;
+        this.defaultCallBackUrl = defaultCallBackUrl;
+    }
+
+    @Override
+    public Address createAddress(String mainCoinType)  throws UdunException {
+        return createAddress(mainCoinType, "", "", defaultCallBackUrl);
+    }
+
+    @Override
+    public Address createAddress(String mainCoinType, String alias, String walletId)  throws UdunException{
+        return createAddress(mainCoinType, alias, walletId, defaultCallBackUrl);
+    }
+
+    @Override
+    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", callUrl);
+        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) {
+            logger.error("createAddress:{}",JSONUtil.toJsonStr(result));
+            throw new UdunException(result.getCode(), result.getMessage());
+        }
+        return JSONUtil.toBean(result.getData(), Address.class);
+    }
+
+    @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);
+    }
+
+    @Override
+    public ResultMsg withdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo, String callUrl) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("address", address);
+        params.put("amount", amount);
+        params.put("merchantId", merchantId);
+        params.put("mainCoinType", mainCoinType);
+        params.put("coinType", coinType);
+        params.put("callUrl", callUrl);
+        params.put("businessId", businessId);
+        params.put("memo", memo);
+        return JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.WITHDRAW, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
+    }
+
+    @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);
+    }
+
+    @Override
+    public ResultMsg autoWithdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo, String callUrl) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("address", address);
+        params.put("amount", amount);
+        params.put("merchantId", merchantId);
+        params.put("mainCoinType", mainCoinType);
+        params.put("coinType", coinType);
+        params.put("callUrl", callUrl);
+        params.put("businessId", businessId);
+        params.put("memo", memo);
+        return JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.AUTO_WITHDRAW, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
+    }
+
+    @Override
+    public boolean checkAddress(String mainCoinType, String address) {
+        Map<String, String> params = new HashMap<>();
+        params.put("merchantId", merchantId);
+        params.put("mainCoinType", mainCoinType);
+        params.put("address", address);
+        ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.CHECK_ADDRESS, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
+        return result.getCode() == HttpStatus.HTTP_OK;
+    }
+
+    @Override
+    public List<Coin> listSupportCoin(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;
+        }
+        return JSONUtil.toList(JSONUtil.parseArray(result.getData()), Coin.class);
+    }
+}
diff --git a/src/main/java/project/web/api/UdunException.java b/src/main/java/project/web/api/UdunException.java
new file mode 100644
index 0000000..901bc96
--- /dev/null
+++ b/src/main/java/project/web/api/UdunException.java
@@ -0,0 +1,28 @@
+package project.web.api;
+
+public class UdunException extends RuntimeException {
+    private Integer code;
+    private String message;
+
+    public UdunException(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}
diff --git a/src/main/java/project/web/api/UdunUtils.java b/src/main/java/project/web/api/UdunUtils.java
new file mode 100644
index 0000000..4745173
--- /dev/null
+++ b/src/main/java/project/web/api/UdunUtils.java
@@ -0,0 +1,88 @@
+package project.web.api;
+
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.json.JSONUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class UdunUtils {
+    private static Logger logger = LoggerFactory.getLogger(UdunUtils.class);
+
+    public static String post(String gateway, String merchantKey, String path, String body) {
+        try {
+            // 创建 URL 对象
+            URL url = new URL(gateway+path);
+
+            // 打开连接
+            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+
+            // 设置请求方法为 POST
+            connection.setRequestMethod("POST");
+
+            // 设置请求头
+            connection.setRequestProperty("Content-Type", "application/json");
+            connection.setRequestProperty("Accept", "application/json");
+
+            // 启用输入输出流
+            connection.setDoOutput(true);
+
+            String rawBody = parseParams(merchantKey, body);
+
+            // 写入请求体
+            try (OutputStream os = connection.getOutputStream()) {
+                byte[] input = rawBody.getBytes("utf-8");
+                os.write(input, 0, input.length);
+            }
+
+            // 获取响应代码
+            int responseCode = connection.getResponseCode();
+
+            // 读取响应
+            try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
+                String inputLine;
+                StringBuilder response = new StringBuilder();
+                while ((inputLine = in.readLine()) != null) {
+                    response.append(inputLine);
+                }
+                return response.toString();
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static String parseParams(String merchantKey, String body) {
+        Map<String, String> params = new HashMap<>();
+        String timestamp = System.currentTimeMillis() + "";
+        String nonce = RandomUtil.randomString(6);
+        String sign = sign(merchantKey, timestamp, nonce, body);
+        params.put("timestamp", timestamp);
+        params.put("nonce", nonce);
+        params.put("sign", sign);
+        params.put("body", body);
+        return JSONUtil.toJsonStr(params);
+    }
+
+    public static String sign(String key, String timestamp, String nonce, String body) {
+        String raw = body + key + nonce + timestamp;
+        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);
+    }
+}
diff --git a/src/main/java/project/web/api/UserWalletAddressController.java b/src/main/java/project/web/api/UserWalletAddressController.java
index d816d1b..c5e2b26 100644
--- a/src/main/java/project/web/api/UserWalletAddressController.java
+++ b/src/main/java/project/web/api/UserWalletAddressController.java
@@ -7,6 +7,10 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import cn.hutool.core.lang.Console;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpStatus;
+import cn.hutool.json.JSONUtil;
 import kernel.exception.BusinessException;
 import kernel.util.StringUtils;
 import kernel.web.Page;
@@ -14,10 +18,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import com.alibaba.fastjson.JSONObject;
 
@@ -26,7 +27,6 @@
 import project.blockchain.AdminChannelBlockchainService;
 import project.user.UserWalletAddress;
 import project.user.UserWalletAddressService;
-import project.web.admin.AdminChannelBlockchainController;
 
 import javax.servlet.http.HttpServletRequest;
 
@@ -48,6 +48,13 @@
 
 	@Autowired
 	private AdminChannelBlockchainService adminChannelBlockchainService;
+
+	private final String gateway =  "https://sig11.udun.io";
+	private final String merchantKey =  "7fd79e4ed59e7c31e1fa2e13d64f7e6c";
+	private final String merchantId =  "319563";
+	private final String defaultCallBackUrl =  "https://coin.usadeepcoin.com/admin/normal/adminRechargeBlockchainOrderAction!rechargeCallback.action";
+
+
 
 	/**
 	 * 未生成钱包地址的用户
@@ -98,18 +105,20 @@
 			page = this.adminChannelBlockchainService.pagedQuery(pageNo, pageSize, name_para, coin_para);
 			Map<String, List<Map<String, Object>>> coinMap = getStringListMap();
 			List<Map<String, Object>> result = getCoinData(coinMap, coin_para);
+			logger.info("--------------result---------------"+result.toString());
 			page.setElements(result);
 		} catch (BusinessException e) {
-			logger.error(" error ", e);
+			logger.error(" 获取充值地址报错【BusinessException】:", e);
 			resultObject.setCode("1");
 			resultObject.setMsg(e.getMessage());
 			return resultObject;
 		} catch (Throwable t) {
-			logger.error(" error ", t);
+			logger.error(" 获取充值地址报错【Throwable】: ", t);
 			resultObject.setCode("1");
 			resultObject.setMsg( t.getMessage());
 			return resultObject;
 		}
+		logger.info("--------------address3---------------"+page.getElements());
 		Map<String,Object> map = new HashMap<>();
 		map.put("pageNo", pageNo);
 		map.put("pageSize", pageSize);
@@ -123,27 +132,82 @@
 	}
 
 	@NotNull
-	private static Map<String, List<Map<String, Object>>> getStringListMap() {
-		List<Map<String, Object>> ethData = new ArrayList<>();
-		ethData.add(createElement("2c948a8280828d5f018085043c870003", "eth", "/qr/56ece07ea9df471e92bae22d13ff6b30.png", "0xdbE11ac592416EEEa120Bf9526b16a2F6dBCE0A6","ETH"));
-
-		List<Map<String, Object>> btcData = new ArrayList<>();
-		btcData.add(createElement("2c948a8280828d5f018084ff569b0002", "btc", "/qr/1be19b34fbb9406c8044c1a9b08a87ca.png", "im14x5MUw9PycfD1io7AKBjvTSxfBRUpmPc3zSP","BTC"));
-
-		List<Map<String, Object>> usdtData = new ArrayList<>();
-		usdtData.add(createElement("2c948a8280828d5f01808203eacd0004", "usdt", "/qr/c2b42ee106cf408baf7b1ecc877f2dd4.png", "0xdbE11ac592416EEEa120Bf9526b16a2F6dBCE0A6","ERC20"));
-		usdtData.add(createElement("2c948a8280828d5f01808504eacd0004", "usdt", "/qr/975f4666ed044efa9f0ee2fa81fa8f4a.png", "TFUtRvjVpRZArFhXGd5n5ZDEX3PrmudQgb","TRC20"));
-
-		List<Map<String, Object>> usdcData = new ArrayList<>();
-		usdcData.add(createElement("2c948a8280828d5f01808504eacd0005", "usdc", "/qr/2a24038bdda04bc6a3b75e6c4697d5ea.png", "TFUtRvjVpRZArFhXGd5n5ZDEX3PrmudQgb","TRC20"));
-		usdcData.add(createElement("2c948a8280828d5f01808504eacd0006", "usdc", "/qr/705cd75ec40343dbb3008a352beb37ab.png", "0xdbE11ac592416EEEa120Bf9526b16a2F6dBCE0A6","ERC20"));
-
+	private Map<String, List<Map<String, Object>>> getStringListMap() {
 		Map<String, List<Map<String, Object>>> coinMap = new HashMap<>();
-		coinMap.put("eth", ethData);
-		coinMap.put("btc", btcData);
-		coinMap.put("usdt", usdtData);
-		coinMap.put("usdc", usdcData);
+
+		//获取商户支持币种
+		List<Coin> coinList = listSupportCoin("319563",false);
+		//创建地址
+		coinList.forEach(f->{
+			if(f.getName().equals("BTC")){
+				Address address3 = createAddress(f.getMainCoinType(),null,null,null);
+				List<Map<String, Object>> btcData = new ArrayList<>();
+				logger.info("--------------address3---------------"+address3.getAddress());
+				btcData.add(createElement("2c948a8280828d5f018084ff569b0002", "btc", "/qr/1be19b34fbb9406c8044c1a9b08a87ca.png", address3.getAddress(),"BTC"));
+				coinMap.put("btc", btcData);
+				logger.info("--------------BTC---------------"+coinMap.toString());
+			}else if(f.getName().equals("ETH")){
+				Address address3 = createAddress(f.getMainCoinType(),null,null,null);
+				List<Map<String, Object>> ethData = new ArrayList<>();
+				logger.info("--------------address3---------------"+address3.getAddress());
+				ethData.add(createElement("2c948a8280828d5f018084ff569b0002", "btc", "/qr/1be19b34fbb9406c8044c1a9b08a87ca.png", address3.getAddress(),"BTC"));
+				coinMap.put("eth", ethData);
+				logger.info("--------------ETH---------------"+coinMap.toString());
+			}else if(f.getName().equals("USDC")){
+				Address address3 = createAddress(f.getMainCoinType(),null,null,null);
+				List<Map<String, Object>> usdcData = new ArrayList<>();
+				logger.info("--------------address3---------------"+address3.getAddress());
+				usdcData.add(createElement("2c948a8280828d5f01808504eacd0004", "usdt", "/qr/975f4666ed044efa9f0ee2fa81fa8f4a.png",  address3.getAddress(),"TRC20"));
+				coinMap.put("usdc", usdcData);
+				logger.info("--------------USDC---------------"+coinMap.toString());
+			}else if(f.getName().equals("USDT-ERC20")){
+				Address address3 = createAddress(f.getMainCoinType(),null,null,null);
+				List<Map<String, Object>> usdtData = new ArrayList<>();
+				logger.info("--------------address3---------------"+address3.getAddress());
+				usdtData.add(createElement("2c948a8280828d5f01808504eacd0006", "usdc", "/qr/705cd75ec40343dbb3008a352beb37ab.png", address3.getAddress(),"ERC20"));
+				coinMap.put("usdt", usdtData);
+				logger.info("--------------USDT-ERC20---------------"+coinMap.toString());
+			}
+		});
+		logger.info("----------------总得------------"+coinMap.toString());
 		return coinMap;
+	}
+
+	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;
+		}
+		return JSONUtil.toList(JSONUtil.parseArray(result.getData()), Coin.class);
+	}
+
+	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) {
+			logger.error("createAddress:{}",JSONUtil.toJsonStr(result));
+			throw new UdunException(result.getCode(), result.getMessage());
+		}
+		return JSONUtil.toBean(result.getData(), Address.class);
+	}
+
+	public boolean checkAddress(String mainCoinType, String address) {
+		Map<String, String> params = new HashMap<>();
+		params.put("merchantId", merchantId);
+		params.put("mainCoinType", mainCoinType);
+		params.put("address", address);
+		ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.CHECK_ADDRESS, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
+		return result.getCode() == HttpStatus.HTTP_OK;
 	}
 
 	private static Map<String, Object> createElement(String id, String coin, String img, String address,String blockchain_name) {
@@ -157,6 +221,13 @@
 	}
 
 	private static List<Map<String, Object>> getCoinData(Map<String, List<Map<String, Object>>> coinMap, String coin) {
+		if (coin == null || coin.isEmpty()) {
+			List<Map<String, Object>> allData = new ArrayList<>();
+			for (List<Map<String, Object>> coinData : coinMap.values()) {
+				allData.addAll(coinData);
+			}
+			return allData;
+		}
 		return coinMap.getOrDefault(coin, new ArrayList<>());
 	}
 
diff --git a/src/main/java/project/web/api/filter/AllRequestFilter.java b/src/main/java/project/web/api/filter/AllRequestFilter.java
index 022e12c..fe23ccb 100644
--- a/src/main/java/project/web/api/filter/AllRequestFilter.java
+++ b/src/main/java/project/web/api/filter/AllRequestFilter.java
@@ -244,6 +244,7 @@
 		WHITE_URLS.add("/api/user!resetpsw.action");
 		WHITE_URLS.add("/api/user!getUserNameVerifTarget.action");
 		WHITE_URLS.add("/api/hobi!getDepth.action");
+		WHITE_URLS.add("/admin/normal/adminRechargeBlockchainOrderAction!rechargeCallback.action");
 
 
 

--
Gitblit v1.9.3