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");
|
|
}
|
}
|