From 513961ecebcfd0619ede7a7edb7ac5e27de28d26 Mon Sep 17 00:00:00 2001
From: Pu Zhibing <393733352@qq.com>
Date: 星期三, 01 一月 2025 17:11:23 +0800
Subject: [PATCH] 增加第三方支付

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/TaskUtil.java                                    |    8 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/RefundResult.java                  |   59 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/MD5AndKL.java                            |  112 +
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/QueryOrderResult.java              |   87 +
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/ShopService.java                              |    8 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/SaveWithdrawalAccount.java                         |   24 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopController.java                        |   10 
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/WithdrawalRequests.java                 |   16 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/FrpCodeEnum.java               |   57 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/WithdrawalRequestsServiceImpl.java   |   45 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/UniPayResult.java                  |   77 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayQueryResult.java          |   63 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/PaymentUtil.java                     |  277 +++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/CloseOrderResult.java              |   45 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/AccountBalanceQueryResult.java     |   43 
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/Shop.java                                  |   20 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayCallbackResult.java   |   68 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/UniPayCallbackResult.java          |   93 +
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopServiceImpl.java                     |   24 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/PaymentUtil.java                         |  277 +++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopWithdrawController.java                |  140 +
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/FrpCodeEnum.java                   |   57 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java             |  217 ++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePay.java                     |   61 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/MD5AndKL.java                        |  112 +
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/QueryOrderResult.java          |   87 +
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/TransferUtil.java                        |  229 ++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayResult.java           |   31 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/QueryRefundResult.java             |   62 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/RefundCallbackResult.java      |   63 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayQueryResult.java      |   63 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/AccountBalanceQueryResult.java     |   43 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayResult.java               |   31 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/QueryRefundResult.java         |   62 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/ShoppingCartService.java                      |   24 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/CloseOrderResult.java              |   45 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/UniPayCallbackResult.java          |   93 +
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/TransferUtil.java                    |  233 ++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayCallbackResult.java       |   64 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/UniPayResult.java                  |   77 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/RefundCallbackResult.java          |   63 
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/ShopBalanceStatement.java                  |    4 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/CloseOrderResult.java          |   45 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/QueryRefundResult.java             |   62 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePay.java                     |   61 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/FrpCodeEnum.java                   |   57 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePay.java                 |   61 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/QueryOrderResult.java              |   87 +
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/WithdrawalRequestsController.java      |  121 +
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/AccountBalanceQueryResult.java |   43 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/UniPayResult.java              |   77 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/RefundCallbackResult.java          |   63 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayResult.java               |   31 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayQueryResult.java          |   63 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/RefundResult.java                  |   59 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayCallbackResult.java       |   64 
 /dev/null                                                                                                     |   78 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/PaymentUtil.java                         |  276 +++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/TransferUtil.java                        |  226 ++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ShoppingCartController.java                |   52 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/RefundResult.java              |   59 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/MD5AndKL.java                            |  112 +
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/UniPayCallbackResult.java      |   93 +
 63 files changed, 4,938 insertions(+), 126 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/WithdrawalRequests.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/WithdrawalRequests.java
index 9e0fa5d..078a363 100644
--- a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/WithdrawalRequests.java
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/WithdrawalRequests.java
@@ -48,6 +48,14 @@
     @ApiModelProperty(value = "提现金额")
     @TableField("withdrawal_amount")
     private BigDecimal withdrawalAmount;
+    
+    @ApiModelProperty(value = "到账金额")
+    @TableField("arrival_amount")
+    private BigDecimal arrivalAmount;
+    
+    @ApiModelProperty(value = "手续费")
+    @TableField("service_charge")
+    private BigDecimal serviceCharge;
 
     @ApiModelProperty(value = "1微信2银行卡")
     @TableField("withdrawal_method")
@@ -64,6 +72,14 @@
     @ApiModelProperty(value = "审核状态 1'待审核',2'审核通过',3'审核拒绝' ")
     @TableField("audit_status")
     private Integer auditStatus;
+    
+    @ApiModelProperty(value = "状态(1=处理中,2=成功)")
+    @TableField("status")
+    private Integer status;
+    
+    @ApiModelProperty(value = "到账时间")
+    @TableField("arrival_time")
+    private LocalDateTime arrivalTime;
     @TableField(exist = false)
     private String userName;
     @TableField(exist = false)
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/Shop.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/Shop.java
index 3a5830a..ba28085 100644
--- a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/Shop.java
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/Shop.java
@@ -169,6 +169,26 @@
     @ApiModelProperty(value = "添加时间")
     @TableField("create_time")
     private LocalDateTime createTime;
+    
+    @ApiModelProperty("报备商户号")
+    @TableField("tradeMerchantNo")
+    private String tradeMerchantNo;
+    
+    @ApiModelProperty("收款银行卡号")
+    @TableField("receiverAccountNoEnc")
+    private String receiverAccountNoEnc;
+    
+    @ApiModelProperty("收款银行卡持卡人名称")
+    @TableField("receiverNameEnc")
+    private String receiverNameEnc;
+    
+    @ApiModelProperty("账户类型(对私账户201,对公账户204)")
+    @TableField("receiverAccountType")
+    private Integer receiverAccountType;
+    
+    @ApiModelProperty("收款账户联行号")
+    @TableField("receiverBankChannelNo")
+    private String receiverBankChannelNo;
 
 
 
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/ShopBalanceStatement.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/ShopBalanceStatement.java
index 177e0f3..464f565 100644
--- a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/ShopBalanceStatement.java
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/ShopBalanceStatement.java
@@ -39,9 +39,9 @@
     @TableField("shop_id")
     private Integer shopId;
 
-    @ApiModelProperty(value = "变动类型(1=门店分佣,2=下级门店分佣,3=门店服务费)")
+    @ApiModelProperty(value = "变动类型(1=门店分佣,2=下级门店分佣,3=门店服务费,4=关联用户分佣,5=提现)")
     @TableField("type")
-    @Excel(name = "变更类型",readConverterExp = "1=门店分佣,2=下级门店分佣,3=门店服务费,4=关联用户分佣")
+    @Excel(name = "变更类型",readConverterExp = "1=门店分佣,2=下级门店分佣,3=门店服务费,4=关联用户分佣,5=提现")
     private Integer type;
 
     @ApiModelProperty(value = "历史余额")
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ObsUploadUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ObsUploadUtil.java
deleted file mode 100644
index f5239c8..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ObsUploadUtil.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.ruoyi.common.core.utils;
-
-import com.obs.services.ObsClient;
-import com.obs.services.model.ObjectMetadata;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.UUID;
-
-public class ObsUploadUtil {
-
-	public static String endPoint = "obs.cn-southwest-2.myhuaweicloud.com";
-	public static String accessKeyId = "LP9N1TLAYN8ERS1PVIYK";
-	public static String accessKeySecret = "bV55lFHi1cG0SYBvnab8yIgDX6etKRSLh5j1gkPR";
-	public static String bucketName = "haitunyingyu";
-	public static String oss_domain = "https://haitunyingyu.obs.cn-southwest-2.myhuaweicloud.com/";
-	// 创建ObsClient实例
-	public static ObsClient obsClient = new ObsClient(accessKeyId, accessKeySecret, endPoint);
-
-	public static String obsUpload(MultipartFile file) throws IOException{
-		//CommonsMultipartFile file = (CommonsMultipartFile)multipartFile;
-		String fileName = "";
-		if(file!=null && !"".equals(file.getOriginalFilename()) && file.getOriginalFilename()!=null){
-			InputStream content = file.getInputStream();//获得指定文件的输入流
-			ObjectMetadata meta = new ObjectMetadata();// 创建上传Object的Metadata
-			meta.setContentLength(file.getSize());  // 必须设置ContentLength
-			String originalFilename = file.getOriginalFilename();
-			if (originalFilename.contains("apk")){
-				fileName = "bf2fe5c5499341e5bc0d56c0c7d5fb2e.apk";
-				System.err.println("apk");
-			}else{
-				fileName =  UUID.randomUUID().toString().replaceAll("-","") + originalFilename.subSequence(originalFilename.lastIndexOf("."), originalFilename.length());
-			}
-			obsClient.putObject(bucketName,"admin/"+fileName,content,meta);// 上传Object.
-			if(fileName != null && !"".equals(fileName)){
-				System.out.println(fileName);
-				fileName = oss_domain+"admin/"+fileName;
-			}
-		}
-		return fileName;
-	}
-
-	/**
-	 * 删除某个Object
-	 *
-	 * @param bucketUrl
-	 * @return
-	 */
-	public static boolean deleteObject(String bucketUrl) {
-		try {
-			bucketUrl=bucketUrl.replace(oss_domain+"web","");
-			// 删除Object.
-			obsClient.deleteObject(bucketName, bucketUrl);
-		} catch (Exception e) {
-			e.printStackTrace();
-			return false;
-		} finally {
-			//ossClient.shutdown();
-		}
-		return true;
-	}
-	
-//	 public static void createBucket(String bucketName)
-//     {
-//         //初始化 OSSClient
-////          ossClient = new OssClient(endPoint, accessKeyId, accessKeySecret);
-//
-//         // 新建一个Bucket
-//         Bucket bucket = ossClient.createBucket(bucketName);
-//         System.out.println(bucket.getName());
-//         System.out.println(bucket.getCreationDate());
-//     }
-//	 
-//	 public static void main(String[] args) {
-//		 OssUploadUtil.createBucket("ssfdfsd");
-//	}
-}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/WithdrawalRequestsController.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/WithdrawalRequestsController.java
index 2763610..3e95d1a 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/WithdrawalRequestsController.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/WithdrawalRequestsController.java
@@ -1,6 +1,7 @@
 package com.ruoyi.account.controller;
 
 
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.ruoyi.account.api.model.AppUser;
 import com.ruoyi.account.api.model.BalanceChangeRecord;
@@ -8,7 +9,13 @@
 import com.ruoyi.account.dto.WithQuery;
 import com.ruoyi.account.dto.WithdrawalRequestsDTO;
 import com.ruoyi.account.service.AppUserService;
+import com.ruoyi.account.service.BalanceChangeRecordService;
 import com.ruoyi.account.service.WithdrawalRequestsService;
+import com.ruoyi.account.util.payment.TransferUtil;
+import com.ruoyi.account.util.payment.model.AccountBalanceQueryResult;
+import com.ruoyi.account.util.payment.model.SinglePay;
+import com.ruoyi.account.util.payment.model.SinglePayCallbackResult;
+import com.ruoyi.account.util.payment.model.SinglePayResult;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.core.web.domain.AjaxResult;
 import io.swagger.annotations.Api;
@@ -17,6 +24,9 @@
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
 
 /**
  * <p>
@@ -35,6 +45,9 @@
     private WithdrawalRequestsService withdrawalRequestsService;
     @Resource
     private AppUserService appUserService;
+    
+    @Resource
+    private BalanceChangeRecordService balanceChangeRecordService;
 
     /**
      * 提现申请
@@ -46,6 +59,9 @@
         return AjaxResult.success();
     }
 
+    
+    
+    
     @PostMapping("/page")
     @ApiOperation(value = "提现申请列表", tags = {"后台"})
     public R<IPage<WithdrawalRequests>> page(@RequestBody WithQuery withQuery){
@@ -55,24 +71,101 @@
         }
         return R.ok(withdrawalRequestsIPage);
     }
+    
+    
+    
+    
+    
     @PostMapping("/auth")
     @ApiOperation(value = "提现申请审批", tags = {"后台"})
-    public R<IPage<WithdrawalRequests>> auth(@RequestParam Long id,@ApiParam("2'审核通过',3'审核拒绝'") Integer auditStatus){
-        WithdrawalRequests byId = withdrawalRequestsService.getById(id);
-        if (auditStatus==2){
-
-            //将用户待审核金额减少,已提现金额增加
-            AppUser byId1 = appUserService.getById(byId.getAppUserId());
-            byId1.setWithdrawnAmount(byId1.getWithdrawnAmount().add(byId.getWithdrawalAmount()));
-            appUserService.updateById(byId1);
-            //执行对应的第三方提现 todo
+    public R auth(@RequestParam Long id,@ApiParam("2'审核通过',3'审核拒绝'") Integer auditStatus){
+        WithdrawalRequests withdrawal = withdrawalRequestsService.getById(id);
+        BigDecimal withdrawalAmount = withdrawal.getWithdrawalAmount();
+        if(withdrawal.getAuditStatus() != 1){
+            return R.fail("不能重复审核");
         }
-        //通过
-        byId.setAuditStatus(auditStatus);
-        withdrawalRequestsService.updateById(byId);
+        if (auditStatus==2){
+            //先检查账户余额是否充足
+            AccountBalanceQueryResult accountBalanceQueryResult = TransferUtil.accountBalanceQuery();
+            if(null == accountBalanceQueryResult){
+                return R.fail("查询账户余额出错");
+            }
+            Double useAbleSettAmount = accountBalanceQueryResult.getUseAbleSettAmount();
+            if(useAbleSettAmount < withdrawal.getArrivalAmount().doubleValue()){
+                return R.fail("账户可用余额不足,请先补充账户余额");
+            }
+            //执行转账操作
+            if(withdrawal.getWithdrawalMethod() == 2){
+                //银行卡转账
+                SinglePay singlePay = new SinglePay();
+                singlePay.setTradeMerchantNo("");
+                singlePay.setMerchantOrderNo(withdrawal.getId().toString());
+                singlePay.setReceiverAccountNoEnc(withdrawal.getBankCardNumber());
+                singlePay.setReceiverNameEnc(withdrawal.getAccountHolder());
+                singlePay.setReceiverAccountType(201);
+                singlePay.setPaidAmount(withdrawal.getArrivalAmount().doubleValue());
+                singlePay.setPaidDesc("账户余额提现");
+                singlePay.setPaidUse("205");
+                singlePay.setCallbackUrl("/account/withdrawal-requests/withdrawalCallback");
+                SinglePayResult singlePayResult = TransferUtil.singlePay(singlePay);
+                if(null == singlePayResult){
+                    return R.fail("转账失败");
+                }
+                withdrawal.setStatus(1);
+            }else{
+                //微信转账
+            }
+        }
+        if(3 == auditStatus){
+            //回退扣除的金额,添加明细记录
+            //修改用户的可提现金额
+            AppUser appUser = appUserService.getById(withdrawal.getAppUserId());
+            BigDecimal withdrawableAmount = appUser.getWithdrawableAmount();
+            BigDecimal withdrawnAmount = appUser.getWithdrawnAmount();
+            BigDecimal balance = appUser.getBalance();
+            appUser.setWithdrawableAmount(withdrawableAmount.add(withdrawalAmount).setScale(2, RoundingMode.HALF_EVEN));
+            appUser.setWithdrawnAmount(withdrawnAmount.subtract(withdrawalAmount).setScale(2, RoundingMode.HALF_EVEN));
+            appUser.setBalance(appUser.getBalance().add(withdrawalAmount).setScale(2, RoundingMode.HALF_EVEN));
+            appUserService.updateById(appUser);
+            //添加变动明细
+            BalanceChangeRecord balanceChangeRecord = new BalanceChangeRecord();
+            balanceChangeRecord.setAppUserId(appUser.getId());
+            balanceChangeRecord.setOrderId(withdrawal.getId());
+            balanceChangeRecord.setChangeType(2);
+            balanceChangeRecord.setBeforeAmount(balance);
+            balanceChangeRecord.setChangeAmount(withdrawalAmount);
+            balanceChangeRecord.setAfterAmount(appUser.getBalance());
+            balanceChangeRecord.setDelFlag(0);
+            balanceChangeRecord.setCreateTime(LocalDateTime.now());
+            balanceChangeRecordService.save(balanceChangeRecord);
+        }
+        withdrawal.setAuditStatus(auditStatus);
+        withdrawalRequestsService.updateById(withdrawal);
         return R.ok();
     }
-
-
+    
+    
+    /**
+     * 提现审核通过后转账回调通知
+     * @param singlePayCallbackResult
+     */
+    @ResponseBody
+    @PostMapping("/withdrawalCallback")
+    public Object withdrawalCallback(@RequestBody SinglePayCallbackResult singlePayCallbackResult){
+        Integer status = singlePayCallbackResult.getStatus();
+        if(203 == status){
+            String merchantOrderNo = singlePayCallbackResult.getMerchantOrderNo();
+            WithdrawalRequests withdrawalRequests = withdrawalRequestsService.getById(merchantOrderNo);
+            if(1 == withdrawalRequests.getStatus()){
+                withdrawalRequests.setStatus(2);
+                withdrawalRequests.setArrivalTime(LocalDateTime.now());
+                withdrawalRequestsService.updateById(withdrawalRequests);
+            }
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("statusCode", 2001);
+            return jsonObject;
+        }
+        return new JSONObject();
+    }
 }
 
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/WithdrawalRequestsServiceImpl.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/WithdrawalRequestsServiceImpl.java
index 30754e1..e2133de 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/WithdrawalRequestsServiceImpl.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/WithdrawalRequestsServiceImpl.java
@@ -5,11 +5,14 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.account.api.feignClient.AppUserClient;
 import com.ruoyi.account.api.model.AppUser;
+import com.ruoyi.account.api.model.BalanceChangeRecord;
 import com.ruoyi.account.api.model.UserClickLog;
 import com.ruoyi.account.api.model.WithdrawalRequests;
 import com.ruoyi.account.dto.WithQuery;
 import com.ruoyi.account.dto.WithdrawalRequestsDTO;
 import com.ruoyi.account.mapper.WithdrawalRequestsMapper;
+import com.ruoyi.account.service.AppUserService;
+import com.ruoyi.account.service.BalanceChangeRecordService;
 import com.ruoyi.account.service.VipSettingService;
 import com.ruoyi.account.service.WithdrawalRequestsService;
 import com.ruoyi.common.core.exception.ServiceException;
@@ -23,6 +26,7 @@
 import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.time.LocalDateTime;
 
 /**
  * <p>
@@ -37,23 +41,26 @@
     @Resource
     private TokenService tokenService;
     @Resource
-    private AppUserClient appUserClient;
+    private AppUserService appUserService;
     @Resource
     private VipSettingService vipSettingService;
+    
+    @Resource
+    private BalanceChangeRecordService balanceChangeRecordService;
 
     public static final BigDecimal MAX_WITHDRAWAL_AMOUNT = new BigDecimal("200");
     public static final BigDecimal VIP_WITHDRAWAL_FEE_DENOMINATOR = new BigDecimal("100");
 
     @Override
     public void withdrawalApply(WithdrawalRequestsDTO params) {
-        if (params.getWithdrawalAmount().compareTo(MAX_WITHDRAWAL_AMOUNT) > 0) {
+        BigDecimal withdrawalAmount = params.getWithdrawalAmount();
+        if (withdrawalAmount.compareTo(MAX_WITHDRAWAL_AMOUNT) > 0) {
             throw new ServiceException("提现失败,单次提现金额不能超过200元!");
         }
 
         LoginUser loginUserApplet = tokenService.getLoginUserApplet();
-        AppUser appUser = appUserClient.getAppUserById(loginUserApplet.getUserid());
-
-        if (appUser.getWithdrawableAmount().compareTo(params.getWithdrawalAmount()) < 0) {
+        AppUser appUser = appUserService.getById(loginUserApplet.getUserid());
+        if (appUser.getWithdrawableAmount().compareTo(withdrawalAmount) < 0) {
             throw new ServiceException("提现失败,可提现金额不足!");
         }
 
@@ -63,22 +70,46 @@
             throw new ServiceException("提现失败,当前会员等级不允许提现!");
         }
         BigDecimal vipWithdrawalMinAmount = vipSetting.getVipWithdrawalMinAmount();
-        if (params.getWithdrawalAmount().compareTo(vipWithdrawalMinAmount) < 0) {
+        if (withdrawalAmount.compareTo(vipWithdrawalMinAmount) < 0) {
             throw new ServiceException("提现失败,提现金额不能小于" + vipWithdrawalMinAmount + "元!");
         }
+        
         // 提现手续费
         BigDecimal vipWithdrawalFee = vipSetting.getVipWithdrawalFee()
                 .divide(VIP_WITHDRAWAL_FEE_DENOMINATOR, 2, RoundingMode.HALF_UP);
         // 减去手续费
+        BigDecimal multiply = params.getWithdrawalAmount().multiply(vipWithdrawalFee);
         params.setWithdrawalAmount(params.getWithdrawalAmount()
-                .subtract(params.getWithdrawalAmount().multiply(vipWithdrawalFee)));
+                .subtract(multiply));
 
         WithdrawalRequests withdrawalRequests = new WithdrawalRequests();
         BeanUtils.copyBeanProp(withdrawalRequests, params);
+        withdrawalRequests.setWithdrawalAmount(withdrawalAmount);
+        withdrawalRequests.setArrivalAmount(withdrawalRequests.getWithdrawalAmount());
+        withdrawalRequests.setServiceCharge(multiply);
         withdrawalRequests.setDelFlag(0);
         withdrawalRequests.setAppUserId(SecurityUtils.getUserId());
         withdrawalRequests.setAuditStatus(1);
         save(withdrawalRequests);
+        //修改用户的可提现金额
+        BigDecimal withdrawableAmount = appUser.getWithdrawableAmount();
+        BigDecimal withdrawnAmount = appUser.getWithdrawnAmount();
+        BigDecimal balance = appUser.getBalance();
+        appUser.setWithdrawableAmount(withdrawableAmount.subtract(withdrawalAmount).setScale(2, RoundingMode.HALF_EVEN));
+        appUser.setWithdrawnAmount(withdrawnAmount.add(withdrawalAmount).setScale(2, RoundingMode.HALF_EVEN));
+        appUser.setBalance(appUser.getBalance().subtract(withdrawalAmount).setScale(2, RoundingMode.HALF_EVEN));
+        appUserService.updateById(appUser);
+        //添加变动明细
+        BalanceChangeRecord balanceChangeRecord = new BalanceChangeRecord();
+        balanceChangeRecord.setAppUserId(appUser.getId());
+        balanceChangeRecord.setOrderId(withdrawalRequests.getId());
+        balanceChangeRecord.setChangeType(2);
+        balanceChangeRecord.setBeforeAmount(balance);
+        balanceChangeRecord.setChangeAmount(withdrawalAmount);
+        balanceChangeRecord.setAfterAmount(appUser.getBalance());
+        balanceChangeRecord.setDelFlag(0);
+        balanceChangeRecord.setCreateTime(LocalDateTime.now());
+        balanceChangeRecordService.save(balanceChangeRecord);
     }
 
     @Override
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/MD5AndKL.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/MD5AndKL.java
new file mode 100644
index 0000000..cdacbfb
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/MD5AndKL.java
@@ -0,0 +1,112 @@
+package com.ruoyi.account.util.payment;
+
+import java.security.MessageDigest;
+
+public class MD5AndKL {
+	
+	/**
+	 * MD5加码。32位
+	 * 
+	 * @param inStr
+	 * @return
+	 */
+	public static String MD5(String inStr) {
+		MessageDigest md5 = null;
+		try {
+			md5 = MessageDigest.getInstance("MD5");
+		} catch (Exception e) {
+			throw new RuntimeException(e.toString());
+		}
+		byte[] md5Bytes = md5.digest(inStr.getBytes());
+		StringBuffer hexValue = new StringBuffer();
+		for (int i = 0; i < md5Bytes.length; i++) {
+			int val = ((int) md5Bytes[i]) & 0xff;
+			if (val < 16) {
+				hexValue.append("0");
+			}
+			hexValue.append(Integer.toHexString(val));
+		}
+		return hexValue.toString();
+	}
+
+	/**
+	 * 可逆的加密算法
+	 * 
+	 * @param inStr
+	 * @return
+	 */
+	public static String KL(String inStr) {
+		char[] a = inStr.toCharArray();
+		for (int i = 0; i < a.length; i++) {
+			a[i] = (char) (a[i] ^ 't');
+		}
+		String s = new String(a);
+		return s;
+	}
+
+	/**
+	 * 加密后解密
+	 * 
+	 * @param inStr
+	 * @return
+	 */
+	public static String JM(String inStr) {
+		char[] a = inStr.toCharArray();
+		for (int i = 0; i < a.length; i++) {
+			a[i] = (char) (a[i] ^ 't');
+		}
+		String k = new String(a);
+		return k;
+	}
+
+
+
+	private static String byteArrayToHexString(byte b[]) {
+		StringBuffer resultSb = new StringBuffer();
+		for (int i = 0; i < b.length; i++)
+			resultSb.append(byteToHexString(b[i]));
+
+		return resultSb.toString();
+	}
+
+	private static String byteToHexString(byte b) {
+		int n = b;
+		if (n < 0)
+			n += 256;
+		int d1 = n / 16;
+		int d2 = n % 16;
+		return hexDigits[d1] + hexDigits[d2];
+	}
+
+	public static String MD5Encode(String origin, String charsetname) {
+		String resultString = null;
+		try {
+			resultString = new String(origin);
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			if (charsetname == null || "".equals(charsetname)){
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
+			}else{
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
+			}
+		} catch (Exception exception) {
+			exception.printStackTrace();
+		}
+		return resultString;
+	}
+
+	private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
+			"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
+
+	public static void main(String args[]) {
+		 
+		System.out.println("MD5后再加密:" + KL(MD5("123456")));
+		System.out.println(MD5("123456"));
+		// System.out.println("加密:" + KL(MD5("123456")));
+		// s = KL(s);
+		// System.out.println("解密:" + KL("81dc9bdb52d04dc20036dbd8313ed055"));
+		// System.out.println("解密:" + JM(KL(s)));
+		// System.out.println("解密为MD5后的:" + KL(KL(MD5(s))));
+		// System.out.println(JM("5d62957bb57d3e49dcf48a0df064be4c"));
+		// System.out.println(MD5AndKL.KL(MD5AndKL.MD5("admin"+"87654321")));
+	}
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/PaymentUtil.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/PaymentUtil.java
new file mode 100644
index 0000000..8069708
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/PaymentUtil.java
@@ -0,0 +1,277 @@
+package com.ruoyi.account.util.payment;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.account.util.payment.model.*;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.*;
+
+/**
+ * 支付工具类
+ * @author zhibing.pu
+ * @Date 2024/12/27 17:00
+ */
+@Slf4j
+public class PaymentUtil {
+	
+	//微信公众号、微信小程序、微信 APP+/H5、云微小程序支付
+	private static final String appId = "wxdeed472c98e42a54";
+	/**
+	 * 商户密钥
+	 */
+	private static final String key = "925899fcc374430f9e4b4ba3db05b448";
+	/**
+	 * 商户号
+	 */
+	private static final String merchantNo = "888122600004175";
+	/**
+	 * 支付回调地址
+	 */
+	private static final String callbackUrl = "http://221.182.45.100:9000";
+	
+	
+	/**
+	 * 支付
+	 * @param orderNo           商户订单号
+	 * @param amount            订单金额
+	 * @param productName       商品名称
+	 * @param productDesc       商品描述
+	 * @param mp                公用回传参数
+	 * @param notifyUrl         服务器异步通知地址
+	 * @param openId            微信 Openid
+	 * @param tradeMerchantNo   报备商户号
+	 * @return
+	 */
+	public static UniPayResult uniPay(String orderNo, Double amount, String productName, String productDesc, String mp, String notifyUrl, String openId, String tradeMerchantNo){
+		String url = "https://trade.joinpay.com/tradeRt/uniPay";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.5");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		//订单金额
+		body.put("p3_Amount", amount);
+		//交易币种
+		body.put("p4_Cur", "1");
+		//商品名称
+		body.put("p5_ProductName", productName);
+		//商品描述
+		body.put("p6_ProductDesc", productDesc);
+		//公用回传参数
+		body.put("p7_Mp", mp);
+		//服务器异步通知地址
+		body.put("p9_NotifyUrl", callbackUrl + notifyUrl);
+		//交易类型
+		body.put("q1_FrpCode", FrpCodeEnum.WEIXIN_XCX.getCode());
+		//微信 Openid
+		body.put("q5_OpenId", openId);
+		//APPID
+		body.put("q7_AppId", appId);
+		//报备商户号
+		body.put("qa_TradeMerchantNo", tradeMerchantNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("支付接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("支付接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("支付接口异常:" + execute.body());
+			return null;
+		}
+		UniPayResult uniPayResult = JSON.parseObject(execute.body(), UniPayResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 查询支付订单
+	 * @param orderNo   订单号
+	 * @return
+	 */
+	public static QueryOrderResult queryOrder(String orderNo){
+		String url = "https://trade.joinpay.com/tradeRt/queryOrder";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.5");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("查询支付接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("查询支付接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("查询支付接口异常:" + execute.body());
+			return null;
+		}
+		QueryOrderResult uniPayResult = JSON.parseObject(execute.body(), QueryOrderResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 退款
+	 * @param orderNo           支付订单号
+	 * @param refundOrderNo     退款订单号
+	 * @param refundAmount      退款金额
+	 * @param notifyUrl         异步通知地址
+	 * @return
+	 */
+	public static RefundResult refund(String orderNo, String refundOrderNo, Double refundAmount, String notifyUrl){
+		String url = "https://trade.joinpay.com/tradeRt/refund";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.3");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		//商户退款订单号
+		body.put("p3_RefundOrderNo", refundOrderNo);
+		//退款金额
+		body.put("p4_RefundAmount", refundAmount);
+		//服务器异步通知地址
+		body.put("p6_NotifyUrl", notifyUrl);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("退款接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("退款接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("退款接口异常:" + execute.body());
+			return null;
+		}
+		RefundResult uniPayResult = JSON.parseObject(execute.body(), RefundResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 查询退款订单
+	 * @param refundOrderNo 退款订单号
+	 * @return
+	 */
+	public static QueryRefundResult queryRefund(String refundOrderNo){
+		String url = "https://trade.joinpay.com/tradeRt/refund";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.3");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户退款订单号
+		body.put("p2_RefundOrderNo", refundOrderNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("退款接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("退款接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("退款接口异常:" + execute.body());
+			return null;
+		}
+		QueryRefundResult uniPayResult = JSON.parseObject(execute.body(), QueryRefundResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 关闭订单(仅支持微信和支付宝)
+	 * @param orderNo   订单号
+	 * @return
+	 */
+	public static CloseOrderResult closeOrder(String orderNo){
+		String url = "https://www.joinpay.com/trade/closeOrder.action";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		//交易类型
+		body.put("p3_FrpCode", FrpCodeEnum.WEIXIN_XCX.getCode());
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("关闭订单接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("关闭订单接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("关闭订单接口异常:" + execute.body());
+			return null;
+		}
+		CloseOrderResult uniPayResult = JSON.parseObject(execute.body(), CloseOrderResult.class);
+		return uniPayResult;
+	}
+	
+	
+	
+	public static String sign(JSONObject body) throws Exception{
+		Set<Map.Entry<String, Object>> entries = body.entrySet();
+		List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries);
+		// 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
+		Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
+			public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
+				return (o1.getKey()).toString().compareTo(o2.getKey());
+			}
+		});
+		// 构造签名键值对的格式
+		StringBuilder sb = new StringBuilder();
+		for (Map.Entry<String, Object> item : infoIds) {
+			if (item.getKey() != null || item.getKey() != "") {
+				Object val = item.getValue();
+				if (!(val == "" || val == null)) {
+					sb.append(val);
+				}
+			}
+		}
+		sb.append(key);
+		return MD5AndKL.MD5(sb.toString());
+	}
+	
+	
+	public static void main(String[] args) {
+		UniPayResult uniPayResult = PaymentUtil.uniPay("123456", 0.01D, "测试商品", "这是用于对接支付测试的商品描述", "", "", "", "");
+		System.err.println(JSON.toJSONString(uniPayResult));
+	}
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/TransferUtil.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/TransferUtil.java
new file mode 100644
index 0000000..d503443
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/TransferUtil.java
@@ -0,0 +1,233 @@
+package com.ruoyi.account.util.payment;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.account.util.payment.model.AccountBalanceQueryResult;
+import com.ruoyi.account.util.payment.model.SinglePay;
+import com.ruoyi.account.util.payment.model.SinglePayQueryResult;
+import com.ruoyi.account.util.payment.model.SinglePayResult;
+import lombok.extern.slf4j.Slf4j;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+/**
+ * 转账代付工具类
+ * @author zhibing.pu
+ * @Date 2024/12/30 19:54
+ */
+@Slf4j
+public class TransferUtil {
+	/**
+	 * 商户密钥
+	 */
+	private static final String key = "925899fcc374430f9e4b4ba3db05b448";
+	/**
+	 * 商户号
+	 */
+	private static final String merchantNo = "888122600004175";
+	
+	private static final String format = "yyyy-MM-dd HH:mm:ss";
+	/**
+	 * 支付回调地址
+	 */
+	private static final String callbackUrl = "http://221.182.45.100:9000";
+	
+	
+	/**
+	 * 单笔代付
+	 * @param singlePay
+	 * @return
+	 */
+	public static SinglePayResult singlePay(SinglePay singlePay){
+		String url = "https://www.joinpay.com/payment/pay/singlePay";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("userNo", merchantNo);
+		//报备商户号
+		body.put("tradeMerchantNo", singlePay.getTradeMerchantNo());
+		//产品类型
+		body.put("productCode", "BANK_PAY_DAILY_ORDER");
+		//交易请求时间
+		body.put("requestTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern(format)));
+		//商户订单号
+		body.put("merchantOrderNo", singlePay.getMerchantOrderNo());
+		//收款账户号,收款人银行卡卡号
+		body.put("receiverAccountNoEnc", singlePay.getReceiverAccountNoEnc());
+		//收款人,收款人银行卡持卡人名称
+		body.put("receiverNameEnc", singlePay.getReceiverNameEnc());
+		//账户类型
+		body.put("receiverAccountType", singlePay.getReceiverAccountType());
+		//收款账户联行号 对公账户必须填写此字段
+		body.put("receiverBankChannelNo", singlePay.getReceiverBankChannelNo());
+		//交易金额
+		body.put("paidAmount", singlePay.getPaidAmount());
+		//币种
+		body.put("currency", "201");
+		//是否复核 复核:201,不复核:202
+		body.put("isChecked", "202");
+		//代付说明
+		body.put("paidDesc", singlePay.getPaidDesc());
+		//代付用途
+		/**
+		 * 工资奖金 201
+		 * 活动经费 202
+		 * 养老金 203
+		 * 货款 204
+		 * 劳务费 205
+		 * 保险理财 206
+		 * 资金下发 207
+		 * 营业款 208
+		 * 退回款项 210
+		 * 消费款项 211
+		 */
+		body.put("paidUse", singlePay.getPaidUse());
+		//商户通知地址
+		body.put("callbackUrl", callbackUrl + singlePay.getCallbackUrl());
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("单笔代付接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("单笔代付接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("单笔代付接口异常:" + execute.body());
+			return null;
+		}
+		JSONObject jsonObject = JSON.parseObject(execute.body());
+		String statusCode = jsonObject.getString("statusCode");
+		if(!"2001".equals(statusCode) && !"2003".equals(statusCode)){
+			log.error("单笔代付接口异常:" + jsonObject.getString("message"));
+			return null;
+		}
+		if("2003".equals(statusCode)){
+			//汇聚不能确定订单状态,建议 10 分钟后发起查询确认。
+			log.error("单笔代付接口异常:汇聚不能确定订单状态,建议 10 分钟后发起查询确认。");
+			return null;
+		}
+		SinglePayResult uniPayResult = jsonObject.getObject("data", SinglePayResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 单笔代付查询接口
+	 * @param merchantOrderNo   订单号
+	 * @return
+	 */
+	public static SinglePayQueryResult singlePayQuery(String merchantOrderNo){
+		String url = "https://www.joinpay.com/payment/pay/singlePayQuery";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("userNo", merchantNo);
+		//商户订单号
+		body.put("merchantOrderNo", merchantOrderNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("单笔代付查询接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("单笔代付查询接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("单笔代付查询接口异常:" + execute.body());
+			return null;
+		}
+		JSONObject jsonObject = JSON.parseObject(execute.body());
+		String statusCode = jsonObject.getString("statusCode");
+		if(!"2001".equals(statusCode) && !"2003".equals(statusCode)){
+			log.error("单笔代付查询接口异常:" + jsonObject.getString("message"));
+			return null;
+		}
+		if("2003".equals(statusCode)){
+			//汇聚不能确定订单状态,建议 10 分钟后发起查询确认。
+			log.error("单笔代付查询接口异常:汇聚不能确定订单状态,建议 10 分钟后发起查询确认。");
+			return null;
+		}
+		SinglePayQueryResult uniPayResult = jsonObject.getObject("data", SinglePayQueryResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 可取余额查询
+	 * @return
+	 */
+	public static AccountBalanceQueryResult accountBalanceQuery(){
+		String url = "https://www.joinpay.com/payment/pay/accountBalanceQuery";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("userNo", merchantNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("可取余额查询接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("可取余额查询接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("可取余额查询接口异常:" + execute.body());
+			return null;
+		}
+		JSONObject jsonObject = JSON.parseObject(execute.body());
+		String statusCode = jsonObject.getString("statusCode");
+		if(!"2001".equals(statusCode) && !"2003".equals(statusCode)){
+			log.error("可取余额查询接口异常:" + jsonObject.getString("message"));
+			return null;
+		}
+		if("2003".equals(statusCode)){
+			//汇聚不能确定订单状态,建议 10 分钟后发起查询确认。
+			log.error("可取余额查询接口异常:汇聚不能确定订单状态,建议 10 分钟后发起查询确认。");
+			return null;
+		}
+		AccountBalanceQueryResult uniPayResult = jsonObject.getObject("data", AccountBalanceQueryResult.class);
+		return uniPayResult;
+	}
+	
+	
+	
+	
+	public static String sign(JSONObject body) throws Exception{
+		Set<Map.Entry<String, Object>> entries = body.entrySet();
+		List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries);
+		// 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
+		Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
+			public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
+				return (o1.getKey()).toString().compareTo(o2.getKey());
+			}
+		});
+		// 构造签名键值对的格式
+		StringBuilder sb = new StringBuilder();
+		for (Map.Entry<String, Object> item : infoIds) {
+			if (item.getKey() != null || item.getKey() != "") {
+				Object val = item.getValue();
+				if (!(val == "" || val == null)) {
+					sb.append(val);
+				}
+			}
+		}
+		sb.append(key);
+		return MD5AndKL.MD5(sb.toString());
+	}
+	
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/AccountBalanceQueryResult.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/AccountBalanceQueryResult.java
new file mode 100644
index 0000000..bcaf5fb
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/AccountBalanceQueryResult.java
@@ -0,0 +1,43 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/31 10:34
+ */
+@Data
+public class AccountBalanceQueryResult {
+	/**
+	 * 商户号
+	 */
+	private String userNo;
+	/**
+	 * 商户名称
+	 */
+	private String userName;
+	/**
+	 * 币种
+	 */
+	private Integer currency;
+	/**
+	 * 可取金额
+	 */
+	private Double useAbleSettAmount;
+	/**
+	 * 可结算冻结金额
+	 */
+	private Double availableSettAmountFrozen;
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorDesc;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/CloseOrderResult.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/CloseOrderResult.java
new file mode 100644
index 0000000..4567d59
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/CloseOrderResult.java
@@ -0,0 +1,45 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2025/1/1 10:15
+ */
+@Data
+public class CloseOrderResult {
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 业务结果 100:成功,101:失败
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 * 0 系统连接超时
+	 * 4 服务不可用
+	 * 100 关单成功
+	 * 101 失败,详见响应码描述
+	 * 10080000 系统异常
+	 * 10080002 验证签名失败
+	 * 10080003 订单号不正确
+	 * 10080042 交易类型不合法
+	 * 10083001 订单正在处理中
+	 * 10083002 该订单请求多次交易
+	 * 10083003 订单已关闭,无需关单操作
+	 * 10083003 交易成功,无需关单操作
+	 * 10083004 通道系统异常,请用相同参数重新请求
+	 * 10083005 通道其他异常信息
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/FrpCodeEnum.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/FrpCodeEnum.java
new file mode 100644
index 0000000..fc86596
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/FrpCodeEnum.java
@@ -0,0 +1,57 @@
+package com.ruoyi.account.util.payment.model;
+
+/**
+ * 支付类型枚举
+ * @author zhibing.pu
+ * @Date 2024/12/27 17:30
+ */
+public enum FrpCodeEnum {
+	ALIPAY_NATIVE("支付宝扫码(主扫)", "ALIPAY_NATIVE"),
+	ALIPAY_CARD("支付宝刷卡(被扫)", "ALIPAY_CARD"),
+	ALIPAY_H5("支付宝 H5", "ALIPAY_H5"),
+	ALIPAY_FWC("支付宝服务窗", "ALIPAY_FWC"),
+	ALIPAY_SYT("支付宝收银台", "ALIPAY_SYT"),
+	WEIXIN_NATIVE("微信扫码(主扫)", "WEIXIN_NATIVE"),
+	WEIXIN_CARD("微信刷卡(被扫)", "WEIXIN_CARD"),
+	WEIXIN_APP3("微信 APP+支付", "WEIXIN_APP3"),
+	WEIXIN_H5_PLUS("微信 H5 支付", "WEIXIN_H5_PLUS"),
+	WEIXIN_GZH("微信公众号支付", "WEIXIN_GZH"),
+	WEIXIN_XCX("微信小程序支付", "WEIXIN_XCX"),
+	QQ_NATIVE("QQ 扫码(主扫)", "QQ_NATIVE"),
+	QQ_CARD("QQ 刷卡(被扫)", "QQ_CARD"),
+	QQ_APP("QQ APP 支付", "QQ_APP"),
+	QQ_H5("QQH5 支付", "QQ_H5"),
+	QQ_GZH("QQ 公众号支付", "QQ_GZH"),
+	UNIONPAY_NATIVE("银联扫码(主扫)", "UNIONPAY_NATIVE"),
+	UNIONPAY_CARD("银联刷卡(被扫)", "UNIONPAY_CARD"),
+	UNIONPAY_APP("银联 APP 支付", "UNIONPAY_APP"),
+	UNIONPAY_H5("银联 H5", "UNIONPAY_H5"),
+	UNIONPAY_SYT("银联统一收银台", "UNIONPAY_SYT"),
+	UNIONPAY_WXMP("银联云微小程序(无感支付)", "UNIONPAY_WXMP")
+	;
+	
+	private String name;
+	
+	private String code;
+	
+	FrpCodeEnum(String name, String code) {
+		this.name = name;
+		this.code = code;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getCode() {
+		return code;
+	}
+	
+	public void setCode(String code) {
+		this.code = code;
+	}
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/QueryOrderResult.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/QueryOrderResult.java
new file mode 100644
index 0000000..904d8a9
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/QueryOrderResult.java
@@ -0,0 +1,87 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:30
+ */
+@Data
+public class QueryOrderResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 支付金额
+	 */
+	private Double r3_Amount;
+	/**
+	 * 商品名称
+	 */
+	private String r4_ProductName;
+	/**
+	 * 交易流水号
+	 */
+	private String r5_TrxNo;
+	/**
+	 * 银行流水号
+	 */
+	private String r6_BankTrxNo;
+	/**
+	 * 订单手续费
+	 */
+	private Double r7_Fee;
+	/**
+	 * 交易类型
+	 */
+	private String r8_FrpCode;
+	/**
+	 * 订单状态 100:成功,101:失败,102:已创建,105:订单已关闭
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 用户标识
+	 */
+	private String rd_OpenId;
+	/**
+	 * 平台优惠金额
+	 */
+	private Double re_DiscountAmount;
+	/**
+	 * 支付时间
+	 */
+	private String rf_PayTime;
+	/**
+	 * 卡类型
+	 */
+	private String rh_cardType;
+	/**
+	 * 银行编码
+	 */
+	private String rj_BankCode;
+	/**
+	 * 签约 ID
+	 */
+	private String rl_ContractId;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/QueryRefundResult.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/QueryRefundResult.java
new file mode 100644
index 0000000..2cee1ea
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/QueryRefundResult.java
@@ -0,0 +1,62 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:56
+ */
+@Data
+public class QueryRefundResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户退款订单号
+	 */
+	private String r2_RefundOrderNo;
+	/**
+	 * 退款金额
+	 */
+	private Double r3_RefundAmount;
+	/**
+	 * 退款流水号
+	 */
+	private String r4_RefundTrxNo;
+	/**
+	 * 退款完成时间
+	 */
+	private String r5_RefundCompleteTime;
+	/**
+	 * 退款渠道
+	 */
+	private String r8_RefundWay;
+	/**
+	 * 退款入账账户
+	 */
+	private String r9_ReceiveAccountNo;
+	/**
+	 * 退款状态
+	 * 100:退款成功
+	 * 101:退款失败
+	 * 102:退款处理中
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/RefundCallbackResult.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/RefundCallbackResult.java
new file mode 100644
index 0000000..eec1b0b
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/RefundCallbackResult.java
@@ -0,0 +1,63 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:50
+ */
+@Data
+public class RefundCallbackResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 商户退款订单号
+	 */
+	private String r3_RefundOrderNo;
+	/**
+	 * 退款金额
+	 */
+	private Double r4_RefundAmount;
+	/**
+	 * 商户退款流水号
+	 */
+	private String r5_RefundTrxNo;
+	/**
+	 * 退款完成时间
+	 */
+	private String r6_RefundCompleteTime;
+	/**
+	 * 退款渠道
+	 */
+	private String r7_RefundWay;
+	/**
+	 * 退款入账账户
+	 */
+	private String r8_ReceiveAccountNo;
+	/**
+	 * 退款状态 100:成功;101:失败
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/RefundResult.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/RefundResult.java
new file mode 100644
index 0000000..8972b66
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/RefundResult.java
@@ -0,0 +1,59 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:43
+ */
+@Data
+public class RefundResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 商户退款订单号
+	 */
+	private String r3_RefundOrderNo;
+	/**
+	 * 退款金额
+	 */
+	private Double r4_RefundAmount;
+	/**
+	 * 商户退款流水号
+	 */
+	private String r5_RefundTrxNo;
+	/**
+	 * 退款申请状态
+	 * 100:成功,
+	 * 101:失败 。
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 营销退款金额
+	 */
+	private Double rd_MarketRefAmount;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+	
+	
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePay.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePay.java
new file mode 100644
index 0000000..4ecb550
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePay.java
@@ -0,0 +1,61 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 20:28
+ */
+@Data
+public class SinglePay {
+	/**
+	 * 报备商户号
+	 */
+	private String tradeMerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 收款账户号,收款人银行卡卡号
+	 */
+	private String receiverAccountNoEnc;
+	/**
+	 * 收款人,收款人银行卡持卡人名称
+	 */
+	private String receiverNameEnc;
+	/**
+	 * 账户类型 对私账户201,对公账户204
+	 */
+	private Integer receiverAccountType;
+	/**
+	 * 收款账户联行号 对公账户必须填写此字段
+	 */
+	private String receiverBankChannelNo;
+	/**
+	 * 交易金额
+	 */
+	private Double paidAmount;
+	/**
+	 * 代付说明
+	 */
+	private String paidDesc;
+	/**
+	 * 代付用途
+	 * 工资奖金 201
+	 * 活动经费 202
+	 * 养老金 203
+	 * 货款 204
+	 * 劳务费 205
+	 * 保险理财 206
+	 * 资金下发 207
+	 * 营业款 208
+	 * 退回款项 210
+	 * 消费款项 211
+	 */
+	private String paidUse;
+	/**
+	 * 商户通知地址
+	 */
+	private String callbackUrl;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayCallbackResult.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayCallbackResult.java
new file mode 100644
index 0000000..973b2ef
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayCallbackResult.java
@@ -0,0 +1,68 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ *
+ * @author zhibing.pu
+ * @Date 2024/12/30 20:39
+ */
+@Data
+public class SinglePayCallbackResult {
+	/**
+	 * 交易状态
+	 * 201 批次已创建 汇聚受理并创建该批次的初始状态
+	 * 202 处理中 批次正在处理中状态
+	 * 203 处理完成 批次中的每笔明细都明确了代付结果
+	 * 204 批次不存在 汇聚未受理该批次的请求,找不到该批次,明确失败
+	 */
+	private Integer status;
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorCodeDesc;
+	/**
+	 * 商户编号
+	 */
+	private String userNo;
+	/**
+	 * 报备商户号
+	 */
+	private String tradeMerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 平台流水号
+	 */
+	private String platformSerialNo;
+	/**
+	 * 收款账户号
+	 */
+	private String receiverAccountNoEnc;
+	/**
+	 * 收款人
+	 */
+	private String receiverNameEnc;
+	/**
+	 * 交易金额
+	 */
+	private Double paidAmount;
+	/**
+	 * 手续费
+	 */
+	private String fee;
+	/**
+	 * 完成时间
+	 */
+	private String completeTime;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayQueryResult.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayQueryResult.java
new file mode 100644
index 0000000..b752f7b
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayQueryResult.java
@@ -0,0 +1,63 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/31 10:10
+ */
+@Data
+public class SinglePayQueryResult {
+	/**
+	 * 单笔代付查询请求的交易状态
+	 */
+	private Integer status;
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorDesc;
+	/**
+	 * 商户号
+	 */
+	private String userNo;
+	/**
+	 * 报备商户号
+	 */
+	private String tradeMerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 平台流水号
+	 */
+	private String platformSerialNo;
+	/**
+	 * 收款账户号
+	 */
+	private String receiverAccountNoEnc;
+	/**
+	 * 收款人
+	 */
+	private String receiverNameEnc;
+	/**
+	 * 交易金额
+	 */
+	private Double paidAmount;
+	/**
+	 * 手续费
+	 */
+	private Double fee;
+	/**
+	 * 完成时间
+	 */
+	private String completeTime;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayResult.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayResult.java
new file mode 100644
index 0000000..6231a45
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/SinglePayResult.java
@@ -0,0 +1,31 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 20:36
+ */
+@Data
+public class SinglePayResult {
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorDesc;
+	/**
+	 * 商户编号
+	 */
+	private String userNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/UniPayCallbackResult.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/UniPayCallbackResult.java
new file mode 100644
index 0000000..3ea002b
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/UniPayCallbackResult.java
@@ -0,0 +1,93 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:00
+ */
+@Data
+public class UniPayCallbackResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 支付金额
+	 */
+	private Double r3_Amount;
+	/**
+	 * 交易币种
+	 */
+	private String r4_Cur;
+	/**
+	 * 公用回传参数
+	 */
+	private String r5_Mp;
+	/**
+	 * 支付状态
+	 * 100:支付成功;
+	 * 101:支付失败。
+	 */
+	private String r6_Status;
+	/**
+	 * 交易流水号
+	 */
+	private String r7_TrxNo;
+	/**
+	 * 银行订单号
+	 */
+	private String r8_BankOrderNo;
+	/**
+	 * 银行流水号
+	 */
+	private String r9_BankTrxNo;
+	/**
+	 * 支付时间
+	 */
+	private String ra_PayTime;
+	/**
+	 * 交易结果通知时间
+	 */
+	private String rb_DealTime;
+	/**
+	 * 银行编码
+	 */
+	private String rc_BankCode;
+	/**
+	 * 用户标识
+	 */
+	private String rd_OpenId;
+	/**
+	 * 平台优惠金额
+	 */
+	private Double re_DiscountAmount;
+	/**
+	 * 卡类型
+	 */
+	private String rh_cardType;
+	/**
+	 * 订单手续费
+	 */
+	private Double rj_Fee;
+	/**
+	 * 交易类型
+	 */
+	private String rk_FrpCode;
+	/**
+	 * 签约 ID
+	 */
+	private String rl_ContractId;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/UniPayResult.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/UniPayResult.java
new file mode 100644
index 0000000..00a8135
--- /dev/null
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/model/UniPayResult.java
@@ -0,0 +1,77 @@
+package com.ruoyi.account.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 10:47
+ */
+@Data
+public class UniPayResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 支付金额
+	 */
+	private Double r3_Amount;
+	/**
+	 * 币种
+	 */
+	private String r4_Cur;
+	/**
+	 * 公用回传参数
+	 */
+	private String r5_Mp;
+	/**
+	 * 交易类型
+	 */
+	private String r6_FrpCode;
+	/**
+	 * 交易流水号
+	 */
+	private String r7_TrxNo;
+	/**
+	 * 银行商户编码
+	 */
+	private String r8_MerchantBankCode;
+	/**
+	 * 响应码,返回 100 时表示成功
+	 */
+	private String ra_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rb_CodeMsg;
+	/**
+	 * 1.主扫支付返回二维码地址。
+	 * 2.支付宝 H5,mode1/2/3 参考请求参数q9_TransactionModel 说明。
+	 * 3.微信 H5_PLUS,获取支付信息的 openlink,通过手机端浏览器跳转并唤起微信 APP客户端,直接打开对应的小程序进行支付。
+	 * 3.公众号支付:需要商户参考微信的官方文档 JSAPI 支付接口进行处理,详情请见:https://pay.weixin.qq.com/wiki/doc/api/index.html
+	 * 4.微信小程序支付返回支付信息。
+	 * 5.支付宝收银台返回支付宝收银台跳转链接,通过请求该链接跳转至支付宝。
+	 * 6.微信 app3 支付,返回预支付信息,集成微信 SDK 唤起小程序进行支付。
+	 * 7.支付宝服务窗支付返回银联交易号 trade_no,可用以唤起支付宝 APP,调起支付宝APP 收银台。
+	 * 8.银联 app 或银联统一收银台支付,返回预支付信息用此网址的接口调起支付。https://open.unionpay.com/tjweb/acproduct/list?apiservId=450#nav02
+	 * 9.银联云微小程序返回跳转地址,格式:{“cqpMpAppId”:”云闪付小程序 id”,”cqpMpPath”:”云闪付小程序 path”}
+	 * 10.其他类型支付返回支付信息。
+	 */
+	private String rc_Result;
+	/**
+	 * 二维码图片码
+	 */
+	private String rd_Pic;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ShoppingCartController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ShoppingCartController.java
index b9be064..c7e9265 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ShoppingCartController.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ShoppingCartController.java
@@ -9,6 +9,7 @@
 import com.ruoyi.common.core.web.page.TableDataInfo;
 import com.ruoyi.common.security.service.TokenService;
 import com.ruoyi.order.service.ShoppingCartService;
+import com.ruoyi.order.util.payment.model.UniPayCallbackResult;
 import com.ruoyi.order.vo.*;
 import com.ruoyi.other.api.domain.GoodsShop;
 import com.ruoyi.other.api.domain.Shop;
@@ -24,6 +25,9 @@
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -111,7 +115,53 @@
 	public R<String> shoppingCartPayment(@RequestBody ShoppingCartPayment shoppingCartPayment){
 		return shoppingCartService.shoppingCartPayment(shoppingCartPayment);
 	}
-
+	
+	/**
+	 * 订单支付回调通知
+	 */
+	@ResponseBody
+	@GetMapping("/shoppingCartPaymentCallback")
+	public void shoppingCartPaymentCallback(UniPayCallbackResult uniPayCallbackResult, HttpServletResponse response){
+		R callback = shoppingCartService.shoppingCartPaymentCallback(uniPayCallbackResult);
+		if(callback.getCode() == 200){
+			response.setStatus(200);
+			PrintWriter out = null;
+			try {
+				out = response.getWriter();
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+			out.println("success");
+			out.flush();
+			out.close();
+		}
+	}
+	
+	
+	/**
+	 * 快递费支付回调
+	 * @param uniPayCallbackResult
+	 * @param response
+	 */
+	@ResponseBody
+	@GetMapping("/shoppingCartMaterialFlowPaymentCallback")
+	public void shoppingCartMaterialFlowPaymentCallback(UniPayCallbackResult uniPayCallbackResult, HttpServletResponse response){
+		R callback = shoppingCartService.shoppingCartMaterialFlowPaymentCallback(uniPayCallbackResult);
+		if(callback.getCode() == 200){
+			response.setStatus(200);
+			PrintWriter out = null;
+			try {
+				out = response.getWriter();
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+			out.println("success");
+			out.flush();
+			out.close();
+		}
+	}
+	
+	
 
 	@ResponseBody
 	@GetMapping("/getVerifiableShop")
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/ShoppingCartService.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/ShoppingCartService.java
index 7e47d31..716921a 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/ShoppingCartService.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/ShoppingCartService.java
@@ -4,6 +4,7 @@
 import com.ruoyi.account.api.model.AppUser;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.order.model.ShoppingCart;
+import com.ruoyi.order.util.payment.model.UniPayCallbackResult;
 import com.ruoyi.order.vo.*;
 
 import java.util.List;
@@ -48,6 +49,29 @@
 	 * @return
 	 */
 	R shoppingCartPayment(ShoppingCartPayment shoppingCartPayment);
+	
+	
+	/**
+	 * 订单支付回调处理逻辑
+	 * @param uniPayCallbackResult
+	 * @return
+	 */
+	R shoppingCartPaymentCallback(UniPayCallbackResult uniPayCallbackResult);
+	
+	/**
+	 * 订单物流支付回调处理
+	 * @param uniPayCallbackResult
+	 * @return
+	 */
+	R shoppingCartMaterialFlowPaymentCallback(UniPayCallbackResult uniPayCallbackResult);
+	
 
 	Price getPrice(AppUser appUser, Integer goodsId, Integer shopId);
+	
+	
+	/**
+	 * 定时任务关闭订单
+	 */
+	void closeOrder();
+	
 }
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java
index e533c48..0ad64c1 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java
@@ -19,12 +19,18 @@
 import com.ruoyi.order.model.OrderGood;
 import com.ruoyi.order.model.ShoppingCart;
 import com.ruoyi.order.service.*;
+import com.ruoyi.order.util.payment.PaymentUtil;
+import com.ruoyi.order.util.payment.model.CloseOrderResult;
+import com.ruoyi.order.util.payment.model.UniPayCallbackResult;
+import com.ruoyi.order.util.payment.model.UniPayResult;
 import com.ruoyi.order.vo.*;
 import com.ruoyi.other.api.domain.*;
 import com.ruoyi.other.api.feignClient.*;
 import com.ruoyi.other.api.vo.GetGoodsBargainPrice;
 import com.ruoyi.other.api.vo.GetGoodsShopByGoodsIds;
 import com.ruoyi.other.api.vo.GetSeckillActivityInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -32,9 +38,11 @@
 import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.util.*;
 import java.util.stream.Collectors;
 
+@Slf4j
 @Service
 public class ShoppingCartServiceImpl extends ServiceImpl<ShoppingCartMapper, ShoppingCart> implements ShoppingCartService {
 
@@ -106,6 +114,11 @@
 	
 	@Resource
 	private OrderBalancePaymentService orderBalancePaymentService;
+	
+	@Resource
+	private RedisTemplate redisTemplate;
+	
+	
 	
 	
 	
@@ -726,9 +739,6 @@
 		for (MyShoppingCartVo myShoppingCartVo : goodsList) {
 			earnPoint += (myShoppingCartVo.getEarnSpendingPoints() * myShoppingCartVo.getNumber());
 		}
-		if(null != shoppingCartPayment.getUserAddressId()){
-			userAddressClient.getUserAddressById(shoppingCartPayment.getUserAddressId()).getData();
-		}
 
 		//获取快递策略,计算快递费
 		BigDecimal expressFee = BigDecimal.ZERO;
@@ -867,10 +877,18 @@
 		//现金支付
 		paymentMoney = paymentMoney.add(expressFee).setScale(2, RoundingMode.HALF_EVEN);
 		if(1 == shoppingCartPayment.getPaymentType()){
-			//调起微信支付 TODO 待完善
-
-
-
+			//调起微信支付
+			String goodsNames = goodsList.stream().map(MyShoppingCartVo::getName).collect(Collectors.joining("\n"));
+			UniPayResult uniPayResult = PaymentUtil.uniPay(order.getOrderNumber(), paymentMoney.doubleValue(), order.getOrderType() == 1 ? "购买服务商品" : "购买单品商品",
+					goodsNames, "", "/order/shopping-cart/shoppingCartPaymentCallback", appUser.getWxOpenid(), "");
+			if(null == uniPayResult || !"100".equals(uniPayResult.getRa_Code())){
+				return R.fail(null == uniPayResult ? "支付失败" : uniPayResult.getRb_CodeMsg());
+			}
+			String rc_result = uniPayResult.getRc_Result();
+			//将支付数据添加到redis队列中,便于定时任务去校验是否完成支付,没有完成支付支付,15分钟后关闭订单。
+			long second = LocalDateTime.now().plusMinutes(15).toEpochSecond(ZoneOffset.UTC);
+			redisTemplate.opsForZSet().add("OrderPayment", order.getOrderNumber(), second);
+			return R.ok(rc_result);
 		}
 		//账户余额
 		BigDecimal redPacketAmount = BigDecimal.ZERO;
@@ -956,6 +974,23 @@
 		}
 		//积分支付
 		if(3 == shoppingCartPayment.getPaymentType()){
+			//先完成快递费支付后再处理后续的逻辑
+			if(expressFee.compareTo(BigDecimal.ZERO) > 0){
+				if(shoppingCartPayment.getFreightPaymentType() == 1){
+					//调起微信支付
+					UniPayResult uniPayResult = PaymentUtil.uniPay(order.getOrderNumber() + appUser.getId(), expressFee.doubleValue(), order.getOrderType() == 1 ? "购买服务商品快递费" : "购买单品商品快递费",
+							"快递费", "", "/order/shopping-cart/shoppingCartMaterialFlowPaymentCallback", appUser.getWxOpenid(), "");
+					if(null == uniPayResult || !"100".equals(uniPayResult.getRa_Code())){
+						return R.fail(null == uniPayResult ? "支付失败" : uniPayResult.getRb_CodeMsg());
+					}
+					String rc_result = uniPayResult.getRc_Result();
+					//将支付数据添加到redis队列中,便于定时任务去校验是否完成支付,没有完成支付支付,15分钟后关闭订单。
+					long second = LocalDateTime.now().plusMinutes(15).toEpochSecond(ZoneOffset.UTC);
+					redisTemplate.opsForZSet().add("MaterialFlowPayment", order.getOrderNumber() + appUser.getId(), second);
+					return R.ok(rc_result);
+				}
+			}
+			
 			Integer lavePoint = appUser.getLavePoint();
 			PointSetting pointSetting = pointSettingClient.getPointSetting(appUser.getVipId()).getData();
 			int earnPoint1 = earnPoint;
@@ -989,9 +1024,6 @@
 			userPointClient.saveUserPoint(userPoint);
 			//如果有运费,需要先扣除账户积分,再进行支付。支付成功后修改订单状态,未支付成功则回退积分,删除的订单
 			if(expressFee.compareTo(BigDecimal.ZERO) > 0){
-				if(shoppingCartPayment.getFreightPaymentType() == 1){
-					//调起微信支付
-				}
 				if(shoppingCartPayment.getFreightPaymentType() == 2){
 					BigDecimal totalRedPacketAmount = appUser.getTotalRedPacketAmount();
 					BigDecimal totalDistributionAmount = appUser.getTotalDistributionAmount();
@@ -1067,7 +1099,7 @@
 		return R.ok(order.getId().toString());
 	}
 
-
+	
 	public String getNumber(Integer size){
 		String str = "";
 		for (Integer i = 0; i < size; i++) {
@@ -1075,6 +1107,165 @@
 		}
 		return str;
 	}
-
-
+	
+	
+	/**
+	 * 线上支付回调逻辑处理
+	 * @param uniPayCallbackResult
+	 * @return
+	 */
+	@Override
+	public R shoppingCartPaymentCallback(UniPayCallbackResult uniPayCallbackResult) {
+		Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, uniPayCallbackResult.getR2_OrderNo()));
+		if(null == order || order.getPayStatus() == 2){
+			return R.ok();
+		}
+		Integer earnPoint = order.getGetPoint();
+		AppUser appUser = appUserClient.getAppUserById(order.getAppUserId());
+		BigDecimal paymentMoney = order.getPaymentAmount();
+		//构建积分流水记录
+		if(earnPoint > 0){
+			PointSetting pointSetting = pointSettingClient.getPointSetting(appUser.getVipId()).getData();
+			int earnPoint1 = earnPoint;
+			if(null != pointSetting && 1 == pointSetting.getBuyPointOpen()){
+				earnPoint1 = new BigDecimal(earnPoint1).multiply(pointSetting.getBuyPoint().divide(new BigDecimal(100))).intValue();
+			}
+			appUser.setShopPoint(appUser.getShopPoint() + earnPoint);
+			appUser.setLavePoint(appUser.getLavePoint() + earnPoint);
+			appUser.setTotalPoint(appUser.getTotalPoint() + earnPoint);
+			appUser.setAvailablePoint(appUser.getAvailablePoint() + earnPoint1);
+			
+			UserPoint userPoint = new UserPoint();
+			userPoint.setType(1);
+			userPoint.setHistoricalPoint(appUser.getLavePoint() - earnPoint);
+			userPoint.setVariablePoint(earnPoint);
+			userPoint.setBalance(appUser.getLavePoint());
+			userPoint.setCreateTime(LocalDateTime.now());
+			userPoint.setAppUserId(appUser.getId());
+			userPoint.setObjectId(order.getId());
+			userPointClient.saveUserPoint(userPoint);
+		}
+		appUser.setShopAmount(appUser.getShopAmount().add(paymentMoney).setScale(2, RoundingMode.HALF_EVEN));
+		appUser.setLastShopTime(LocalDateTime.now());
+		appUserClient.editAppUserById(appUser);
+		//变更等级
+		appUserClient.vipUpgrade(appUser.getId());
+		//修改订支付状态
+		order.setPayStatus(2);
+		//自提
+		if(order.getOrderType() == 1 && StringUtils.isEmpty(order.getAddressJson())){
+			order.setOrderStatus(2);
+		}
+		orderService.updateById(order);
+		//删除购物车数据
+		Long userid = tokenService.getLoginUserApplet().getUserid();
+		List<OrderGood> list = orderGoodService.list(new LambdaQueryWrapper<OrderGood>().eq(OrderGood::getOrderId, order.getId()));
+		List<Integer> goodsIds = list.stream().map(OrderGood::getGoodsId).collect(Collectors.toList());
+		this.remove(new LambdaQueryWrapper<ShoppingCart>().eq(ShoppingCart::getAppUserId, userid).in(ShoppingCart::getGoodsId, goodsIds));
+		return R.ok();
+	}
+	
+	
+	/**
+	 * 订单物流支付回调处理逻辑
+	 * @param uniPayCallbackResult
+	 * @return
+	 */
+	@Override
+	public R shoppingCartMaterialFlowPaymentCallback(UniPayCallbackResult uniPayCallbackResult) {
+		String r2_orderNo = uniPayCallbackResult.getR2_OrderNo();
+		r2_orderNo = r2_orderNo.substring(0, 23);
+		Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, r2_orderNo));
+		if(null == order || order.getPayStatus() == 2){
+			return R.ok();
+		}
+		Integer earnPoint = order.getGetPoint();
+		AppUser appUser = appUserClient.getAppUserById(order.getAppUserId());
+		Integer lavePoint = appUser.getLavePoint();
+		Integer orderPoint = order.getPoint();
+		PointSetting pointSetting = pointSettingClient.getPointSetting(appUser.getVipId()).getData();
+		int earnPoint1 = earnPoint;
+		//计算可用积分比例
+		if(null != pointSetting && 1 == pointSetting.getBuyPointOpen()){
+			earnPoint1 = new BigDecimal(earnPoint1).multiply(pointSetting.getBuyPoint().divide(new BigDecimal(100))).intValue();
+		}
+		//扣减订单支付积分
+		appUser.setLavePoint(appUser.getLavePoint() - orderPoint);
+		appUser.setAvailablePoint(appUser.getAvailablePoint() - orderPoint);
+		
+		appUser.setShopPoint(appUser.getShopPoint() + earnPoint);
+		appUser.setLavePoint(appUser.getLavePoint() + earnPoint);
+		appUser.setAvailablePoint(appUser.getAvailablePoint() + earnPoint1);
+		appUser.setTotalPoint(appUser.getTotalPoint() + earnPoint);
+		appUser.setLastShopTime(LocalDateTime.now());
+		appUserClient.editAppUserById(appUser);
+		//变更等级
+		appUserClient.vipUpgrade(appUser.getId());
+		
+		//构建积分流水记录
+		UserPoint userPoint = new UserPoint();
+		userPoint.setType(1);
+		userPoint.setHistoricalPoint(lavePoint);
+		Integer point = appUser.getLavePoint() - lavePoint;
+		userPoint.setVariablePoint(point >= 0 ? point : point * -1);
+		userPoint.setBalance(appUser.getLavePoint());
+		userPoint.setCreateTime(LocalDateTime.now());
+		userPoint.setAppUserId(appUser.getId());
+		userPoint.setObjectId(order.getId());
+		userPointClient.saveUserPoint(userPoint);
+		//修改订支付状态
+		order.setPayStatus(2);
+		//自提
+		if(order.getOrderType() == 1 && StringUtils.isEmpty(order.getAddressJson())){
+			order.setOrderStatus(2);
+		}
+		orderService.updateById(order);
+		//删除购物车数据
+		Long userid = tokenService.getLoginUserApplet().getUserid();
+		List<OrderGood> list = orderGoodService.list(new LambdaQueryWrapper<OrderGood>().eq(OrderGood::getOrderId, order.getId()));
+		List<Integer> goodsIds = list.stream().map(OrderGood::getGoodsId).collect(Collectors.toList());
+		this.remove(new LambdaQueryWrapper<ShoppingCart>().eq(ShoppingCart::getAppUserId, userid).in(ShoppingCart::getGoodsId, goodsIds));
+		return R.ok();
+	}
+	
+	
+	/**
+	 * 定时任务关闭订单
+	 */
+	@Override
+	public void closeOrder() {
+		//订单支付数据
+		long second = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC);
+		Set<String> orderPayment = redisTemplate.opsForZSet().range("OrderPayment", 0, second);
+		for (String code : orderPayment) {
+			Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, code));
+			if(null == order || order.getPayStatus() != 1){
+				continue;
+			}
+			//开始执行关闭订单操作
+			CloseOrderResult closeOrderResult = PaymentUtil.closeOrder(code);
+			if((null == closeOrderResult || !closeOrderResult.getRa_Status().equals("100")) &&
+					Arrays.asList("0", "4", "101", "10080000", "10080002", "10083004", "10083005").contains(closeOrderResult.getRb_Code())){
+				redisTemplate.opsForZSet().add("OrderPayment", code, 0);
+				log.error("关闭订单失败:{}---->{}", code, JSON.toJSONString(closeOrderResult));
+			}
+		}
+		
+		//快递支付
+		Set<String> materialFlowPayment = redisTemplate.opsForZSet().range("MaterialFlowPayment", 0, second);
+		for (String code : materialFlowPayment) {
+			code = code.substring(0, 23);
+			Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, code));
+			if(null == order || order.getPayStatus() != 1){
+				continue;
+			}
+			//开始执行关闭订单操作
+			CloseOrderResult closeOrderResult = PaymentUtil.closeOrder(code);
+			if((null == closeOrderResult || !closeOrderResult.getRa_Status().equals("100")) &&
+					Arrays.asList("0", "4", "101", "10080000", "10080002", "10083004", "10083005").contains(closeOrderResult.getRb_Code())){
+				redisTemplate.opsForZSet().add("MaterialFlowPayment", code, 0);
+				log.error("关闭订单失败:{}---->{}", code, JSON.toJSONString(closeOrderResult));
+			}
+		}
+	}
 }
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/TaskUtil.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/TaskUtil.java
index 7c77100..07d8334 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/TaskUtil.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/TaskUtil.java
@@ -1,6 +1,7 @@
 package com.ruoyi.order.util;
 
 import com.ruoyi.order.service.CommissionService;
+import com.ruoyi.order.service.ShoppingCartService;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
@@ -16,10 +17,17 @@
 
     @Resource
     private CommissionService commissionService;
+    
+    @Resource
+    private ShoppingCartService shoppingCartService;
+    
+    
+    
 
     @Scheduled(fixedRate = 60000)
     public void taskMonth() {
         commissionService.calculationCommission();
+        shoppingCartService.closeOrder();
     }
 
     // 每天晚上23:59:59执行的定时任务
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/MD5AndKL.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/MD5AndKL.java
new file mode 100644
index 0000000..8abf33a
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/MD5AndKL.java
@@ -0,0 +1,112 @@
+package com.ruoyi.order.util.payment;
+
+import java.security.MessageDigest;
+
+public class MD5AndKL {
+	
+	/**
+	 * MD5加码。32位
+	 * 
+	 * @param inStr
+	 * @return
+	 */
+	public static String MD5(String inStr) {
+		MessageDigest md5 = null;
+		try {
+			md5 = MessageDigest.getInstance("MD5");
+		} catch (Exception e) {
+			throw new RuntimeException(e.toString());
+		}
+		byte[] md5Bytes = md5.digest(inStr.getBytes());
+		StringBuffer hexValue = new StringBuffer();
+		for (int i = 0; i < md5Bytes.length; i++) {
+			int val = ((int) md5Bytes[i]) & 0xff;
+			if (val < 16) {
+				hexValue.append("0");
+			}
+			hexValue.append(Integer.toHexString(val));
+		}
+		return hexValue.toString();
+	}
+
+	/**
+	 * 可逆的加密算法
+	 * 
+	 * @param inStr
+	 * @return
+	 */
+	public static String KL(String inStr) {
+		char[] a = inStr.toCharArray();
+		for (int i = 0; i < a.length; i++) {
+			a[i] = (char) (a[i] ^ 't');
+		}
+		String s = new String(a);
+		return s;
+	}
+
+	/**
+	 * 加密后解密
+	 * 
+	 * @param inStr
+	 * @return
+	 */
+	public static String JM(String inStr) {
+		char[] a = inStr.toCharArray();
+		for (int i = 0; i < a.length; i++) {
+			a[i] = (char) (a[i] ^ 't');
+		}
+		String k = new String(a);
+		return k;
+	}
+
+
+
+	private static String byteArrayToHexString(byte b[]) {
+		StringBuffer resultSb = new StringBuffer();
+		for (int i = 0; i < b.length; i++)
+			resultSb.append(byteToHexString(b[i]));
+
+		return resultSb.toString();
+	}
+
+	private static String byteToHexString(byte b) {
+		int n = b;
+		if (n < 0)
+			n += 256;
+		int d1 = n / 16;
+		int d2 = n % 16;
+		return hexDigits[d1] + hexDigits[d2];
+	}
+
+	public static String MD5Encode(String origin, String charsetname) {
+		String resultString = null;
+		try {
+			resultString = new String(origin);
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			if (charsetname == null || "".equals(charsetname)){
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
+			}else{
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
+			}
+		} catch (Exception exception) {
+			exception.printStackTrace();
+		}
+		return resultString;
+	}
+
+	private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
+			"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
+
+	public static void main(String args[]) {
+		 
+		System.out.println("MD5后再加密:" + KL(MD5("123456")));
+		System.out.println(MD5("123456"));
+		// System.out.println("加密:" + KL(MD5("123456")));
+		// s = KL(s);
+		// System.out.println("解密:" + KL("81dc9bdb52d04dc20036dbd8313ed055"));
+		// System.out.println("解密:" + JM(KL(s)));
+		// System.out.println("解密为MD5后的:" + KL(KL(MD5(s))));
+		// System.out.println(JM("5d62957bb57d3e49dcf48a0df064be4c"));
+		// System.out.println(MD5AndKL.KL(MD5AndKL.MD5("admin"+"87654321")));
+	}
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/PaymentUtil.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/PaymentUtil.java
new file mode 100644
index 0000000..6a6c88c
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/PaymentUtil.java
@@ -0,0 +1,276 @@
+package com.ruoyi.order.util.payment;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.order.util.payment.model.*;
+import lombok.extern.slf4j.Slf4j;
+import java.util.*;
+
+/**
+ * 支付工具类
+ * @author zhibing.pu
+ * @Date 2024/12/27 17:00
+ */
+@Slf4j
+public class PaymentUtil {
+	
+	//微信公众号、微信小程序、微信 APP+/H5、云微小程序支付
+	private static final String appId = "wxdeed472c98e42a54";
+	/**
+	 * 商户密钥
+	 */
+	private static final String key = "925899fcc374430f9e4b4ba3db05b448";
+	/**
+	 * 商户号
+	 */
+	private static final String merchantNo = "888122600004175";
+	/**
+	 * 支付回调地址
+	 */
+	private static final String callbackUrl = "http://221.182.45.100:9000";
+	
+	
+	/**
+	 * 支付
+	 * @param orderNo           商户订单号
+	 * @param amount            订单金额
+	 * @param productName       商品名称
+	 * @param productDesc       商品描述
+	 * @param mp                公用回传参数
+	 * @param notifyUrl         服务器异步通知地址
+	 * @param openId            微信 Openid
+	 * @param tradeMerchantNo   报备商户号
+	 * @return
+	 */
+	public static UniPayResult uniPay(String orderNo, Double amount, String productName, String productDesc, String mp, String notifyUrl, String openId, String tradeMerchantNo){
+		String url = "https://trade.joinpay.com/tradeRt/uniPay";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.5");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		//订单金额
+		body.put("p3_Amount", amount);
+		//交易币种
+		body.put("p4_Cur", "1");
+		//商品名称
+		body.put("p5_ProductName", productName);
+		//商品描述
+		body.put("p6_ProductDesc", productDesc);
+		//公用回传参数
+		body.put("p7_Mp", mp);
+		//服务器异步通知地址
+		body.put("p9_NotifyUrl", callbackUrl + notifyUrl);
+		//交易类型
+		body.put("q1_FrpCode", FrpCodeEnum.WEIXIN_XCX.getCode());
+		//微信 Openid
+		body.put("q5_OpenId", openId);
+		//APPID
+		body.put("q7_AppId", appId);
+		//报备商户号
+		body.put("qa_TradeMerchantNo", tradeMerchantNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("支付接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("支付接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("支付接口异常:" + execute.body());
+			return null;
+		}
+		UniPayResult uniPayResult = JSON.parseObject(execute.body(), UniPayResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 查询支付订单
+	 * @param orderNo   订单号
+	 * @return
+	 */
+	public static QueryOrderResult queryOrder(String orderNo){
+		String url = "https://trade.joinpay.com/tradeRt/queryOrder";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.5");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("查询支付接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("查询支付接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("查询支付接口异常:" + execute.body());
+			return null;
+		}
+		QueryOrderResult uniPayResult = JSON.parseObject(execute.body(), QueryOrderResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 退款
+	 * @param orderNo           支付订单号
+	 * @param refundOrderNo     退款订单号
+	 * @param refundAmount      退款金额
+	 * @param notifyUrl         异步通知地址
+	 * @return
+	 */
+	public static RefundResult refund(String orderNo, String refundOrderNo, Double refundAmount, String notifyUrl){
+		String url = "https://trade.joinpay.com/tradeRt/refund";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.3");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		//商户退款订单号
+		body.put("p3_RefundOrderNo", refundOrderNo);
+		//退款金额
+		body.put("p4_RefundAmount", refundAmount);
+		//服务器异步通知地址
+		body.put("p6_NotifyUrl", notifyUrl);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("退款接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("退款接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("退款接口异常:" + execute.body());
+			return null;
+		}
+		RefundResult uniPayResult = JSON.parseObject(execute.body(), RefundResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 查询退款订单
+	 * @param refundOrderNo 退款订单号
+	 * @return
+	 */
+	public static QueryRefundResult queryRefund(String refundOrderNo){
+		String url = "https://trade.joinpay.com/tradeRt/refund";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.3");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户退款订单号
+		body.put("p2_RefundOrderNo", refundOrderNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("退款接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("退款接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("退款接口异常:" + execute.body());
+			return null;
+		}
+		QueryRefundResult uniPayResult = JSON.parseObject(execute.body(), QueryRefundResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 关闭订单(仅支持微信和支付宝)
+	 * @param orderNo   订单号
+	 * @return
+	 */
+	public static CloseOrderResult closeOrder(String orderNo){
+		String url = "https://www.joinpay.com/trade/closeOrder.action";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		//交易类型
+		body.put("p3_FrpCode", FrpCodeEnum.WEIXIN_XCX.getCode());
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("关闭订单接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("关闭订单接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("关闭订单接口异常:" + execute.body());
+			return null;
+		}
+		CloseOrderResult uniPayResult = JSON.parseObject(execute.body(), CloseOrderResult.class);
+		return uniPayResult;
+	}
+	
+	
+	
+	public static String sign(JSONObject body) throws Exception{
+		Set<Map.Entry<String, Object>> entries = body.entrySet();
+		List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries);
+		// 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
+		Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
+			public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
+				return (o1.getKey()).toString().compareTo(o2.getKey());
+			}
+		});
+		// 构造签名键值对的格式
+		StringBuilder sb = new StringBuilder();
+		for (Map.Entry<String, Object> item : infoIds) {
+			if (item.getKey() != null || item.getKey() != "") {
+				Object val = item.getValue();
+				if (!(val == "" || val == null)) {
+					sb.append(val);
+				}
+			}
+		}
+		sb.append(key);
+		return MD5AndKL.MD5(sb.toString());
+	}
+	
+	
+	public static void main(String[] args) {
+		UniPayResult uniPayResult = PaymentUtil.uniPay("123456", 0.01D, "测试商品", "这是用于对接支付测试的商品描述", "", "", "", "");
+		System.err.println(JSON.toJSONString(uniPayResult));
+	}
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/TransferUtil.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/TransferUtil.java
new file mode 100644
index 0000000..c60dbc8
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/TransferUtil.java
@@ -0,0 +1,226 @@
+package com.ruoyi.order.util.payment;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.order.util.payment.model.*;
+import lombok.extern.slf4j.Slf4j;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+/**
+ * 转账代付工具类
+ * @author zhibing.pu
+ * @Date 2024/12/30 19:54
+ */
+@Slf4j
+public class TransferUtil {
+	/**
+	 * 商户密钥
+	 */
+	private static final String key = "925899fcc374430f9e4b4ba3db05b448";
+	/**
+	 * 商户号
+	 */
+	private static final String merchantNo = "888122600004175";
+	
+	private static final String format = "yyyy-MM-dd HH:mm:ss";
+	
+	
+	/**
+	 * 单笔代付
+	 * @param singlePay
+	 * @return
+	 */
+	public static SinglePayResult singlePay(SinglePay singlePay){
+		String url = "https://www.joinpay.com/payment/pay/singlePay";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("userNo", merchantNo);
+		//报备商户号
+		body.put("tradeMerchantNo", singlePay.getTradeMerchantNo());
+		//产品类型
+		body.put("productCode", "BANK_PAY_DAILY_ORDER");
+		//交易请求时间
+		body.put("requestTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern(format)));
+		//商户订单号
+		body.put("merchantOrderNo", singlePay.getMerchantOrderNo());
+		//收款账户号,收款人银行卡卡号
+		body.put("receiverAccountNoEnc", singlePay.getReceiverAccountNoEnc());
+		//收款人,收款人银行卡持卡人名称
+		body.put("receiverNameEnc", singlePay.getReceiverNameEnc());
+		//账户类型
+		body.put("receiverAccountType", singlePay.getReceiverAccountType());
+		//收款账户联行号 对公账户必须填写此字段
+		body.put("receiverBankChannelNo", singlePay.getReceiverBankChannelNo());
+		//交易金额
+		body.put("paidAmount", singlePay.getPaidAmount());
+		//币种
+		body.put("currency", "201");
+		//是否复核 复核:201,不复核:202
+		body.put("isChecked", "202");
+		//代付说明
+		body.put("paidDesc", singlePay.getPaidDesc());
+		//代付用途
+		/**
+		 * 工资奖金 201
+		 * 活动经费 202
+		 * 养老金 203
+		 * 货款 204
+		 * 劳务费 205
+		 * 保险理财 206
+		 * 资金下发 207
+		 * 营业款 208
+		 * 退回款项 210
+		 * 消费款项 211
+		 */
+		body.put("paidUse", singlePay.getPaidUse());
+		//商户通知地址
+		body.put("callbackUrl", singlePay.getCallbackUrl());
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("单笔代付接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("单笔代付接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("单笔代付接口异常:" + execute.body());
+			return null;
+		}
+		JSONObject jsonObject = JSON.parseObject(execute.body());
+		String statusCode = jsonObject.getString("statusCode");
+		if(!"2001".equals(statusCode) && !"2003".equals(statusCode)){
+			log.error("单笔代付接口异常:" + jsonObject.getString("message"));
+			return null;
+		}
+		if("2003".equals(statusCode)){
+			//汇聚不能确定订单状态,建议 10 分钟后发起查询确认。
+			log.error("单笔代付接口异常:汇聚不能确定订单状态,建议 10 分钟后发起查询确认。");
+			return null;
+		}
+		SinglePayResult uniPayResult = jsonObject.getObject("data", SinglePayResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 单笔代付查询接口
+	 * @param merchantOrderNo   订单号
+	 * @return
+	 */
+	public static SinglePayQueryResult singlePayQuery(String merchantOrderNo){
+		String url = "https://www.joinpay.com/payment/pay/singlePayQuery";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("userNo", merchantNo);
+		//商户订单号
+		body.put("merchantOrderNo", merchantOrderNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("单笔代付查询接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("单笔代付查询接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("单笔代付查询接口异常:" + execute.body());
+			return null;
+		}
+		JSONObject jsonObject = JSON.parseObject(execute.body());
+		String statusCode = jsonObject.getString("statusCode");
+		if(!"2001".equals(statusCode) && !"2003".equals(statusCode)){
+			log.error("单笔代付查询接口异常:" + jsonObject.getString("message"));
+			return null;
+		}
+		if("2003".equals(statusCode)){
+			//汇聚不能确定订单状态,建议 10 分钟后发起查询确认。
+			log.error("单笔代付查询接口异常:汇聚不能确定订单状态,建议 10 分钟后发起查询确认。");
+			return null;
+		}
+		SinglePayQueryResult uniPayResult = jsonObject.getObject("data", SinglePayQueryResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 可取余额查询
+	 * @return
+	 */
+	public static AccountBalanceQueryResult accountBalanceQuery(){
+		String url = "https://www.joinpay.com/payment/pay/accountBalanceQuery";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("userNo", merchantNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("可取余额查询接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("可取余额查询接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("可取余额查询接口异常:" + execute.body());
+			return null;
+		}
+		JSONObject jsonObject = JSON.parseObject(execute.body());
+		String statusCode = jsonObject.getString("statusCode");
+		if(!"2001".equals(statusCode) && !"2003".equals(statusCode)){
+			log.error("可取余额查询接口异常:" + jsonObject.getString("message"));
+			return null;
+		}
+		if("2003".equals(statusCode)){
+			//汇聚不能确定订单状态,建议 10 分钟后发起查询确认。
+			log.error("可取余额查询接口异常:汇聚不能确定订单状态,建议 10 分钟后发起查询确认。");
+			return null;
+		}
+		AccountBalanceQueryResult uniPayResult = jsonObject.getObject("data", AccountBalanceQueryResult.class);
+		return uniPayResult;
+	}
+	
+	
+	
+	
+	public static String sign(JSONObject body) throws Exception{
+		Set<Map.Entry<String, Object>> entries = body.entrySet();
+		List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries);
+		// 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
+		Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
+			public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
+				return (o1.getKey()).toString().compareTo(o2.getKey());
+			}
+		});
+		// 构造签名键值对的格式
+		StringBuilder sb = new StringBuilder();
+		for (Map.Entry<String, Object> item : infoIds) {
+			if (item.getKey() != null || item.getKey() != "") {
+				Object val = item.getValue();
+				if (!(val == "" || val == null)) {
+					sb.append(val);
+				}
+			}
+		}
+		sb.append(key);
+		return MD5AndKL.MD5(sb.toString());
+	}
+	
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/AccountBalanceQueryResult.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/AccountBalanceQueryResult.java
new file mode 100644
index 0000000..9e35f1f
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/AccountBalanceQueryResult.java
@@ -0,0 +1,43 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/31 10:34
+ */
+@Data
+public class AccountBalanceQueryResult {
+	/**
+	 * 商户号
+	 */
+	private String userNo;
+	/**
+	 * 商户名称
+	 */
+	private String userName;
+	/**
+	 * 币种
+	 */
+	private Integer currency;
+	/**
+	 * 可取金额
+	 */
+	private Double useAbleSettAmount;
+	/**
+	 * 可结算冻结金额
+	 */
+	private Double availableSettAmountFrozen;
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorDesc;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/CloseOrderResult.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/CloseOrderResult.java
new file mode 100644
index 0000000..df16d5e
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/CloseOrderResult.java
@@ -0,0 +1,45 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2025/1/1 10:15
+ */
+@Data
+public class CloseOrderResult {
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 业务结果 100:成功,101:失败
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 * 0 系统连接超时
+	 * 4 服务不可用
+	 * 100 关单成功
+	 * 101 失败,详见响应码描述
+	 * 10080000 系统异常
+	 * 10080002 验证签名失败
+	 * 10080003 订单号不正确
+	 * 10080042 交易类型不合法
+	 * 10083001 订单正在处理中
+	 * 10083002 该订单请求多次交易
+	 * 10083003 订单已关闭,无需关单操作
+	 * 10083003 交易成功,无需关单操作
+	 * 10083004 通道系统异常,请用相同参数重新请求
+	 * 10083005 通道其他异常信息
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/FrpCodeEnum.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/FrpCodeEnum.java
new file mode 100644
index 0000000..5b40201
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/FrpCodeEnum.java
@@ -0,0 +1,57 @@
+package com.ruoyi.order.util.payment.model;
+
+/**
+ * 支付类型枚举
+ * @author zhibing.pu
+ * @Date 2024/12/27 17:30
+ */
+public enum FrpCodeEnum {
+	ALIPAY_NATIVE("支付宝扫码(主扫)", "ALIPAY_NATIVE"),
+	ALIPAY_CARD("支付宝刷卡(被扫)", "ALIPAY_CARD"),
+	ALIPAY_H5("支付宝 H5", "ALIPAY_H5"),
+	ALIPAY_FWC("支付宝服务窗", "ALIPAY_FWC"),
+	ALIPAY_SYT("支付宝收银台", "ALIPAY_SYT"),
+	WEIXIN_NATIVE("微信扫码(主扫)", "WEIXIN_NATIVE"),
+	WEIXIN_CARD("微信刷卡(被扫)", "WEIXIN_CARD"),
+	WEIXIN_APP3("微信 APP+支付", "WEIXIN_APP3"),
+	WEIXIN_H5_PLUS("微信 H5 支付", "WEIXIN_H5_PLUS"),
+	WEIXIN_GZH("微信公众号支付", "WEIXIN_GZH"),
+	WEIXIN_XCX("微信小程序支付", "WEIXIN_XCX"),
+	QQ_NATIVE("QQ 扫码(主扫)", "QQ_NATIVE"),
+	QQ_CARD("QQ 刷卡(被扫)", "QQ_CARD"),
+	QQ_APP("QQ APP 支付", "QQ_APP"),
+	QQ_H5("QQH5 支付", "QQ_H5"),
+	QQ_GZH("QQ 公众号支付", "QQ_GZH"),
+	UNIONPAY_NATIVE("银联扫码(主扫)", "UNIONPAY_NATIVE"),
+	UNIONPAY_CARD("银联刷卡(被扫)", "UNIONPAY_CARD"),
+	UNIONPAY_APP("银联 APP 支付", "UNIONPAY_APP"),
+	UNIONPAY_H5("银联 H5", "UNIONPAY_H5"),
+	UNIONPAY_SYT("银联统一收银台", "UNIONPAY_SYT"),
+	UNIONPAY_WXMP("银联云微小程序(无感支付)", "UNIONPAY_WXMP")
+	;
+	
+	private String name;
+	
+	private String code;
+	
+	FrpCodeEnum(String name, String code) {
+		this.name = name;
+		this.code = code;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getCode() {
+		return code;
+	}
+	
+	public void setCode(String code) {
+		this.code = code;
+	}
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/QueryOrderResult.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/QueryOrderResult.java
new file mode 100644
index 0000000..ba5fff1
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/QueryOrderResult.java
@@ -0,0 +1,87 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:30
+ */
+@Data
+public class QueryOrderResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 支付金额
+	 */
+	private Double r3_Amount;
+	/**
+	 * 商品名称
+	 */
+	private String r4_ProductName;
+	/**
+	 * 交易流水号
+	 */
+	private String r5_TrxNo;
+	/**
+	 * 银行流水号
+	 */
+	private String r6_BankTrxNo;
+	/**
+	 * 订单手续费
+	 */
+	private Double r7_Fee;
+	/**
+	 * 交易类型
+	 */
+	private String r8_FrpCode;
+	/**
+	 * 订单状态 100:成功,101:失败,102:已创建,105:订单已关闭
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 用户标识
+	 */
+	private String rd_OpenId;
+	/**
+	 * 平台优惠金额
+	 */
+	private Double re_DiscountAmount;
+	/**
+	 * 支付时间
+	 */
+	private String rf_PayTime;
+	/**
+	 * 卡类型
+	 */
+	private String rh_cardType;
+	/**
+	 * 银行编码
+	 */
+	private String rj_BankCode;
+	/**
+	 * 签约 ID
+	 */
+	private String rl_ContractId;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/QueryRefundResult.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/QueryRefundResult.java
new file mode 100644
index 0000000..d452e33
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/QueryRefundResult.java
@@ -0,0 +1,62 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:56
+ */
+@Data
+public class QueryRefundResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户退款订单号
+	 */
+	private String r2_RefundOrderNo;
+	/**
+	 * 退款金额
+	 */
+	private Double r3_RefundAmount;
+	/**
+	 * 退款流水号
+	 */
+	private String r4_RefundTrxNo;
+	/**
+	 * 退款完成时间
+	 */
+	private String r5_RefundCompleteTime;
+	/**
+	 * 退款渠道
+	 */
+	private String r8_RefundWay;
+	/**
+	 * 退款入账账户
+	 */
+	private String r9_ReceiveAccountNo;
+	/**
+	 * 退款状态
+	 * 100:退款成功
+	 * 101:退款失败
+	 * 102:退款处理中
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/RefundCallbackResult.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/RefundCallbackResult.java
new file mode 100644
index 0000000..35af562
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/RefundCallbackResult.java
@@ -0,0 +1,63 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:50
+ */
+@Data
+public class RefundCallbackResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 商户退款订单号
+	 */
+	private String r3_RefundOrderNo;
+	/**
+	 * 退款金额
+	 */
+	private Double r4_RefundAmount;
+	/**
+	 * 商户退款流水号
+	 */
+	private String r5_RefundTrxNo;
+	/**
+	 * 退款完成时间
+	 */
+	private String r6_RefundCompleteTime;
+	/**
+	 * 退款渠道
+	 */
+	private String r7_RefundWay;
+	/**
+	 * 退款入账账户
+	 */
+	private String r8_ReceiveAccountNo;
+	/**
+	 * 退款状态 100:成功;101:失败
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/RefundResult.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/RefundResult.java
new file mode 100644
index 0000000..a559ca6
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/RefundResult.java
@@ -0,0 +1,59 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:43
+ */
+@Data
+public class RefundResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 商户退款订单号
+	 */
+	private String r3_RefundOrderNo;
+	/**
+	 * 退款金额
+	 */
+	private Double r4_RefundAmount;
+	/**
+	 * 商户退款流水号
+	 */
+	private String r5_RefundTrxNo;
+	/**
+	 * 退款申请状态
+	 * 100:成功,
+	 * 101:失败 。
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 营销退款金额
+	 */
+	private Double rd_MarketRefAmount;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+	
+	
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePay.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePay.java
new file mode 100644
index 0000000..5ca9b5d
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePay.java
@@ -0,0 +1,61 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 20:28
+ */
+@Data
+public class SinglePay {
+	/**
+	 * 报备商户号
+	 */
+	private String tradeMerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 收款账户号,收款人银行卡卡号
+	 */
+	private String receiverAccountNoEnc;
+	/**
+	 * 收款人,收款人银行卡持卡人名称
+	 */
+	private String receiverNameEnc;
+	/**
+	 * 账户类型 对私账户201,对公账户204
+	 */
+	private Integer receiverAccountType;
+	/**
+	 * 收款账户联行号 对公账户必须填写此字段
+	 */
+	private String receiverBankChannelNo;
+	/**
+	 * 交易金额
+	 */
+	private Double paidAmount;
+	/**
+	 * 代付说明
+	 */
+	private String paidDesc;
+	/**
+	 * 代付用途
+	 * 工资奖金 201
+	 * 活动经费 202
+	 * 养老金 203
+	 * 货款 204
+	 * 劳务费 205
+	 * 保险理财 206
+	 * 资金下发 207
+	 * 营业款 208
+	 * 退回款项 210
+	 * 消费款项 211
+	 */
+	private String paidUse;
+	/**
+	 * 商户通知地址
+	 */
+	private String callbackUrl;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayCallbackResult.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayCallbackResult.java
new file mode 100644
index 0000000..c4e45b1
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayCallbackResult.java
@@ -0,0 +1,64 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ *
+ * @author zhibing.pu
+ * @Date 2024/12/30 20:39
+ */
+@Data
+public class SinglePayCallbackResult {
+	/**
+	 * 交易状态
+	 */
+	private Integer status;
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorCodeDesc;
+	/**
+	 * 商户编号
+	 */
+	private String userNo;
+	/**
+	 * 报备商户号
+	 */
+	private String tradeMerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 平台流水号
+	 */
+	private String platformSerialNo;
+	/**
+	 * 收款账户号
+	 */
+	private String receiverAccountNoEnc;
+	/**
+	 * 收款人
+	 */
+	private String receiverNameEnc;
+	/**
+	 * 交易金额
+	 */
+	private Double paidAmount;
+	/**
+	 * 手续费
+	 */
+	private String fee;
+	/**
+	 * 完成时间
+	 */
+	private String completeTime;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayQueryResult.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayQueryResult.java
new file mode 100644
index 0000000..0460e12
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayQueryResult.java
@@ -0,0 +1,63 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/31 10:10
+ */
+@Data
+public class SinglePayQueryResult {
+	/**
+	 * 单笔代付查询请求的交易状态
+	 */
+	private Integer status;
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorDesc;
+	/**
+	 * 商户号
+	 */
+	private String userNo;
+	/**
+	 * 报备商户号
+	 */
+	private String tradeMerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 平台流水号
+	 */
+	private String platformSerialNo;
+	/**
+	 * 收款账户号
+	 */
+	private String receiverAccountNoEnc;
+	/**
+	 * 收款人
+	 */
+	private String receiverNameEnc;
+	/**
+	 * 交易金额
+	 */
+	private Double paidAmount;
+	/**
+	 * 手续费
+	 */
+	private Double fee;
+	/**
+	 * 完成时间
+	 */
+	private String completeTime;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayResult.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayResult.java
new file mode 100644
index 0000000..5001cc1
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/SinglePayResult.java
@@ -0,0 +1,31 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 20:36
+ */
+@Data
+public class SinglePayResult {
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorDesc;
+	/**
+	 * 商户编号
+	 */
+	private String userNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/UniPayCallbackResult.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/UniPayCallbackResult.java
new file mode 100644
index 0000000..8af2b3d
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/UniPayCallbackResult.java
@@ -0,0 +1,93 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:00
+ */
+@Data
+public class UniPayCallbackResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 支付金额
+	 */
+	private Double r3_Amount;
+	/**
+	 * 交易币种
+	 */
+	private String r4_Cur;
+	/**
+	 * 公用回传参数
+	 */
+	private String r5_Mp;
+	/**
+	 * 支付状态
+	 * 100:支付成功;
+	 * 101:支付失败。
+	 */
+	private String r6_Status;
+	/**
+	 * 交易流水号
+	 */
+	private String r7_TrxNo;
+	/**
+	 * 银行订单号
+	 */
+	private String r8_BankOrderNo;
+	/**
+	 * 银行流水号
+	 */
+	private String r9_BankTrxNo;
+	/**
+	 * 支付时间
+	 */
+	private String ra_PayTime;
+	/**
+	 * 交易结果通知时间
+	 */
+	private String rb_DealTime;
+	/**
+	 * 银行编码
+	 */
+	private String rc_BankCode;
+	/**
+	 * 用户标识
+	 */
+	private String rd_OpenId;
+	/**
+	 * 平台优惠金额
+	 */
+	private Double re_DiscountAmount;
+	/**
+	 * 卡类型
+	 */
+	private String rh_cardType;
+	/**
+	 * 订单手续费
+	 */
+	private Double rj_Fee;
+	/**
+	 * 交易类型
+	 */
+	private String rk_FrpCode;
+	/**
+	 * 签约 ID
+	 */
+	private String rl_ContractId;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/UniPayResult.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/UniPayResult.java
new file mode 100644
index 0000000..8f8aecc
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/model/UniPayResult.java
@@ -0,0 +1,77 @@
+package com.ruoyi.order.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 10:47
+ */
+@Data
+public class UniPayResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 支付金额
+	 */
+	private Double r3_Amount;
+	/**
+	 * 币种
+	 */
+	private String r4_Cur;
+	/**
+	 * 公用回传参数
+	 */
+	private String r5_Mp;
+	/**
+	 * 交易类型
+	 */
+	private String r6_FrpCode;
+	/**
+	 * 交易流水号
+	 */
+	private String r7_TrxNo;
+	/**
+	 * 银行商户编码
+	 */
+	private String r8_MerchantBankCode;
+	/**
+	 * 响应码,返回 100 时表示成功
+	 */
+	private String ra_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rb_CodeMsg;
+	/**
+	 * 1.主扫支付返回二维码地址。
+	 * 2.支付宝 H5,mode1/2/3 参考请求参数q9_TransactionModel 说明。
+	 * 3.微信 H5_PLUS,获取支付信息的 openlink,通过手机端浏览器跳转并唤起微信 APP客户端,直接打开对应的小程序进行支付。
+	 * 3.公众号支付:需要商户参考微信的官方文档 JSAPI 支付接口进行处理,详情请见:https://pay.weixin.qq.com/wiki/doc/api/index.html
+	 * 4.微信小程序支付返回支付信息。
+	 * 5.支付宝收银台返回支付宝收银台跳转链接,通过请求该链接跳转至支付宝。
+	 * 6.微信 app3 支付,返回预支付信息,集成微信 SDK 唤起小程序进行支付。
+	 * 7.支付宝服务窗支付返回银联交易号 trade_no,可用以唤起支付宝 APP,调起支付宝APP 收银台。
+	 * 8.银联 app 或银联统一收银台支付,返回预支付信息用此网址的接口调起支付。https://open.unionpay.com/tjweb/acproduct/list?apiservId=450#nav02
+	 * 9.银联云微小程序返回跳转地址,格式:{“cqpMpAppId”:”云闪付小程序 id”,”cqpMpPath”:”云闪付小程序 path”}
+	 * 10.其他类型支付返回支付信息。
+	 */
+	private String rc_Result;
+	/**
+	 * 二维码图片码
+	 */
+	private String rd_Pic;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopController.java
index 617ff88..f024e49 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopController.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopController.java
@@ -16,6 +16,7 @@
 import com.ruoyi.other.service.ShopScoreService;
 import com.ruoyi.other.service.ShopService;
 import com.ruoyi.other.vo.NearbyShopVO;
+import com.ruoyi.other.vo.SaveWithdrawalAccount;
 import com.ruoyi.other.vo.ShopDetailVO;
 import com.ruoyi.other.vo.ShopStatistics;
 import com.ruoyi.system.api.domain.SysUser;
@@ -312,5 +313,14 @@
     public void updateShop(@RequestBody Shop shop){
         shopService.updateById(shop);
     }
+    
+    
+    
+    @PostMapping("/saveWithdrawalAccount")
+    @ApiOperation(value = "保存提现账户", tags = {"门店后台-财务统计-提现明细"})
+    public R saveWithdrawalAccount(SaveWithdrawalAccount saveWithdrawalAccount) {
+        shopService.saveWithdrawalAccount(saveWithdrawalAccount);
+        return R.ok();
+    }
 }
 
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopWithdrawController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopWithdrawController.java
index c804805..f761f1e 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopWithdrawController.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopWithdrawController.java
@@ -1,17 +1,30 @@
 package com.ruoyi.other.controller;
 
 
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.account.api.feignClient.AppUserClient;
+import com.ruoyi.account.api.model.AppUser;
+import com.ruoyi.account.api.model.BalanceChangeRecord;
+import com.ruoyi.account.api.model.WithdrawalRequests;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.core.utils.StringUtils;
 import com.ruoyi.common.security.service.TokenService;
 import com.ruoyi.other.api.domain.Shop;
+import com.ruoyi.other.api.domain.ShopBalanceStatement;
 import com.ruoyi.other.api.domain.ShopWithdraw;
 import com.ruoyi.other.dto.ShopBalanceDto;
+import com.ruoyi.other.service.ShopBalanceStatementService;
 import com.ruoyi.other.service.ShopService;
 import com.ruoyi.other.service.ShopWithdrawService;
+import com.ruoyi.other.util.payment.TransferUtil;
+import com.ruoyi.other.util.payment.model.AccountBalanceQueryResult;
+import com.ruoyi.other.util.payment.model.SinglePay;
+import com.ruoyi.other.util.payment.model.SinglePayCallbackResult;
+import com.ruoyi.other.util.payment.model.SinglePayResult;
+import com.ruoyi.system.api.domain.SysUser;
 import com.ruoyi.system.api.model.LoginUser;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -20,6 +33,7 @@
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDateTime;
 
 /**
@@ -41,6 +55,15 @@
     private ShopService shopService;
     @Resource
     private TokenService tokenService;
+    
+    @Resource
+    private ShopBalanceStatementService shopBalanceStatementService;
+    
+    @Resource
+    private AppUserClient appUserClient;
+    
+    
+    
 
     /**
      * 提现申请列表
@@ -78,13 +101,18 @@
         Shop byId = shopService.getById(objectId);
         return R.ok(byId);
     }
+    
     @GetMapping("/shop/with")
     @ApiOperation(value = "提现申请", notes = "提现申请列表", tags = {"门店后台"})
-    public R<Shop> shopwith(@RequestParam BigDecimal money){
-        Integer objectId = tokenService.getLoginUser().getSysUser().getObjectId();
-        Shop byId = shopService.getById(objectId);
-        if (money.compareTo(byId.getCanWithdrawMoney())>0){
+    public R shopwith(@RequestParam BigDecimal money){
+        SysUser sysUser = tokenService.getLoginUser().getSysUser();
+        Integer objectId = sysUser.getObjectId();
+        Shop shop = shopService.getById(objectId);
+        if (money.compareTo(shop.getCanWithdrawMoney())>0){
             return R.fail("提现金额不能大于可提现金额");
+        }
+        if(StringUtils.isEmpty(shop.getReceiverAccountNoEnc())){
+            return R.fail("请完善账户信息后再申请提现!");
         }
         ShopWithdraw shopWithdraw = new ShopWithdraw();
         shopWithdraw.setShopId(objectId);
@@ -92,8 +120,26 @@
         shopWithdraw.setAuditStatus(0);
         shopWithdraw.setStatus(1);
         shopWithdrawService.save(shopWithdraw);
-
-        return R.ok(byId);
+        //扣除账户余额及添加变动明细
+        BigDecimal balance = shop.getBalance();
+        BigDecimal canWithdrawMoney = shop.getCanWithdrawMoney();
+        BigDecimal withdrawMoney = shop.getWithdrawMoney();
+        shop.setBalance(balance.subtract(money).setScale(2, RoundingMode.HALF_EVEN));
+        shop.setCanWithdrawMoney(canWithdrawMoney.subtract(money).setScale(2, RoundingMode.HALF_EVEN));
+        shop.setWithdrawMoney(withdrawMoney.add(money).setScale(2, RoundingMode.HALF_EVEN));
+        shopService.updateById(shop);
+        //添加门店变动明细
+        ShopBalanceStatement shopBalanceStatement = new ShopBalanceStatement();
+        shopBalanceStatement.setShopId(shop.getId());
+        shopBalanceStatement.setType(5);
+        shopBalanceStatement.setHistoricalBalance(balance);
+        shopBalanceStatement.setVariableAmount(money);
+        shopBalanceStatement.setBalance(shop.getBalance());
+        shopBalanceStatement.setCreateUserId(sysUser.getUserId());
+        shopBalanceStatement.setCreateTime(LocalDateTime.now());
+        shopBalanceStatement.setObjectId(shopWithdraw.getId());
+        shopBalanceStatementService.save(shopBalanceStatement);
+        return R.ok();
     }
 
 
@@ -105,6 +151,59 @@
     public R<Void> audit(@RequestBody ShopWithdraw shopWithdraw) {
         LoginUser loginUser = tokenService.getLoginUser();
         ShopWithdraw shopWithdraw1 = shopWithdrawService.getById(shopWithdraw.getId());
+        if(0 != shopWithdraw1.getAuditStatus()){
+            return R.fail("不能重复审核");
+        }
+        Shop shop = shopService.getById(shopWithdraw1.getShopId());
+        BigDecimal money = shopWithdraw1.getMoney();
+        if(1 == shopWithdraw.getAuditStatus()){
+            //先检查账户余额是否充足
+            AccountBalanceQueryResult accountBalanceQueryResult = TransferUtil.accountBalanceQuery();
+            if(null == accountBalanceQueryResult){
+                return R.fail("查询账户余额出错");
+            }
+            Double useAbleSettAmount = accountBalanceQueryResult.getUseAbleSettAmount();
+            if(useAbleSettAmount < shopWithdraw1.getMoney().doubleValue()){
+                return R.fail("账户可用余额不足,请先补充账户余额");
+            }
+            //银行卡转账
+            SinglePay singlePay = new SinglePay();
+            singlePay.setTradeMerchantNo("");
+            singlePay.setMerchantOrderNo(shopWithdraw1.getId().toString());
+            singlePay.setReceiverAccountNoEnc(shop.getReceiverAccountNoEnc());
+            singlePay.setReceiverNameEnc(shop.getReceiverNameEnc());
+            singlePay.setReceiverAccountType(shop.getReceiverAccountType());
+            singlePay.setPaidAmount(shopWithdraw1.getMoney().doubleValue());
+            singlePay.setPaidDesc("账户余额提现");
+            singlePay.setPaidUse("208");
+            singlePay.setCallbackUrl("/other/shop-withdraw/withdrawalCallback");
+            SinglePayResult singlePayResult = TransferUtil.singlePay(singlePay);
+            if(null == singlePayResult){
+                return R.fail("转账失败");
+            }
+            shopWithdraw1.setStatus(1);
+        }
+        if(2 == shopWithdraw.getAuditStatus()){
+            //回退金额和添加变动明细
+            BigDecimal balance = shop.getBalance();
+            BigDecimal canWithdrawMoney = shop.getCanWithdrawMoney();
+            BigDecimal withdrawMoney = shop.getWithdrawMoney();
+            shop.setBalance(balance.add(money).setScale(2, RoundingMode.HALF_EVEN));
+            shop.setCanWithdrawMoney(canWithdrawMoney.add(money).setScale(2, RoundingMode.HALF_EVEN));
+            shop.setWithdrawMoney(withdrawMoney.subtract(money).setScale(2, RoundingMode.HALF_EVEN));
+            shopService.updateById(shop);
+            //添加门店变动明细
+            ShopBalanceStatement shopBalanceStatement = new ShopBalanceStatement();
+            shopBalanceStatement.setShopId(shop.getId());
+            shopBalanceStatement.setType(5);
+            shopBalanceStatement.setHistoricalBalance(balance);
+            shopBalanceStatement.setVariableAmount(money);
+            shopBalanceStatement.setBalance(shop.getBalance());
+            shopBalanceStatement.setCreateUserId(loginUser.getUserid());
+            shopBalanceStatement.setCreateTime(LocalDateTime.now());
+            shopBalanceStatement.setObjectId(shopWithdraw.getId());
+            shopBalanceStatementService.save(shopBalanceStatement);
+        }
         shopWithdraw1.setAuditStatus(shopWithdraw.getAuditStatus());
         shopWithdraw1.setAuditUserId(loginUser.getUserid());
         shopWithdraw1.setAuditTime(LocalDateTime.now());
@@ -112,9 +211,30 @@
         shopWithdrawService.updateById(shopWithdraw1);
         return R.ok();
     }
-
-
-
-
+    
+    
+    
+    /**
+     * 提现审核通过后转账回调通知
+     * @param singlePayCallbackResult
+     */
+    @ResponseBody
+    @PostMapping("/withdrawalCallback")
+    public Object withdrawalCallback(@RequestBody SinglePayCallbackResult singlePayCallbackResult){
+        Integer status = singlePayCallbackResult.getStatus();
+        if(203 == status){
+            String merchantOrderNo = singlePayCallbackResult.getMerchantOrderNo();
+            ShopWithdraw shopWithdraw = shopWithdrawService.getById(merchantOrderNo);
+            if(1 == shopWithdraw.getStatus()){
+                shopWithdraw.setStatus(2);
+                shopWithdraw.setArrivalTime(LocalDateTime.now());
+                shopWithdrawService.updateById(shopWithdraw);
+            }
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("statusCode", 2001);
+            return jsonObject;
+        }
+        return new JSONObject();
+    }
 }
 
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/ShopService.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/ShopService.java
index 8729cd7..0967eb1 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/ShopService.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/ShopService.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.other.api.domain.Shop;
 import com.ruoyi.other.vo.NearbyShopVO;
+import com.ruoyi.other.vo.SaveWithdrawalAccount;
 import com.ruoyi.other.vo.ShopDetailVO;
 import io.swagger.annotations.ApiParam;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -28,5 +29,10 @@
     ShopDetailVO getShopDetail(Integer shopId, BigDecimal longitude, BigDecimal latitude);
 
     Boolean cheUserByPhone(String phone);
-
+    
+    /**
+     * 保存提现账户
+     * @param saveWithdrawalAccount
+     */
+    void saveWithdrawalAccount(SaveWithdrawalAccount saveWithdrawalAccount);
 }
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopServiceImpl.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopServiceImpl.java
index 1ada38b..212f7ae 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopServiceImpl.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopServiceImpl.java
@@ -16,7 +16,10 @@
 import com.ruoyi.other.service.ShopScoreService;
 import com.ruoyi.other.service.ShopService;
 import com.ruoyi.other.vo.NearbyShopVO;
+import com.ruoyi.other.vo.SaveWithdrawalAccount;
 import com.ruoyi.other.vo.ShopDetailVO;
+import com.ruoyi.system.api.domain.SysUser;
+import com.ruoyi.system.api.feignClient.SysUserClient;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -46,6 +49,8 @@
     private AppUserClient appUserClient;
     @Resource
     private TokenService tokenService;
+    @Resource
+    private SysUserClient sysUserClient;
 
 
     @Override
@@ -128,4 +133,23 @@
         }
         return r.getData() != null;
     }
+    
+    
+    /**
+     * 保存提现账户
+     * @param saveWithdrawalAccount
+     */
+    @Override
+    public void saveWithdrawalAccount(SaveWithdrawalAccount saveWithdrawalAccount) {
+        Long userid = tokenService.getLoginUser().getUserid();
+        SysUser sysUser = sysUserClient.getSysUser(userid).getData();
+        Shop shop = this.getById(sysUser.getObjectId());
+        if(null != shop){
+            shop.setReceiverAccountNoEnc(saveWithdrawalAccount.getReceiverAccountNoEnc());
+            shop.setReceiverNameEnc(saveWithdrawalAccount.getReceiverNameEnc());
+            shop.setReceiverAccountType(saveWithdrawalAccount.getReceiverAccountType());
+            shop.setReceiverBankChannelNo(saveWithdrawalAccount.getReceiverBankChannelNo());
+            this.updateById(shop);
+        }
+    }
 }
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/MD5AndKL.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/MD5AndKL.java
new file mode 100644
index 0000000..1a8ad14
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/MD5AndKL.java
@@ -0,0 +1,112 @@
+package com.ruoyi.other.util.payment;
+
+import java.security.MessageDigest;
+
+public class MD5AndKL {
+	
+	/**
+	 * MD5加码。32位
+	 * 
+	 * @param inStr
+	 * @return
+	 */
+	public static String MD5(String inStr) {
+		MessageDigest md5 = null;
+		try {
+			md5 = MessageDigest.getInstance("MD5");
+		} catch (Exception e) {
+			throw new RuntimeException(e.toString());
+		}
+		byte[] md5Bytes = md5.digest(inStr.getBytes());
+		StringBuffer hexValue = new StringBuffer();
+		for (int i = 0; i < md5Bytes.length; i++) {
+			int val = ((int) md5Bytes[i]) & 0xff;
+			if (val < 16) {
+				hexValue.append("0");
+			}
+			hexValue.append(Integer.toHexString(val));
+		}
+		return hexValue.toString();
+	}
+
+	/**
+	 * 可逆的加密算法
+	 * 
+	 * @param inStr
+	 * @return
+	 */
+	public static String KL(String inStr) {
+		char[] a = inStr.toCharArray();
+		for (int i = 0; i < a.length; i++) {
+			a[i] = (char) (a[i] ^ 't');
+		}
+		String s = new String(a);
+		return s;
+	}
+
+	/**
+	 * 加密后解密
+	 * 
+	 * @param inStr
+	 * @return
+	 */
+	public static String JM(String inStr) {
+		char[] a = inStr.toCharArray();
+		for (int i = 0; i < a.length; i++) {
+			a[i] = (char) (a[i] ^ 't');
+		}
+		String k = new String(a);
+		return k;
+	}
+
+
+
+	private static String byteArrayToHexString(byte b[]) {
+		StringBuffer resultSb = new StringBuffer();
+		for (int i = 0; i < b.length; i++)
+			resultSb.append(byteToHexString(b[i]));
+
+		return resultSb.toString();
+	}
+
+	private static String byteToHexString(byte b) {
+		int n = b;
+		if (n < 0)
+			n += 256;
+		int d1 = n / 16;
+		int d2 = n % 16;
+		return hexDigits[d1] + hexDigits[d2];
+	}
+
+	public static String MD5Encode(String origin, String charsetname) {
+		String resultString = null;
+		try {
+			resultString = new String(origin);
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			if (charsetname == null || "".equals(charsetname)){
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
+			}else{
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
+			}
+		} catch (Exception exception) {
+			exception.printStackTrace();
+		}
+		return resultString;
+	}
+
+	private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
+			"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
+
+	public static void main(String args[]) {
+		 
+		System.out.println("MD5后再加密:" + KL(MD5("123456")));
+		System.out.println(MD5("123456"));
+		// System.out.println("加密:" + KL(MD5("123456")));
+		// s = KL(s);
+		// System.out.println("解密:" + KL("81dc9bdb52d04dc20036dbd8313ed055"));
+		// System.out.println("解密:" + JM(KL(s)));
+		// System.out.println("解密为MD5后的:" + KL(KL(MD5(s))));
+		// System.out.println(JM("5d62957bb57d3e49dcf48a0df064be4c"));
+		// System.out.println(MD5AndKL.KL(MD5AndKL.MD5("admin"+"87654321")));
+	}
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/PaymentUtil.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/PaymentUtil.java
new file mode 100644
index 0000000..d37bc30
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/PaymentUtil.java
@@ -0,0 +1,277 @@
+package com.ruoyi.other.util.payment;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.other.util.payment.model.*;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.*;
+
+/**
+ * 支付工具类
+ * @author zhibing.pu
+ * @Date 2024/12/27 17:00
+ */
+@Slf4j
+public class PaymentUtil {
+	
+	//微信公众号、微信小程序、微信 APP+/H5、云微小程序支付
+	private static final String appId = "wxdeed472c98e42a54";
+	/**
+	 * 商户密钥
+	 */
+	private static final String key = "925899fcc374430f9e4b4ba3db05b448";
+	/**
+	 * 商户号
+	 */
+	private static final String merchantNo = "888122600004175";
+	/**
+	 * 支付回调地址
+	 */
+	private static final String callbackUrl = "http://221.182.45.100:9000";
+	
+	
+	/**
+	 * 支付
+	 * @param orderNo           商户订单号
+	 * @param amount            订单金额
+	 * @param productName       商品名称
+	 * @param productDesc       商品描述
+	 * @param mp                公用回传参数
+	 * @param notifyUrl         服务器异步通知地址
+	 * @param openId            微信 Openid
+	 * @param tradeMerchantNo   报备商户号
+	 * @return
+	 */
+	public static UniPayResult uniPay(String orderNo, Double amount, String productName, String productDesc, String mp, String notifyUrl, String openId, String tradeMerchantNo){
+		String url = "https://trade.joinpay.com/tradeRt/uniPay";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.5");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		//订单金额
+		body.put("p3_Amount", amount);
+		//交易币种
+		body.put("p4_Cur", "1");
+		//商品名称
+		body.put("p5_ProductName", productName);
+		//商品描述
+		body.put("p6_ProductDesc", productDesc);
+		//公用回传参数
+		body.put("p7_Mp", mp);
+		//服务器异步通知地址
+		body.put("p9_NotifyUrl", callbackUrl + notifyUrl);
+		//交易类型
+		body.put("q1_FrpCode", FrpCodeEnum.WEIXIN_XCX.getCode());
+		//微信 Openid
+		body.put("q5_OpenId", openId);
+		//APPID
+		body.put("q7_AppId", appId);
+		//报备商户号
+		body.put("qa_TradeMerchantNo", tradeMerchantNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("支付接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("支付接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("支付接口异常:" + execute.body());
+			return null;
+		}
+		UniPayResult uniPayResult = JSON.parseObject(execute.body(), UniPayResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 查询支付订单
+	 * @param orderNo   订单号
+	 * @return
+	 */
+	public static QueryOrderResult queryOrder(String orderNo){
+		String url = "https://trade.joinpay.com/tradeRt/queryOrder";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.5");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("查询支付接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("查询支付接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("查询支付接口异常:" + execute.body());
+			return null;
+		}
+		QueryOrderResult uniPayResult = JSON.parseObject(execute.body(), QueryOrderResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 退款
+	 * @param orderNo           支付订单号
+	 * @param refundOrderNo     退款订单号
+	 * @param refundAmount      退款金额
+	 * @param notifyUrl         异步通知地址
+	 * @return
+	 */
+	public static RefundResult refund(String orderNo, String refundOrderNo, Double refundAmount, String notifyUrl){
+		String url = "https://trade.joinpay.com/tradeRt/refund";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.3");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		//商户退款订单号
+		body.put("p3_RefundOrderNo", refundOrderNo);
+		//退款金额
+		body.put("p4_RefundAmount", refundAmount);
+		//服务器异步通知地址
+		body.put("p6_NotifyUrl", notifyUrl);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("退款接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("退款接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("退款接口异常:" + execute.body());
+			return null;
+		}
+		RefundResult uniPayResult = JSON.parseObject(execute.body(), RefundResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 查询退款订单
+	 * @param refundOrderNo 退款订单号
+	 * @return
+	 */
+	public static QueryRefundResult queryRefund(String refundOrderNo){
+		String url = "https://trade.joinpay.com/tradeRt/refund";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//版本号
+		body.put("p0_Version", "2.3");
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户退款订单号
+		body.put("p2_RefundOrderNo", refundOrderNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("退款接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("退款接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("退款接口异常:" + execute.body());
+			return null;
+		}
+		QueryRefundResult uniPayResult = JSON.parseObject(execute.body(), QueryRefundResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 关闭订单(仅支持微信和支付宝)
+	 * @param orderNo   订单号
+	 * @return
+	 */
+	public static CloseOrderResult closeOrder(String orderNo){
+		String url = "https://www.joinpay.com/trade/closeOrder.action";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("p1_MerchantNo", merchantNo);
+		//商户订单号
+		body.put("p2_OrderNo", orderNo);
+		//交易类型
+		body.put("p3_FrpCode", FrpCodeEnum.WEIXIN_XCX.getCode());
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("关闭订单接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("关闭订单接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("关闭订单接口异常:" + execute.body());
+			return null;
+		}
+		CloseOrderResult uniPayResult = JSON.parseObject(execute.body(), CloseOrderResult.class);
+		return uniPayResult;
+	}
+	
+	
+	
+	public static String sign(JSONObject body) throws Exception{
+		Set<Map.Entry<String, Object>> entries = body.entrySet();
+		List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries);
+		// 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
+		Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
+			public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
+				return (o1.getKey()).toString().compareTo(o2.getKey());
+			}
+		});
+		// 构造签名键值对的格式
+		StringBuilder sb = new StringBuilder();
+		for (Map.Entry<String, Object> item : infoIds) {
+			if (item.getKey() != null || item.getKey() != "") {
+				Object val = item.getValue();
+				if (!(val == "" || val == null)) {
+					sb.append(val);
+				}
+			}
+		}
+		sb.append(key);
+		return MD5AndKL.MD5(sb.toString());
+	}
+	
+	
+	public static void main(String[] args) {
+		UniPayResult uniPayResult = PaymentUtil.uniPay("123456", 0.01D, "测试商品", "这是用于对接支付测试的商品描述", "", "", "", "");
+		System.err.println(JSON.toJSONString(uniPayResult));
+	}
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/TransferUtil.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/TransferUtil.java
new file mode 100644
index 0000000..f8d6139
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/TransferUtil.java
@@ -0,0 +1,229 @@
+package com.ruoyi.other.util.payment;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.other.util.payment.model.AccountBalanceQueryResult;
+import com.ruoyi.other.util.payment.model.SinglePay;
+import com.ruoyi.other.util.payment.model.SinglePayQueryResult;
+import com.ruoyi.other.util.payment.model.SinglePayResult;
+import lombok.extern.slf4j.Slf4j;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+/**
+ * 转账代付工具类
+ * @author zhibing.pu
+ * @Date 2024/12/30 19:54
+ */
+@Slf4j
+public class TransferUtil {
+	/**
+	 * 商户密钥
+	 */
+	private static final String key = "925899fcc374430f9e4b4ba3db05b448";
+	/**
+	 * 商户号
+	 */
+	private static final String merchantNo = "888122600004175";
+	
+	private static final String format = "yyyy-MM-dd HH:mm:ss";
+	
+	
+	/**
+	 * 单笔代付
+	 * @param singlePay
+	 * @return
+	 */
+	public static SinglePayResult singlePay(SinglePay singlePay){
+		String url = "https://www.joinpay.com/payment/pay/singlePay";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("userNo", merchantNo);
+		//报备商户号
+		body.put("tradeMerchantNo", singlePay.getTradeMerchantNo());
+		//产品类型
+		body.put("productCode", "BANK_PAY_DAILY_ORDER");
+		//交易请求时间
+		body.put("requestTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern(format)));
+		//商户订单号
+		body.put("merchantOrderNo", singlePay.getMerchantOrderNo());
+		//收款账户号,收款人银行卡卡号
+		body.put("receiverAccountNoEnc", singlePay.getReceiverAccountNoEnc());
+		//收款人,收款人银行卡持卡人名称
+		body.put("receiverNameEnc", singlePay.getReceiverNameEnc());
+		//账户类型
+		body.put("receiverAccountType", singlePay.getReceiverAccountType());
+		//收款账户联行号 对公账户必须填写此字段
+		body.put("receiverBankChannelNo", singlePay.getReceiverBankChannelNo());
+		//交易金额
+		body.put("paidAmount", singlePay.getPaidAmount());
+		//币种
+		body.put("currency", "201");
+		//是否复核 复核:201,不复核:202
+		body.put("isChecked", "202");
+		//代付说明
+		body.put("paidDesc", singlePay.getPaidDesc());
+		//代付用途
+		/**
+		 * 工资奖金 201
+		 * 活动经费 202
+		 * 养老金 203
+		 * 货款 204
+		 * 劳务费 205
+		 * 保险理财 206
+		 * 资金下发 207
+		 * 营业款 208
+		 * 退回款项 210
+		 * 消费款项 211
+		 */
+		body.put("paidUse", singlePay.getPaidUse());
+		//商户通知地址
+		body.put("callbackUrl", singlePay.getCallbackUrl());
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("单笔代付接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("单笔代付接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("单笔代付接口异常:" + execute.body());
+			return null;
+		}
+		JSONObject jsonObject = JSON.parseObject(execute.body());
+		String statusCode = jsonObject.getString("statusCode");
+		if(!"2001".equals(statusCode) && !"2003".equals(statusCode)){
+			log.error("单笔代付接口异常:" + jsonObject.getString("message"));
+			return null;
+		}
+		if("2003".equals(statusCode)){
+			//汇聚不能确定订单状态,建议 10 分钟后发起查询确认。
+			log.error("单笔代付接口异常:汇聚不能确定订单状态,建议 10 分钟后发起查询确认。");
+			return null;
+		}
+		SinglePayResult uniPayResult = jsonObject.getObject("data", SinglePayResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 单笔代付查询接口
+	 * @param merchantOrderNo   订单号
+	 * @return
+	 */
+	public static SinglePayQueryResult singlePayQuery(String merchantOrderNo){
+		String url = "https://www.joinpay.com/payment/pay/singlePayQuery";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("userNo", merchantNo);
+		//商户订单号
+		body.put("merchantOrderNo", merchantOrderNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("单笔代付查询接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("单笔代付查询接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("单笔代付查询接口异常:" + execute.body());
+			return null;
+		}
+		JSONObject jsonObject = JSON.parseObject(execute.body());
+		String statusCode = jsonObject.getString("statusCode");
+		if(!"2001".equals(statusCode) && !"2003".equals(statusCode)){
+			log.error("单笔代付查询接口异常:" + jsonObject.getString("message"));
+			return null;
+		}
+		if("2003".equals(statusCode)){
+			//汇聚不能确定订单状态,建议 10 分钟后发起查询确认。
+			log.error("单笔代付查询接口异常:汇聚不能确定订单状态,建议 10 分钟后发起查询确认。");
+			return null;
+		}
+		SinglePayQueryResult uniPayResult = jsonObject.getObject("data", SinglePayQueryResult.class);
+		return uniPayResult;
+	}
+	
+	
+	/**
+	 * 可取余额查询
+	 * @return
+	 */
+	public static AccountBalanceQueryResult accountBalanceQuery(){
+		String url = "https://www.joinpay.com/payment/pay/accountBalanceQuery";
+		HttpRequest post = HttpUtil.createPost(url);
+		JSONObject body = new JSONObject();
+		//商户编号
+		body.put("userNo", merchantNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.body(body.toString());
+		log.info("可取余额查询接口请求参数:" + body);
+		HttpResponse execute = post.execute();
+		log.info("可取余额查询接口请求响应:" + execute.body());
+		if(200 != execute.getStatus()){
+			log.error("可取余额查询接口异常:" + execute.body());
+			return null;
+		}
+		JSONObject jsonObject = JSON.parseObject(execute.body());
+		String statusCode = jsonObject.getString("statusCode");
+		if(!"2001".equals(statusCode) && !"2003".equals(statusCode)){
+			log.error("可取余额查询接口异常:" + jsonObject.getString("message"));
+			return null;
+		}
+		if("2003".equals(statusCode)){
+			//汇聚不能确定订单状态,建议 10 分钟后发起查询确认。
+			log.error("可取余额查询接口异常:汇聚不能确定订单状态,建议 10 分钟后发起查询确认。");
+			return null;
+		}
+		AccountBalanceQueryResult uniPayResult = jsonObject.getObject("data", AccountBalanceQueryResult.class);
+		return uniPayResult;
+	}
+	
+	
+	
+	
+	public static String sign(JSONObject body) throws Exception{
+		Set<Map.Entry<String, Object>> entries = body.entrySet();
+		List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries);
+		// 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
+		Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
+			public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
+				return (o1.getKey()).toString().compareTo(o2.getKey());
+			}
+		});
+		// 构造签名键值对的格式
+		StringBuilder sb = new StringBuilder();
+		for (Map.Entry<String, Object> item : infoIds) {
+			if (item.getKey() != null || item.getKey() != "") {
+				Object val = item.getValue();
+				if (!(val == "" || val == null)) {
+					sb.append(val);
+				}
+			}
+		}
+		sb.append(key);
+		return MD5AndKL.MD5(sb.toString());
+	}
+	
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/AccountBalanceQueryResult.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/AccountBalanceQueryResult.java
new file mode 100644
index 0000000..f302966
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/AccountBalanceQueryResult.java
@@ -0,0 +1,43 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/31 10:34
+ */
+@Data
+public class AccountBalanceQueryResult {
+	/**
+	 * 商户号
+	 */
+	private String userNo;
+	/**
+	 * 商户名称
+	 */
+	private String userName;
+	/**
+	 * 币种
+	 */
+	private Integer currency;
+	/**
+	 * 可取金额
+	 */
+	private Double useAbleSettAmount;
+	/**
+	 * 可结算冻结金额
+	 */
+	private Double availableSettAmountFrozen;
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorDesc;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/CloseOrderResult.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/CloseOrderResult.java
new file mode 100644
index 0000000..72170da
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/CloseOrderResult.java
@@ -0,0 +1,45 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2025/1/1 10:15
+ */
+@Data
+public class CloseOrderResult {
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 业务结果 100:成功,101:失败
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 * 0 系统连接超时
+	 * 4 服务不可用
+	 * 100 关单成功
+	 * 101 失败,详见响应码描述
+	 * 10080000 系统异常
+	 * 10080002 验证签名失败
+	 * 10080003 订单号不正确
+	 * 10080042 交易类型不合法
+	 * 10083001 订单正在处理中
+	 * 10083002 该订单请求多次交易
+	 * 10083003 订单已关闭,无需关单操作
+	 * 10083003 交易成功,无需关单操作
+	 * 10083004 通道系统异常,请用相同参数重新请求
+	 * 10083005 通道其他异常信息
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/FrpCodeEnum.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/FrpCodeEnum.java
new file mode 100644
index 0000000..086eab5
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/FrpCodeEnum.java
@@ -0,0 +1,57 @@
+package com.ruoyi.other.util.payment.model;
+
+/**
+ * 支付类型枚举
+ * @author zhibing.pu
+ * @Date 2024/12/27 17:30
+ */
+public enum FrpCodeEnum {
+	ALIPAY_NATIVE("支付宝扫码(主扫)", "ALIPAY_NATIVE"),
+	ALIPAY_CARD("支付宝刷卡(被扫)", "ALIPAY_CARD"),
+	ALIPAY_H5("支付宝 H5", "ALIPAY_H5"),
+	ALIPAY_FWC("支付宝服务窗", "ALIPAY_FWC"),
+	ALIPAY_SYT("支付宝收银台", "ALIPAY_SYT"),
+	WEIXIN_NATIVE("微信扫码(主扫)", "WEIXIN_NATIVE"),
+	WEIXIN_CARD("微信刷卡(被扫)", "WEIXIN_CARD"),
+	WEIXIN_APP3("微信 APP+支付", "WEIXIN_APP3"),
+	WEIXIN_H5_PLUS("微信 H5 支付", "WEIXIN_H5_PLUS"),
+	WEIXIN_GZH("微信公众号支付", "WEIXIN_GZH"),
+	WEIXIN_XCX("微信小程序支付", "WEIXIN_XCX"),
+	QQ_NATIVE("QQ 扫码(主扫)", "QQ_NATIVE"),
+	QQ_CARD("QQ 刷卡(被扫)", "QQ_CARD"),
+	QQ_APP("QQ APP 支付", "QQ_APP"),
+	QQ_H5("QQH5 支付", "QQ_H5"),
+	QQ_GZH("QQ 公众号支付", "QQ_GZH"),
+	UNIONPAY_NATIVE("银联扫码(主扫)", "UNIONPAY_NATIVE"),
+	UNIONPAY_CARD("银联刷卡(被扫)", "UNIONPAY_CARD"),
+	UNIONPAY_APP("银联 APP 支付", "UNIONPAY_APP"),
+	UNIONPAY_H5("银联 H5", "UNIONPAY_H5"),
+	UNIONPAY_SYT("银联统一收银台", "UNIONPAY_SYT"),
+	UNIONPAY_WXMP("银联云微小程序(无感支付)", "UNIONPAY_WXMP")
+	;
+	
+	private String name;
+	
+	private String code;
+	
+	FrpCodeEnum(String name, String code) {
+		this.name = name;
+		this.code = code;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getCode() {
+		return code;
+	}
+	
+	public void setCode(String code) {
+		this.code = code;
+	}
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/QueryOrderResult.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/QueryOrderResult.java
new file mode 100644
index 0000000..f4a8e1f
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/QueryOrderResult.java
@@ -0,0 +1,87 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:30
+ */
+@Data
+public class QueryOrderResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 支付金额
+	 */
+	private Double r3_Amount;
+	/**
+	 * 商品名称
+	 */
+	private String r4_ProductName;
+	/**
+	 * 交易流水号
+	 */
+	private String r5_TrxNo;
+	/**
+	 * 银行流水号
+	 */
+	private String r6_BankTrxNo;
+	/**
+	 * 订单手续费
+	 */
+	private Double r7_Fee;
+	/**
+	 * 交易类型
+	 */
+	private String r8_FrpCode;
+	/**
+	 * 订单状态 100:成功,101:失败,102:已创建,105:订单已关闭
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 用户标识
+	 */
+	private String rd_OpenId;
+	/**
+	 * 平台优惠金额
+	 */
+	private Double re_DiscountAmount;
+	/**
+	 * 支付时间
+	 */
+	private String rf_PayTime;
+	/**
+	 * 卡类型
+	 */
+	private String rh_cardType;
+	/**
+	 * 银行编码
+	 */
+	private String rj_BankCode;
+	/**
+	 * 签约 ID
+	 */
+	private String rl_ContractId;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/QueryRefundResult.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/QueryRefundResult.java
new file mode 100644
index 0000000..6a2a632
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/QueryRefundResult.java
@@ -0,0 +1,62 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:56
+ */
+@Data
+public class QueryRefundResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户退款订单号
+	 */
+	private String r2_RefundOrderNo;
+	/**
+	 * 退款金额
+	 */
+	private Double r3_RefundAmount;
+	/**
+	 * 退款流水号
+	 */
+	private String r4_RefundTrxNo;
+	/**
+	 * 退款完成时间
+	 */
+	private String r5_RefundCompleteTime;
+	/**
+	 * 退款渠道
+	 */
+	private String r8_RefundWay;
+	/**
+	 * 退款入账账户
+	 */
+	private String r9_ReceiveAccountNo;
+	/**
+	 * 退款状态
+	 * 100:退款成功
+	 * 101:退款失败
+	 * 102:退款处理中
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/RefundCallbackResult.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/RefundCallbackResult.java
new file mode 100644
index 0000000..326d69a
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/RefundCallbackResult.java
@@ -0,0 +1,63 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:50
+ */
+@Data
+public class RefundCallbackResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 商户退款订单号
+	 */
+	private String r3_RefundOrderNo;
+	/**
+	 * 退款金额
+	 */
+	private Double r4_RefundAmount;
+	/**
+	 * 商户退款流水号
+	 */
+	private String r5_RefundTrxNo;
+	/**
+	 * 退款完成时间
+	 */
+	private String r6_RefundCompleteTime;
+	/**
+	 * 退款渠道
+	 */
+	private String r7_RefundWay;
+	/**
+	 * 退款入账账户
+	 */
+	private String r8_ReceiveAccountNo;
+	/**
+	 * 退款状态 100:成功;101:失败
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/RefundResult.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/RefundResult.java
new file mode 100644
index 0000000..98e1d5a
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/RefundResult.java
@@ -0,0 +1,59 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:43
+ */
+@Data
+public class RefundResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 商户退款订单号
+	 */
+	private String r3_RefundOrderNo;
+	/**
+	 * 退款金额
+	 */
+	private Double r4_RefundAmount;
+	/**
+	 * 商户退款流水号
+	 */
+	private String r5_RefundTrxNo;
+	/**
+	 * 退款申请状态
+	 * 100:成功,
+	 * 101:失败 。
+	 */
+	private String ra_Status;
+	/**
+	 * 响应码
+	 */
+	private String rb_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rc_CodeMsg;
+	/**
+	 * 营销退款金额
+	 */
+	private Double rd_MarketRefAmount;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+	
+	
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePay.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePay.java
new file mode 100644
index 0000000..831cd7f
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePay.java
@@ -0,0 +1,61 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 20:28
+ */
+@Data
+public class SinglePay {
+	/**
+	 * 报备商户号
+	 */
+	private String tradeMerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 收款账户号,收款人银行卡卡号
+	 */
+	private String receiverAccountNoEnc;
+	/**
+	 * 收款人,收款人银行卡持卡人名称
+	 */
+	private String receiverNameEnc;
+	/**
+	 * 账户类型 对私账户201,对公账户204
+	 */
+	private Integer receiverAccountType;
+	/**
+	 * 收款账户联行号 对公账户必须填写此字段
+	 */
+	private String receiverBankChannelNo;
+	/**
+	 * 交易金额
+	 */
+	private Double paidAmount;
+	/**
+	 * 代付说明
+	 */
+	private String paidDesc;
+	/**
+	 * 代付用途
+	 * 工资奖金 201
+	 * 活动经费 202
+	 * 养老金 203
+	 * 货款 204
+	 * 劳务费 205
+	 * 保险理财 206
+	 * 资金下发 207
+	 * 营业款 208
+	 * 退回款项 210
+	 * 消费款项 211
+	 */
+	private String paidUse;
+	/**
+	 * 商户通知地址
+	 */
+	private String callbackUrl;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayCallbackResult.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayCallbackResult.java
new file mode 100644
index 0000000..6953a5a
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayCallbackResult.java
@@ -0,0 +1,64 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ *
+ * @author zhibing.pu
+ * @Date 2024/12/30 20:39
+ */
+@Data
+public class SinglePayCallbackResult {
+	/**
+	 * 交易状态
+	 */
+	private Integer status;
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorCodeDesc;
+	/**
+	 * 商户编号
+	 */
+	private String userNo;
+	/**
+	 * 报备商户号
+	 */
+	private String tradeMerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 平台流水号
+	 */
+	private String platformSerialNo;
+	/**
+	 * 收款账户号
+	 */
+	private String receiverAccountNoEnc;
+	/**
+	 * 收款人
+	 */
+	private String receiverNameEnc;
+	/**
+	 * 交易金额
+	 */
+	private Double paidAmount;
+	/**
+	 * 手续费
+	 */
+	private String fee;
+	/**
+	 * 完成时间
+	 */
+	private String completeTime;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayQueryResult.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayQueryResult.java
new file mode 100644
index 0000000..5dac9d6
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayQueryResult.java
@@ -0,0 +1,63 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/31 10:10
+ */
+@Data
+public class SinglePayQueryResult {
+	/**
+	 * 单笔代付查询请求的交易状态
+	 */
+	private Integer status;
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorDesc;
+	/**
+	 * 商户号
+	 */
+	private String userNo;
+	/**
+	 * 报备商户号
+	 */
+	private String tradeMerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 平台流水号
+	 */
+	private String platformSerialNo;
+	/**
+	 * 收款账户号
+	 */
+	private String receiverAccountNoEnc;
+	/**
+	 * 收款人
+	 */
+	private String receiverNameEnc;
+	/**
+	 * 交易金额
+	 */
+	private Double paidAmount;
+	/**
+	 * 手续费
+	 */
+	private Double fee;
+	/**
+	 * 完成时间
+	 */
+	private String completeTime;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayResult.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayResult.java
new file mode 100644
index 0000000..70b55ee
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/SinglePayResult.java
@@ -0,0 +1,31 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 20:36
+ */
+@Data
+public class SinglePayResult {
+	/**
+	 * 错误码
+	 */
+	private String errorCode;
+	/**
+	 * 错误描述
+	 */
+	private String errorDesc;
+	/**
+	 * 商户编号
+	 */
+	private String userNo;
+	/**
+	 * 商户订单号
+	 */
+	private String merchantOrderNo;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/UniPayCallbackResult.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/UniPayCallbackResult.java
new file mode 100644
index 0000000..cc84369
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/UniPayCallbackResult.java
@@ -0,0 +1,93 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 11:00
+ */
+@Data
+public class UniPayCallbackResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 支付金额
+	 */
+	private Double r3_Amount;
+	/**
+	 * 交易币种
+	 */
+	private String r4_Cur;
+	/**
+	 * 公用回传参数
+	 */
+	private String r5_Mp;
+	/**
+	 * 支付状态
+	 * 100:支付成功;
+	 * 101:支付失败。
+	 */
+	private String r6_Status;
+	/**
+	 * 交易流水号
+	 */
+	private String r7_TrxNo;
+	/**
+	 * 银行订单号
+	 */
+	private String r8_BankOrderNo;
+	/**
+	 * 银行流水号
+	 */
+	private String r9_BankTrxNo;
+	/**
+	 * 支付时间
+	 */
+	private String ra_PayTime;
+	/**
+	 * 交易结果通知时间
+	 */
+	private String rb_DealTime;
+	/**
+	 * 银行编码
+	 */
+	private String rc_BankCode;
+	/**
+	 * 用户标识
+	 */
+	private String rd_OpenId;
+	/**
+	 * 平台优惠金额
+	 */
+	private Double re_DiscountAmount;
+	/**
+	 * 卡类型
+	 */
+	private String rh_cardType;
+	/**
+	 * 订单手续费
+	 */
+	private Double rj_Fee;
+	/**
+	 * 交易类型
+	 */
+	private String rk_FrpCode;
+	/**
+	 * 签约 ID
+	 */
+	private String rl_ContractId;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/UniPayResult.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/UniPayResult.java
new file mode 100644
index 0000000..a92ee3f
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/model/UniPayResult.java
@@ -0,0 +1,77 @@
+package com.ruoyi.other.util.payment.model;
+
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/12/30 10:47
+ */
+@Data
+public class UniPayResult {
+	/**
+	 * 版本号
+	 */
+	private Double r0_Version;
+	/**
+	 * 商户编号
+	 */
+	private String r1_MerchantNo;
+	/**
+	 * 商户订单号
+	 */
+	private String r2_OrderNo;
+	/**
+	 * 支付金额
+	 */
+	private Double r3_Amount;
+	/**
+	 * 币种
+	 */
+	private String r4_Cur;
+	/**
+	 * 公用回传参数
+	 */
+	private String r5_Mp;
+	/**
+	 * 交易类型
+	 */
+	private String r6_FrpCode;
+	/**
+	 * 交易流水号
+	 */
+	private String r7_TrxNo;
+	/**
+	 * 银行商户编码
+	 */
+	private String r8_MerchantBankCode;
+	/**
+	 * 响应码,返回 100 时表示成功
+	 */
+	private String ra_Code;
+	/**
+	 * 响应码描述
+	 */
+	private String rb_CodeMsg;
+	/**
+	 * 1.主扫支付返回二维码地址。
+	 * 2.支付宝 H5,mode1/2/3 参考请求参数q9_TransactionModel 说明。
+	 * 3.微信 H5_PLUS,获取支付信息的 openlink,通过手机端浏览器跳转并唤起微信 APP客户端,直接打开对应的小程序进行支付。
+	 * 3.公众号支付:需要商户参考微信的官方文档 JSAPI 支付接口进行处理,详情请见:https://pay.weixin.qq.com/wiki/doc/api/index.html
+	 * 4.微信小程序支付返回支付信息。
+	 * 5.支付宝收银台返回支付宝收银台跳转链接,通过请求该链接跳转至支付宝。
+	 * 6.微信 app3 支付,返回预支付信息,集成微信 SDK 唤起小程序进行支付。
+	 * 7.支付宝服务窗支付返回银联交易号 trade_no,可用以唤起支付宝 APP,调起支付宝APP 收银台。
+	 * 8.银联 app 或银联统一收银台支付,返回预支付信息用此网址的接口调起支付。https://open.unionpay.com/tjweb/acproduct/list?apiservId=450#nav02
+	 * 9.银联云微小程序返回跳转地址,格式:{“cqpMpAppId”:”云闪付小程序 id”,”cqpMpPath”:”云闪付小程序 path”}
+	 * 10.其他类型支付返回支付信息。
+	 */
+	private String rc_Result;
+	/**
+	 * 二维码图片码
+	 */
+	private String rd_Pic;
+	/**
+	 * 签名数据
+	 */
+	private String hmac;
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/SaveWithdrawalAccount.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/SaveWithdrawalAccount.java
new file mode 100644
index 0000000..a91eb6a
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/SaveWithdrawalAccount.java
@@ -0,0 +1,24 @@
+package com.ruoyi.other.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author zhibing.pu
+ * @Date 2025/1/1 11:54
+ */
+@Data
+public class SaveWithdrawalAccount {
+	
+	@ApiModelProperty("收款银行卡号")
+	private String receiverAccountNoEnc;
+	
+	@ApiModelProperty("收款银行卡持卡人名称")
+	private String receiverNameEnc;
+	
+	@ApiModelProperty("账户类型(对私账户201,对公账户204)")
+	private Integer receiverAccountType;
+	
+	@ApiModelProperty("收款账户联行号")
+	private String receiverBankChannelNo;
+}

--
Gitblit v1.7.1