From a015e7c916474bb51b33c228f690aa17f30c746c Mon Sep 17 00:00:00 2001
From: Pu Zhibing <393733352@qq.com>
Date: 星期六, 04 一月 2025 09:32:31 +0800
Subject: [PATCH] 修改bug

---
 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/UserShop.java                            |   10 +
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/model/InitiateBatchTransfer.java |   40 ++++++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/PaymentUtil.java                        |   24 ++-
 ruoyi-service/ruoyi-order/pom.xml                                                                            |    7 +
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/TransferUtil.java                |  119 +++++++++++++++++++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/TransferUtil.java                   |   11 +
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ShoppingCartServiceImpl.java            |    1 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/PaymentUtil.java                        |   28 +++-
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/TransferUtil.java                       |    8 +
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/payment/TransferUtil.java                       |    9 +
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/MyShoppingCartVo.java                             |    2 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/WechatProperty.java              |   29 ++++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/payment/PaymentUtil.java                    |   24 ++-
 13 files changed, 287 insertions(+), 25 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/MyShoppingCartVo.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/MyShoppingCartVo.java
index 9f43321..922e250 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/MyShoppingCartVo.java
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/MyShoppingCartVo.java
@@ -35,6 +35,8 @@
 	private Boolean verifiable;
 	@ApiModelProperty("是否超出限购数量")
 	private Boolean purchaseLimit;
+	@ApiModelProperty("限购数量")
+	private Integer purchaseLimitNum;
 	@ApiModelProperty("现金支付")
 	private Boolean cashPayment;
 	@ApiModelProperty("积分支付")
diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/UserShop.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/UserShop.java
index bc8a12a..9a751e0 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/UserShop.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/UserShop.java
@@ -28,4 +28,14 @@
 	 */
 	@TableField("shop_id")
 	private Integer shopId;
+	/**
+	 * 角色类型(1=店长,2=店员)
+	 */
+	@TableField("role_type")
+	private Integer roleType;
+	/**
+	 * 角色id
+	 */
+	@TableField("role_id")
+	private Integer roleId;
 }
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
index 8069708..88ae4d1 100644
--- 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
@@ -1,5 +1,6 @@
 package com.ruoyi.account.util.payment;
 
+import cn.hutool.http.Header;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.HttpUtil;
@@ -49,6 +50,7 @@
 	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);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.5");
@@ -83,7 +85,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("支付接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("支付接口请求响应:" + execute.body());
@@ -104,6 +106,7 @@
 	public static QueryOrderResult queryOrder(String orderNo){
 		String url = "https://trade.joinpay.com/tradeRt/queryOrder";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.5");
@@ -118,7 +121,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("查询支付接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("查询支付接口请求响应:" + execute.body());
@@ -142,6 +145,7 @@
 	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);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.3");
@@ -162,7 +166,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("退款接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("退款接口请求响应:" + execute.body());
@@ -183,6 +187,7 @@
 	public static QueryRefundResult queryRefund(String refundOrderNo){
 		String url = "https://trade.joinpay.com/tradeRt/refund";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.3");
@@ -197,7 +202,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("退款接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("退款接口请求响应:" + execute.body());
@@ -218,6 +223,7 @@
 	public static CloseOrderResult closeOrder(String orderNo){
 		String url = "https://www.joinpay.com/trade/closeOrder.action";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("p1_MerchantNo", merchantNo);
@@ -232,7 +238,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("关闭订单接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("关闭订单接口请求响应:" + execute.body());
@@ -266,12 +272,16 @@
 			}
 		}
 		sb.append(key);
+		log.info("待签名串:{}", sb.toString());
 		return MD5AndKL.MD5(sb.toString());
 	}
 	
 	
 	public static void main(String[] args) {
-		UniPayResult uniPayResult = PaymentUtil.uniPay("123456", 0.01D, "测试商品", "这是用于对接支付测试的商品描述", "", "", "", "");
-		System.err.println(JSON.toJSONString(uniPayResult));
+//		UniPayResult uniPayResult = PaymentUtil.uniPay("852963742", 0.01D, "测试商品", "这是用于对接支付测试的商品描述",
+//				"", "/order/shopping-cart/shoppingCartPaymentCallback", "ooOrs64zHLuInkZ_GF0LpIN9_Rxc", "777168500885852");
+//		PaymentUtil.queryOrder("852963742");
+//		PaymentUtil.closeOrder("852963742");
+	
 	}
 }
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
index d503443..98c0408 100644
--- 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
@@ -1,5 +1,6 @@
 package com.ruoyi.account.util.payment;
 
+import cn.hutool.http.ContentType;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.HttpUtil;
@@ -46,6 +47,7 @@
 	public static SinglePayResult singlePay(SinglePay singlePay){
 		String url = "https://www.joinpay.com/payment/pay/singlePay";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.contentType(ContentType.JSON.toString());
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("userNo", merchantNo);
@@ -88,7 +90,7 @@
 		 */
 		body.put("paidUse", singlePay.getPaidUse());
 		//商户通知地址
-		body.put("callbackUrl", callbackUrl + singlePay.getCallbackUrl());
+		body.put("callbackUrl", singlePay.getCallbackUrl());
 		String sign = null;
 		try {
 			sign = sign(body);
@@ -128,6 +130,7 @@
 	public static SinglePayQueryResult singlePayQuery(String merchantOrderNo){
 		String url = "https://www.joinpay.com/payment/pay/singlePayQuery";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.contentType(ContentType.JSON.toString());
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("userNo", merchantNo);
@@ -171,6 +174,7 @@
 	public static AccountBalanceQueryResult accountBalanceQuery(){
 		String url = "https://www.joinpay.com/payment/pay/accountBalanceQuery";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.contentType(ContentType.JSON.toString());
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("userNo", merchantNo);
@@ -230,4 +234,9 @@
 		return MD5AndKL.MD5(sb.toString());
 	}
 	
+	
+	public static void main(String[] args) {
+		TransferUtil.accountBalanceQuery();
+	}
+	
 }
diff --git a/ruoyi-service/ruoyi-order/pom.xml b/ruoyi-service/ruoyi-order/pom.xml
index 52c2a8b..8f7a20b 100644
--- a/ruoyi-service/ruoyi-order/pom.xml
+++ b/ruoyi-service/ruoyi-order/pom.xml
@@ -156,6 +156,13 @@
             <artifactId>sdk</artifactId>
             <version>1.0.11</version>
         </dependency>
+    
+        <dependency>
+            <groupId>com.github.wechatpay-apiv3</groupId>
+            <artifactId>wechatpay-java</artifactId>
+            <version>0.2.15</version>
+        </dependency>
+        
     </dependencies>
 
     <build>
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 2debcc2..2802a73 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
@@ -522,6 +522,7 @@
 					sum = orderGoodList.stream().mapToInt(OrderGood::getNum).sum();
 				}
 				vo.setPurchaseLimit((num + sum) > goods.getPurchaseLimit());
+				vo.setPurchaseLimitNum(goods.getPurchaseLimit() - sum);
 			}
 			vo.setDistributionMode(goods.getDistributionMode());
 			vo.setEarnSpendingPoints(price.getEarnSpendingPoints());
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
index 6a6c88c..4914a27 100644
--- 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
@@ -1,12 +1,11 @@
 package com.ruoyi.order.util.payment;
 
-import cn.hutool.http.HttpRequest;
-import cn.hutool.http.HttpResponse;
-import cn.hutool.http.HttpUtil;
+import cn.hutool.http.*;
 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.*;
 
 /**
@@ -48,6 +47,7 @@
 	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);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.5");
@@ -82,7 +82,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("支付接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("支付接口请求响应:" + execute.body());
@@ -103,6 +103,7 @@
 	public static QueryOrderResult queryOrder(String orderNo){
 		String url = "https://trade.joinpay.com/tradeRt/queryOrder";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.5");
@@ -117,7 +118,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("查询支付接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("查询支付接口请求响应:" + execute.body());
@@ -141,6 +142,7 @@
 	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);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.3");
@@ -161,7 +163,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("退款接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("退款接口请求响应:" + execute.body());
@@ -182,6 +184,7 @@
 	public static QueryRefundResult queryRefund(String refundOrderNo){
 		String url = "https://trade.joinpay.com/tradeRt/refund";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.3");
@@ -196,7 +199,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("退款接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("退款接口请求响应:" + execute.body());
@@ -217,6 +220,7 @@
 	public static CloseOrderResult closeOrder(String orderNo){
 		String url = "https://www.joinpay.com/trade/closeOrder.action";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("p1_MerchantNo", merchantNo);
@@ -231,7 +235,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("关闭订单接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("关闭订单接口请求响应:" + execute.body());
@@ -265,12 +269,16 @@
 			}
 		}
 		sb.append(key);
+		log.info("待签名串:{}", sb.toString());
 		return MD5AndKL.MD5(sb.toString());
 	}
 	
 	
 	public static void main(String[] args) {
-		UniPayResult uniPayResult = PaymentUtil.uniPay("123456", 0.01D, "测试商品", "这是用于对接支付测试的商品描述", "", "", "", "");
-		System.err.println(JSON.toJSONString(uniPayResult));
+//		UniPayResult uniPayResult = PaymentUtil.uniPay("852963742", 0.01D, "测试商品", "这是用于对接支付测试的商品描述",
+//				"", "/order/shopping-cart/shoppingCartPaymentCallback", "ooOrs64zHLuInkZ_GF0LpIN9_Rxc", "777168500885852");
+//		PaymentUtil.queryOrder("852963742");
+//		PaymentUtil.closeOrder("852963742");
+		
 	}
 }
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
index c60dbc8..8caadab 100644
--- 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
@@ -1,5 +1,6 @@
 package com.ruoyi.order.util.payment;
 
+import cn.hutool.http.ContentType;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.HttpUtil;
@@ -39,6 +40,7 @@
 	public static SinglePayResult singlePay(SinglePay singlePay){
 		String url = "https://www.joinpay.com/payment/pay/singlePay";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.contentType(ContentType.JSON.toString());
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("userNo", merchantNo);
@@ -121,6 +123,7 @@
 	public static SinglePayQueryResult singlePayQuery(String merchantOrderNo){
 		String url = "https://www.joinpay.com/payment/pay/singlePayQuery";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.contentType(ContentType.JSON.toString());
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("userNo", merchantNo);
@@ -164,6 +167,7 @@
 	public static AccountBalanceQueryResult accountBalanceQuery(){
 		String url = "https://www.joinpay.com/payment/pay/accountBalanceQuery";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.contentType(ContentType.JSON.toString());
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("userNo", merchantNo);
@@ -223,4 +227,8 @@
 		return MD5AndKL.MD5(sb.toString());
 	}
 	
+	
+	public static void main(String[] args) {
+		com.ruoyi.order.util.payment.wechat.TransferUtil.accountBalanceQuery();
+	}
 }
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/TransferUtil.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/TransferUtil.java
new file mode 100644
index 0000000..638f46a
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/TransferUtil.java
@@ -0,0 +1,119 @@
+package com.ruoyi.order.util.payment.wechat;
+
+import com.wechat.pay.java.core.Config;
+import com.wechat.pay.java.core.RSAAutoCertificateConfig;
+import com.wechat.pay.java.service.transferbatch.TransferBatchService;
+import com.wechat.pay.java.service.transferbatch.model.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 微信支付工具类
+ * @author zhibing.pu
+ * @Date 2025/1/3 11:25
+ */
+public class TransferUtil {
+	
+	
+	
+	public static TransferBatchService service;
+	
+	
+	/**
+	 * 初始化转账服务
+	 */
+	public static void init(){
+		// 初始化商户配置
+		Config config = new RSAAutoCertificateConfig.Builder()
+						.merchantId(WechatProperty.merchantId)
+						// 使用 com.wechat.pay.java.core.util
+						// 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
+						.privateKeyFromPath(WechatProperty.privateKeyPath)
+						.merchantSerialNumber(WechatProperty.merchantSerialNumber)
+						.apiV3Key(WechatProperty.apiV3Key)
+						.build();
+		
+		// 初始化服务
+		service = new TransferBatchService.Builder().config(config).build();
+	}
+	
+	
+	/**
+	 * 通过微信批次单号查询批次单
+	 * @return
+	 */
+	public static TransferBatchEntity getTransferBatchByNo() {
+		if(null == service){
+			init();
+		}
+		GetTransferBatchByNoRequest request = new GetTransferBatchByNoRequest();
+		
+		return service.getTransferBatchByNo(request);
+	}
+	
+	/** 通过商家批次单号查询批次单 */
+	public static TransferBatchEntity getTransferBatchByOutNo() {
+		GetTransferBatchByOutNoRequest request = new GetTransferBatchByOutNoRequest();
+		return service.getTransferBatchByOutNo(request);
+	}
+	
+	/**
+	 * 发起商家转账
+	 * @param outBatchNo
+	 * @param batchName
+	 * @param batchRemark
+	 * @param totalAmount
+	 * @param totalNum
+	 * @param notifyUrl
+	 * @param out_detail_no
+	 * @param transfer_amount
+	 * @param transferRemark
+	 * @param openid
+	 * @return
+	 */
+	public static InitiateBatchTransferResponse initiateBatchTransfer(String outBatchNo, String batchName, String batchRemark, Long totalAmount,
+	                                                                  Integer totalNum, String notifyUrl, String out_detail_no, Long transfer_amount,
+	                                                                  String transferRemark, String openid) {
+		InitiateBatchTransferRequest request = new InitiateBatchTransferRequest();
+		request.setAppid(WechatProperty.appid);
+		request.setOutBatchNo(outBatchNo);
+		request.setBatchName(batchName);
+		request.setBatchRemark(batchRemark);
+		request.setTotalAmount(totalAmount);
+		request.setTotalNum(totalNum);
+		
+		List<TransferDetailInput> transferDetailList = new ArrayList<>();
+		TransferDetailInput transferDetailInput = new TransferDetailInput();
+		transferDetailInput.setOutDetailNo(out_detail_no);
+		transferDetailInput.setTransferAmount(transfer_amount);
+		transferDetailInput.setTransferRemark(transferRemark);
+		transferDetailInput.setOpenid(openid);
+		transferDetailList.add(transferDetailInput);
+		request.setTransferDetailList(transferDetailList);
+		request.setNotifyUrl(notifyUrl);
+		return service.initiateBatchTransfer(request);
+	}
+	
+	/**
+	 * 通过微信明细单号查询明细单
+	 * @return
+	 */
+	public static TransferDetailEntity getTransferDetailByNo() {
+		GetTransferDetailByNoRequest request = new GetTransferDetailByNoRequest();
+		return service.getTransferDetailByNo(request);
+	}
+	
+	/**
+	 * 通过商家明细单号查询明细单
+	 * @return
+	 */
+	public static TransferDetailEntity getTransferDetailByOutNo() {
+		GetTransferDetailByOutNoRequest request = new GetTransferDetailByOutNoRequest();
+		return service.getTransferDetailByOutNo(request);
+	}
+	
+	
+	
+	
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/WechatProperty.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/WechatProperty.java
new file mode 100644
index 0000000..85e654f
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/WechatProperty.java
@@ -0,0 +1,29 @@
+package com.ruoyi.order.util.payment.wechat;
+
+/**
+ * @author zhibing.pu
+ * @Date 2025/1/3 14:26
+ */
+public interface WechatProperty {
+	
+	/** 商户号 */
+	String merchantId = "1703304170";
+	
+	/** 商户API私钥路径 */
+	String privateKeyPath = "/Users/yourname/your/path/apiclient_key.pem";
+	
+	/** 商户证书序列号 */
+	String merchantSerialNumber = "42779097B2477E9996D3B2A4F237F663FD33B9DB";
+	
+	/** 商户APIV2密钥 */
+	String apiV2Key = "YGdzX23JseBf45JPfQtXNQSBHjSaJwrc";
+	
+	/** 商户APIV3密钥 */
+	String apiV3Key = "yaNFEA3mA5FPGr9DDWM4dP3F0RpkF0yt";
+	/**
+	 * appid
+	 */
+	String appid = "";
+	
+	
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/model/InitiateBatchTransfer.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/model/InitiateBatchTransfer.java
new file mode 100644
index 0000000..0259e31
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/payment/wechat/model/InitiateBatchTransfer.java
@@ -0,0 +1,40 @@
+package com.ruoyi.order.util.payment.wechat.model;
+
+import com.google.gson.annotations.SerializedName;
+import com.wechat.pay.java.core.cipher.Encryption;
+import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author zhibing.pu
+ * @Date 2025/1/3 16:27
+ */
+@Data
+public class InitiateBatchTransfer {
+	/**
+	 * 申请商户号的appid或商户号绑定的appid
+	 */
+	private String appid;
+	/**
+	 * 商户系统内部的商家批次单号
+	 */
+	private String outBatchNo;
+	@SerializedName("batch_name")
+	private String batchName;
+	@SerializedName("batch_remark")
+	private String batchRemark;
+	@SerializedName("total_amount")
+	private Long totalAmount;
+	@SerializedName("total_num")
+	private Integer totalNum;
+	@Encryption
+	@SerializedName("transfer_detail_list")
+	private List<TransferDetailInput> transferDetailList = new ArrayList();
+	@SerializedName("transfer_scene_id")
+	private String transferSceneId;
+	@SerializedName("notify_url")
+	private String notifyUrl;
+}
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
index d37bc30..b7d8486 100644
--- 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
@@ -1,5 +1,6 @@
 package com.ruoyi.other.util.payment;
 
+import cn.hutool.http.Header;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.HttpUtil;
@@ -49,6 +50,7 @@
 	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);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.5");
@@ -83,7 +85,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("支付接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("支付接口请求响应:" + execute.body());
@@ -104,6 +106,7 @@
 	public static QueryOrderResult queryOrder(String orderNo){
 		String url = "https://trade.joinpay.com/tradeRt/queryOrder";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.5");
@@ -118,7 +121,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("查询支付接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("查询支付接口请求响应:" + execute.body());
@@ -142,6 +145,7 @@
 	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);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.3");
@@ -162,7 +166,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("退款接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("退款接口请求响应:" + execute.body());
@@ -183,6 +187,7 @@
 	public static QueryRefundResult queryRefund(String refundOrderNo){
 		String url = "https://trade.joinpay.com/tradeRt/refund";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//版本号
 		body.put("p0_Version", "2.3");
@@ -197,7 +202,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("退款接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("退款接口请求响应:" + execute.body());
@@ -218,6 +223,7 @@
 	public static CloseOrderResult closeOrder(String orderNo){
 		String url = "https://www.joinpay.com/trade/closeOrder.action";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("p1_MerchantNo", merchantNo);
@@ -232,7 +238,7 @@
 			throw new RuntimeException(e);
 		}
 		body.put("hmac", sign);
-		post.body(body.toString());
+		post.form(body);
 		log.info("关闭订单接口请求参数:" + body);
 		HttpResponse execute = post.execute();
 		log.info("关闭订单接口请求响应:" + execute.body());
@@ -266,12 +272,16 @@
 			}
 		}
 		sb.append(key);
+		log.info("待签名串:{}", sb.toString());
 		return MD5AndKL.MD5(sb.toString());
 	}
 	
 	
 	public static void main(String[] args) {
-		UniPayResult uniPayResult = PaymentUtil.uniPay("123456", 0.01D, "测试商品", "这是用于对接支付测试的商品描述", "", "", "", "");
-		System.err.println(JSON.toJSONString(uniPayResult));
+//		UniPayResult uniPayResult = PaymentUtil.uniPay("852963742", 0.01D, "测试商品", "这是用于对接支付测试的商品描述",
+//				"", "/order/shopping-cart/shoppingCartPaymentCallback", "ooOrs64zHLuInkZ_GF0LpIN9_Rxc", "777168500885852");
+//		PaymentUtil.queryOrder("852963742");
+//		PaymentUtil.closeOrder("852963742");
+	
 	}
 }
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
index f8d6139..6718780 100644
--- 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
@@ -1,5 +1,6 @@
 package com.ruoyi.other.util.payment;
 
+import cn.hutool.http.ContentType;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.HttpUtil;
@@ -42,6 +43,7 @@
 	public static SinglePayResult singlePay(SinglePay singlePay){
 		String url = "https://www.joinpay.com/payment/pay/singlePay";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.contentType(ContentType.JSON.toString());
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("userNo", merchantNo);
@@ -124,6 +126,7 @@
 	public static SinglePayQueryResult singlePayQuery(String merchantOrderNo){
 		String url = "https://www.joinpay.com/payment/pay/singlePayQuery";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.contentType(ContentType.JSON.toString());
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("userNo", merchantNo);
@@ -167,6 +170,7 @@
 	public static AccountBalanceQueryResult accountBalanceQuery(){
 		String url = "https://www.joinpay.com/payment/pay/accountBalanceQuery";
 		HttpRequest post = HttpUtil.createPost(url);
+		post.contentType(ContentType.JSON.toString());
 		JSONObject body = new JSONObject();
 		//商户编号
 		body.put("userNo", merchantNo);
@@ -226,4 +230,9 @@
 		return MD5AndKL.MD5(sb.toString());
 	}
 	
+	
+	public static void main(String[] args) {
+		TransferUtil.accountBalanceQuery();
+	}
+	
 }

--
Gitblit v1.7.1