From 5d7b65670282a4fad015e37d567cfa171b162052 Mon Sep 17 00:00:00 2001
From: huliguo <2023611923@qq.com>
Date: 星期二, 20 五月 2025 12:25:19 +0800
Subject: [PATCH] 基础代码

---
 pt-errand/src/main/java/com/ruoyi/errand/utils/PaymentUtil.java |  285 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 285 insertions(+), 0 deletions(-)

diff --git a/pt-errand/src/main/java/com/ruoyi/errand/utils/PaymentUtil.java b/pt-errand/src/main/java/com/ruoyi/errand/utils/PaymentUtil.java
new file mode 100644
index 0000000..46bbf3a
--- /dev/null
+++ b/pt-errand/src/main/java/com/ruoyi/errand/utils/PaymentUtil.java
@@ -0,0 +1,285 @@
+package com.ruoyi.errand.utils;
+
+import cn.hutool.http.*;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+
+
+import com.ruoyi.common.utils.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.*;
+
+@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 sysTradeMerchantNo = "777168500885852";
+	/**
+	 * 支付回调地址
+	 */
+	private static final String callbackUrl = "https://www.qijisheng.top";
+	
+	
+	/**
+	 * 支付
+	 * @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);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
+		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", StringUtils.isNotEmpty(tradeMerchantNo) ? tradeMerchantNo : sysTradeMerchantNo);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.form(body);
+		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);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
+		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.form(body);
+		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);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
+		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", callbackUrl + notifyUrl);
+		String sign = null;
+		try {
+			sign = sign(body);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		body.put("hmac", sign);
+		post.form(body);
+		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);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
+		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.form(body);
+		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);
+		post.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded");
+		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.form(body);
+		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) {
+		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()).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);
+		log.info("待签名串:{}", sb.toString());
+		return MD5AndKL.MD5(sb.toString());
+	}
+	
+	
+	public static void main(String[] args) {
+//		UniPayResult uniPayResult = PaymentUtil.uniPay("852963742", 0.01D, "测试商品", "这是用于对接支付测试的商品描述",
+//				"", "/order/shopping-cart/shoppingCartPaymentCallback", "ooOrs64zHLuInkZ_GF0LpIN9_Rxc", "777168500885852");
+//		PaymentUtil.queryOrder("852963742");
+//		PaymentUtil.closeOrder("852963742");
+		
+	}
+}

--
Gitblit v1.7.1