From f38d69d70e3e126d2f58971d0b4854f2aa144fc1 Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期五, 22 八月 2025 14:40:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/2.0' into 2.0
---
cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java | 458 +++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 378 insertions(+), 80 deletions(-)
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java b/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java
index fc97d88..fa7103f 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java
@@ -1,15 +1,14 @@
package com.dsh.competition.util;
import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
-import com.alipay.api.AlipayApiException;
-import com.alipay.api.AlipayClient;
-import com.alipay.api.CertAlipayRequest;
-import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.*;
import com.alipay.api.domain.*;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.dsh.competition.util.httpClinet.HttpClientUtil;
+import com.dsh.competition.util.wx.*;
import org.apache.commons.collections.map.HashedMap;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.dom4j.Document;
@@ -19,11 +18,9 @@
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
+import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
@@ -35,6 +32,8 @@
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.*;
+
+import static com.dsh.competition.util.akeylogin.Md5Util.byteArrayToHexString;
/**
* 第三方支付工具类
@@ -57,7 +56,7 @@
private String key = "6f5e0c2dcabfa9c27b5da5836a362fef";//微信商户号
- private String callbackPath = "http://221.182.45.100:56666/competition";//支付回调网关地址
+ private String callbackPath = "https://online.daowepark.com:443/competition";//支付回调网关地址
private String app_cert_path = "C:/cert/alipay/user/app_cert_path.crt";//应用公钥证书路径
@@ -65,65 +64,13 @@
private String alipay_root_cert_path = "C:/cert/alipay/user/alipay_root_cert_path.crt";//支付宝CA根证书文件路径
- private String certPath = "C:\\Users\\Admin\\Desktop\\weixin_cert\\apiclient_cert.p12";//微信证书
+ private String certPath = "/usr/playpai/cert/weixin/apiclient_cert.p12";//微信证书
/**
* 支付宝支付
*/
public ResultUtil alipay(String smid,String body, String subject, String passbackParams, String outTradeNo, String amount, String notifyUrl) {
-// //构造client
-// CertAlipayRequest certAlipayRequest = new CertAlipayRequest ();
-// //设置网关地址
-// certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
-// //设置应用Id
-// certAlipayRequest.setAppId(aliAppid);
-// //设置应用私钥
-// certAlipayRequest.setPrivateKey(appPrivateKey);
-// //设置请求格式,固定值json
-// certAlipayRequest.setFormat("json");
-// //设置字符集
-// certAlipayRequest.setCharset("UTF-8");
-// //设置签名类型
-// certAlipayRequest.setSignType("RSA2");
-// //设置应用公钥证书路径
-// certAlipayRequest.setCertPath(app_cert_path);
-// //设置支付宝公钥证书路径
-// certAlipayRequest.setAlipayPublicCertPath(alipay_cert_path);
-// //设置支付宝根证书路径
-// certAlipayRequest.setRootCertPath(alipay_root_cert_path);
-// //构造client
-// AlipayClient alipayClient = null;
-// try {
-// alipayClient = new DefaultAlipayClient(certAlipayRequest);
-// } catch (AlipayApiException e) {
-// e.printStackTrace();
-// }
-// //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
-// AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest ();
-// //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
-// AlipayTradeAppPayModel model = new AlipayTradeAppPayModel ();
-// model.setBody(body);
-// model.setSubject (subject);
-// model.setOutTradeNo (outTradeNo);
-// model.setTimeoutExpress ("30m" );
-// model.setTotalAmount (amount);
-// model.setProductCode ( "QUICK_MSECURITY_PAY" );
-// model.setPassbackParams(passbackParams);//自定义参数
-// request.setBizModel ( model );
-// request.setNotifyUrl (callbackPath + notifyUrl);
-// try {
-// //这里和普通的接口调用不同,使用的是sdkExecute
-// AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
-// Map<String, String> map = new HashMap<>();
-// map.put("orderString", response.getBody());
-// System.out.println(map);//就是orderString 可以直接给客户端请求,无需再做处理。
-// return ResultUtil.success(map);
-// } catch (AlipayApiException e ) {
-// e.printStackTrace();
-// }
-
-
//实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", aliAppid, appPrivateKey, "json", "UTF-8", alipay_public_key, "RSA2");
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
@@ -149,9 +96,10 @@
SubMerchant subMerchant = new SubMerchant();
subMerchant.setMerchantId(smid);
model.setSubMerchant(subMerchant);
- ExtendParams extendParams = new ExtendParams();
- extendParams.setRoyaltyFreeze("true");// 冻结资金 用于后续分账处理
- model.setExtendParams(extendParams);
+ ExtendParams extendParams = new ExtendParams();
+ extendParams.setRoyaltyFreeze("false");
+ model.setExtendParams(extendParams);
+
request.setBizModel(model);
request.setNotifyUrl(callbackPath + notifyUrl);
@@ -252,17 +200,23 @@
Map<String, String> map = new HashMap<>();
- String out_trade_no = params.get("out_trade_no");
- String subject = params.get("subject");
- String total_amount = params.get("total_amount");
- String trade_no = params.get("trade_no");
- String passback_params = params.get("passback_params");
- map.put("out_trade_no", out_trade_no);//商家订单号
- map.put("subject", subject);
- map.put("total_amount", total_amount);
- map.put("trade_no", trade_no);//支付宝交易号
- map.put("passback_params", passback_params);//回传参数
- return map;
+ System.err.println("返回码"+params);
+ if (params.get("trade_status").equals("TRADE_SUCCESS")){
+ String out_trade_no = params.get("out_trade_no");
+ String subject = params.get("subject");
+ String total_amount = params.get("total_amount");
+ String trade_no = params.get("trade_no");
+ String passback_params = params.get("passback_params");
+ map.put("out_trade_no", out_trade_no);//商家订单号
+ map.put("subject", subject);
+ map.put("total_amount", total_amount);
+ map.put("trade_no", trade_no);//支付宝交易号
+ map.put("passback_params", passback_params);//回传参数
+ System.err.println("回调map");
+ return map;
+ }else{
+ return null;
+ }
}
@@ -297,7 +251,69 @@
* @param amount
* @return
*/
- public ResultUtil confirm(String smid,String code, String outTradeNo, String amount) {
+ public ResultUtil confirm(String smid1,String code, String outTradeNo, String amount) throws AlipayApiException {
+ // 初始化SDK
+ AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
+
+ // 构造请求参数以调用接口
+ AlipayTradeSettleConfirmRequest request = new AlipayTradeSettleConfirmRequest();
+ AlipayTradeSettleConfirmModel model = new AlipayTradeSettleConfirmModel();
+
+ // 设置确认结算请求流水号
+ model.setOutRequestNo(code);
+
+ // 设置支付宝交易号
+ model.setTradeNo(outTradeNo);
+
+ // 设置描述结算信息
+ SettleInfo settleInfo = new SettleInfo();
+ List<SettleDetailInfo> settleDetailInfos = new ArrayList<SettleDetailInfo>();
+ SettleDetailInfo settleDetailInfos0 = new SettleDetailInfo();
+ settleDetailInfos0.setAmount(amount);
+ settleDetailInfos0.setTransIn(smid1);
+ settleDetailInfos0.setSettleEntityType("SecondMerchant");
+ settleDetailInfos0.setSettleEntityId(smid1);
+ settleDetailInfos0.setTransInType("defaultSettle");
+ settleDetailInfos.add(settleDetailInfos0);
+ settleInfo.setSettleDetailInfos(settleDetailInfos);
+ SettleConfirmExtendParams settleConfirmExtendParams = new SettleConfirmExtendParams();
+ settleConfirmExtendParams.setRoyaltyFreeze("false");
+ model.setExtendParams(settleConfirmExtendParams);
+ model.setSettleInfo(settleInfo);
+ request.setBizModel(model);
+ System.err.println("结算金额"+amount);
+ // 第三方代调用模式下请设置app_auth_token
+ // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
+
+ AlipayTradeSettleConfirmResponse response = alipayClient.execute(request);
+ System.out.println("返回体"+response.getBody());
+
+
+ if (response.isSuccess()) {
+ System.out.println("调用成功");
+ } else {
+ System.out.println("调用失败");
+ // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
+ // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
+ // System.out.println(diagnosisUrl);
+ }
+ return ResultUtil.success(response.getBody());
+ }
+ private static AlipayConfig getAlipayConfig() {
+ String privateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCi5i9nW/hGLJ3A06cZxTQdviFC7THpdSihoTYGLr9q006hu0V26ecBMY/o4w5bvIX0Ok/yofmZsVcCJpAPvbXL/uqVrIjnRRxXiaeBFThlxoBUTdunvbUSDYfzlEhJr5NvUKI6H6lz2niXlQGx4qy8Hau4ccWit9kM8jwUvsBVQoFgJA+xrjMvooA7YLopQtpOD+UJr5thApTSf1xrnr1W12yolTLEH15JmNV372cqXrYUuqnY0QsaPtxeqJUGAOcGdVLllQ7easEznP8DFBvDdHATcmp2SHNQDUEWN6MCVPbMgY06NQVqAXxqjTAYSVh+6TRu6bofPmpYC3TZB003AgMBAAECggEBAJAcR2+PA3NBYUYHeFrqBRMS8uX8ZR19kjZ7IgoSLTFaQsP9opRylPSPXhrPVBKAE5leRQAHn4MCSlESwHvMfxo7KFjFTFAc6dffZZpipYQUOc9bGampwJh58/3e/pyBgVMG6J23CPf/HJQtNFSkjd/V9+ayb/9l2dUEL3bC0fAZ/dbx8HsxdLw8wn3fLlWLj68hOMqa2deCZe3JdSVsPbeWqkh56FFsMLug0Nd+Ar4TgRl9/jnhXF0JWiD0LmPUYLhboY7EfUBzN4w1iYbDi1P+3zvoOYsiVKAXox9GMhQ2VzOO2UcSTuizSza2e98mGpabl/GpKmCz+RDFjtkX6eECgYEA2MyCij65eO3aGIm3FUe93DULRBYTfX8qJQSJq2WOWA3mmQlEW6L3O2B5/lG2h+8WmN6iLEs9eHpgycGYp7vAqgrANEn16ACVcuyx0scFtrZfZ+kmHMzFfiUWxJjVYk/6YngsGVBLdw6ueM42C8TTP67X9tU5TdVGoGWuqEj4W98CgYEAwFqwprXOch5Pqk/RPbb49r0Ou03K/UbciWnWWKzUhFFNS8MdlQPoDvQZbMwHLeWsa2VhaKITK3x5biLQb3U+0GLOn6lTvEyrEUH+ucREyLgVYTRAvwBPtnvlrzpyxPk2HnslQjju8WrvvLLBMKWUjlTrTOzhaHT21gz3pHMiOakCgYEAhLmfaXdBITGshb054sNLDtdCkGpbgEcrzAHdLps769iGxkYQHXHFngpQZUwtTUcoNGqIKknd1jZFrv7gsD+XkgKG7PwimehRlkwmCX5ilxtLiVgJRzRt6+5U5AMVD90a0tHzXYP0z2yjj73fBJF5KtGl0a10KZxaYrQdm1UhB00CgYBZZgzx/k9rtHC8LAqIj1CYhHejT92G53c6Gkl3vyOqN4sgKhfGmSEySfrDGPRBPZxr8ZtbIPCd5mUdberH0osWGMYFaJI1UsCy7aQwvGpniz7MhZeN7dweaOjwDs8mgtjHQ96mL4XGCDhR0BZ/wIURvZ/6iaGdhbbu9unlsWj3uQKBgQCmZYdsbbZkd3ev6f8rwyvMz+DrCQyYpY44cegBYuJgrZiQnL2fJioeN7ixX0UM48SfwsZEIrzshP/LGAwnc2MdjxKUl4jLN8SEe0NAjXOnz9Zaw740+aOmLpXcLWdP4uM2gIhWsvW1tEkQZCXmm7c9s/RsU8Pmzv+YL3+fSijOzA==";
+ String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmu8n/4yTHWbn7VOrNc9OsLtDL1bEQ8gC1dHkj8Wy5z0mkaOsjJRIG/28ze12M0V8jdCKuuDr5Z1OPKiqf+XO3ypguEh+mYUVMBM/cZodDFQfTY1TKLWjvQCuaqlA+QUTCK6f7T7stsgyQ1o9Jj0rXZDz6PM4QHSTzjrLIBaeqM5WIBvH+fy/X+QG5Utd+/UT0kc0JyvuKhZ65yVUd/C9VcwJJAPliRsAQNrqYterwAJ9zvw9tF11wj9W0XgJ8Ccu4x3gR1vrlLRJJo/OA97RmxPQ+5hSacWQZCUd1dwiBq+YCrKVHGTj14izRHXrLc0yBlRXo7tBOIqcy3IsvKVthQIDAQAB";
+ AlipayConfig alipayConfig = new AlipayConfig();
+ alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
+ alipayConfig.setAppId("2021004105665036");
+ alipayConfig.setPrivateKey(privateKey);
+ alipayConfig.setFormat("json");
+ alipayConfig.setAlipayPublicKey(alipayPublicKey);
+ alipayConfig.setCharset("UTF-8");
+ alipayConfig.setSignType("RSA2");
+ return alipayConfig;
+ }
+ // 属于平台的运营商 因为无需分账不冻结资金
+ public ResultUtil confirm1(String smid,String code, String outTradeNo, String amount) {
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
aliAppid,
appPrivateKey,
@@ -337,7 +353,6 @@
return ResultUtil.error("出现问题啦");
}
}
-
/**
* 微信统一下单
*
@@ -362,13 +377,18 @@
map.put("appid", appid);
map.put("mch_id", mchId);
map.put("nonce_str", nonce_str);
- map.put("body", body);
+
+ map.put("body", body);
+
+
+
map.put("attach", attach);//存储订单id
map.put("out_trade_no", out_trade_no);//存储的订单code
map.put("total_fee", i);
map.put("spbill_create_ip", hostAddress);
map.put("notify_url", callbackPath + notify_url);
map.put("trade_type", tradeType);
+
if ("JSAPI".equals(tradeType)) {
map.put("openid", openId);
}
@@ -452,7 +472,138 @@
return ResultUtil.error(map1.get("return_msg"), new JSONObject());
}
}
+ public ResultUtil weixinpayV3(String subMchid,String description, String outTradeNo, String notifyUrl, String totalFee) throws Exception {
+ int i = new BigDecimal(totalFee).multiply(new BigDecimal("100")).intValue();
+ // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/partner/4013080340
+ PartnerAppPrepay client = new PartnerAppPrepay(
+// "1681873607", // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考https://pay.weixin.qq.com/doc/v3/partner/4013080340
+// "55714944F7A7E52526F708280B176DCC838F371A", // 商户API证书序列号,如何获取请参考https://pay.weixin.qq.com/doc/v3/partner/4013058924
+// "E:\\wanpai\\1681873607_20250424_cert\\apiclient_key.pem", // 商户API证书私钥文件路径,本地文件路径
+// "PUB_KEY_ID_0116818736072025042400351694002605", // 微信支付公钥ID,如何获取请参考https://pay.weixin.qq.com/doc/v3/partner/4013038589
+// "E:\\wanpai\\pub_key.pem" // 微信支付公钥文件路径,本地文件路径
+ "1681873607", // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考https://pay.weixin.qq.com/doc/v3/partner/4013080340
+ "55714944F7A7E52526F708280B176DCC838F371A", // 商户API证书序列号,如何获取请参考https://pay.weixin.qq.com/doc/v3/partner/4013058924
+ "/usr/playpai/server/wxV3/1681873607_20250424_cert/apiclient_key.pem", // 商户API证书私钥文件路径,本地文件路径
+ "PUB_KEY_ID_0116818736072025042400351694002605", // 微信支付公钥ID,如何获取请参考https://pay.weixin.qq.com/doc/v3/partner/4013038589
+ "/usr/playpai/server/wxV3/pub_key.pem" // 微信支付公钥文件路径,本地文件路径
+ );
+
+ PartnerAppPrepay.PartnerAPIv3CommonPrepayRequest request = new PartnerAppPrepay.PartnerAPIv3CommonPrepayRequest();
+ request.spAppid = appid;// appid
+ request.spMchid = WxV3PayConfig.Mch_ID;// 服务商商户号
+ request.subMchid = subMchid;// 子商户号
+ request.description = description;// 描述
+ request.outTradeNo = outTradeNo;// 订单号
+ request.notifyUrl =callbackPath+ notifyUrl;// 回调地址
+ request.amount = new PartnerAppPrepay.CommonAmountInfo();
+ request.amount.total = (long) i;// 金额 单位分
+ request.amount.currency = "CNY";
+ String prepayId ="";
+ Map<String, Object> map3 = new HashMap<>();
+ try {
+ PartnerAppPrepay.PartnerAPIv3AppPrepayResponse response = client.run(request);
+ // TODO: 请求成功,继续业务逻辑
+ System.err.println("微信申请成功,预支付ID: " + response.prepayId);
+ prepayId = response.prepayId;
+ } catch (WXPayUtility.ApiException e) {
+ // TODO: 请求失败,根据状态码执行不同的逻辑
+ e.printStackTrace();
+ }
+ map3.put("appid", appid);
+ map3.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
+ String nonce_str = UUIDUtil.getRandomCode(16);
+ map3.put("noncestr", nonce_str);
+ map3.put("prepayid", prepayId);
+ // 构造待签名字符串
+ String message = WeChatV3SignUtil.buildSignMessage(map3);
+ // 私钥路径(pem 文件)
+ String privateKeyPath = "/usr/playpai/server/wxV3/1681873607_20250424_cert/apiclient_key.pem";
+// String privateKeyPath = "E:\\wanpai\\1681873607_20250424_cert\\apiclient_key.pem";
+ // 生成签名
+ String sign = WeChatV3SignUtil.signWithPrivateKey(message, privateKeyPath);
+ map3.put("sign", sign);
+ map3.put("package", "Sign=WXPay");
+ map3.put("partnerid", WxV3PayConfig.Mch_ID);// 服务商商户号
+ System.err.println(map3);
+ return ResultUtil.success(map3);
+ }
+
+ /**
+ * 发起分账
+ * @param order 微信订单号
+ * @return
+ */
+ public ResultUtil fenzhang(String order,BigDecimal amount,String merchantNumber,String nonceStr,String description) throws Exception {
+ Map<String, Object> map = new HashMap<>();
+ map.put("mch_id", mchId);
+ map.put("appid", appid);
+ map.put("nonce_str", nonceStr);
+ map.put("transaction_id", order);
+ String out_order_no = UUIDUtil.getRandomCode(16);
+ map.put("out_order_no", out_order_no);
+ // 将这个字符串使用json格式拼接起来
+ Map<String, Object> body = new HashMap<>();
+ // 将这个字符串使用json格式拼接起来
+ body.put("type", "MERCHANT_ID");
+ body.put("account", merchantNumber);
+ int i = amount.multiply(new BigDecimal("100")).intValue();
+ body.put("amount", i);
+ body.put("description", description);
+ JSONObject jsonObject = new JSONObject(body);
+ JSONArray objects = new JSONArray();
+ objects.add(jsonObject);
+ map.put("receivers",objects.toJSONString());
+ String s = this.weixinSignature1(map);
+ map.put("sign", s);
+ String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing";
+ //设置请求头
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_XML);
+ StringBuffer xmlString = new StringBuffer();
+ Set<String> strings = map.keySet();
+ String[] keys = {};
+ keys = strings.toArray(keys);
+ Arrays.sort(keys);
+ xmlString.append("<xml>");
+ for (int l = 0; l < keys.length; l++) {
+ xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">");
+ }
+ xmlString.append("</xml>");
+
+ Map<String, String> map1 = null;
+ String body1 = null;
+ try {
+ body1 = HttpClientUtil.pushHttpsRequsetXml1(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ System.err.println("分账请求"+body1);
+ //将结果xml解析成map
+ body1 = body1.replaceAll("<!\\[CDATA\\[", "");
+ body1 = body1.replaceAll("]]>", "");
+ try {
+ map1 = this.xmlToMap(body1, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ } catch (DocumentException e) {
+ e.printStackTrace();
+ }
+ String return_code = map1.get("return_code");
+ if ("SUCCESS".equals(return_code)) {
+ String result_code = map1.get("result_code");
+ if ("SUCCESS".equals(result_code)) {
+
+ return ResultUtil.success(map1.get("order_id"));
+ } else {
+// System.err.println(map1.get("err_code_des"));
+ return ResultUtil.error(map1.get("err_code_des"));
+ }
+ } else {
+// System.err.println(map1.get("return_msg") + appid + "----" + mchId);
+ return ResultUtil.error(map1.get("return_msg"), new JSONObject());
+ }
+ }
/**
* 微信支付成功后的回调处理
@@ -694,7 +845,107 @@
return map2;
}
}
+ public ResultUtil weixinRefundV3(String subMchid,String outRefundNo, String transactionId, String totalFee, String notifyUrl) throws Exception {
+ BigDecimal bigDecimal = new BigDecimal(totalFee);
+ int i = bigDecimal.multiply(new BigDecimal("100")).intValue();
+ // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/partner/4013080340
+ Create client = new Create(
+ "1681873607", // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/merchant/4013070756
+ "55714944F7A7E52526F708280B176DCC838F371A", // 商户API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/v3/merchant/4013053053
+ "/usr/playpai/server/wxV3/1681873607_20250424_cert/apiclient_key.pem", // 商户API证书私钥文件路径,本地文件路径
+ "PUB_KEY_ID_0116818736072025042400351694002605", // 微信支付公钥ID,如何获取请参考 https://pay.weixin.qq.com/doc/v3/merchant/4013038816
+ "/usr/playpai/server/wxV3/pub_key.pem" // 微信支付公钥文件路径,本地文件路径
+ );
+ Create.CreateRequest request = new Create.CreateRequest();
+ request.subMchid = subMchid;
+ request.transactionId = transactionId;
+ request.outRefundNo = outRefundNo;
+ request.reason = "退款";
+ request.notifyUrl = callbackPath+notifyUrl;
+ request.amount = new Create.AmountReq();
+ request.amount.refund = (long) i;
+ request.amount.total = (long) i;
+ request.amount.currency = "CNY";
+ try {
+ Create.Refund response = client.run(request);
+
+ // TODO: 请求成功,继续业务逻辑
+ System.out.println(response);
+ } catch (WXPayUtility.ApiException e) {
+ // TODO: 请求失败,根据状态码执行不同的逻辑
+ e.printStackTrace();
+ }
+ return ResultUtil.success();
+ }
+ /**
+ * 发起分账回退
+ * @param order 微信订单号
+ * @return
+ */
+ public ResultUtil fenzhangRefund(String order,BigDecimal amount,String merchantNumber,
+ String nonce_str,
+ String fenzhangRefundNo) throws Exception {
+ Map<String, Object> map = new HashMap<>();
+ map.put("mch_id", mchId);
+ map.put("appid", appid);
+ map.put("nonce_str", nonce_str);
+ map.put("order_id", order);
+ map.put("out_return_no", fenzhangRefundNo);
+ map.put("return_account_type", "MERCHANT_ID");
+ map.put("return_account", merchantNumber);
+ BigDecimal multiply = amount.multiply(new BigDecimal("100"));
+ map.put("return_amount", multiply.intValue());
+ map.put("description", "用户报名赛事退款");
+ String s = this.weixinSignature1(map);
+ map.put("sign", s);
+ String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharingreturn";
+ //设置请求头
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_XML);
+ StringBuffer xmlString = new StringBuffer();
+ Set<String> strings = map.keySet();
+ String[] keys = {};
+ keys = strings.toArray(keys);
+ Arrays.sort(keys);
+ xmlString.append("<xml>");
+ for (int l = 0; l < keys.length; l++) {
+ xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">");
+ }
+ xmlString.append("</xml>");
+
+ Map<String, String> map1 = null;
+ String body1 = null;
+ try {
+ body1 = HttpClientUtil.pushHttpsRequsetXml1(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ System.err.println("分账金额回退"+body1);
+ //将结果xml解析成map
+ body1 = body1.replaceAll("<!\\[CDATA\\[", "");
+ body1 = body1.replaceAll("]]>", "");
+ try {
+ map1 = this.xmlToMap(body1, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ } catch (DocumentException e) {
+ e.printStackTrace();
+ }
+ String return_code = map1.get("return_code");
+ if ("SUCCESS".equals(return_code)) {
+ String result_code = map1.get("result_code");
+ if ("SUCCESS".equals(result_code)) {
+ return ResultUtil.success(map1.get("return_no"));
+ } else {
+// System.err.println(map1.get("err_code_des"));
+ return ResultUtil.error(map1.get("err_code_des"));
+ }
+ } else {
+// System.err.println(map1.get("return_msg") + appid + "----" + mchId);
+ return ResultUtil.error(map1.get("return_msg"), new JSONObject());
+ }
+ }
/**
* 微信退款成功后的回调处理
@@ -1090,7 +1341,54 @@
return sb.toString();
}
-
+ private String weixinSignature1(Map<String, Object> map) {
+ try {
+ Set<Map.Entry<String, Object>> entries = map.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() != "") {
+ String key = item.getKey();
+ Object val = item.getValue();
+ if (!(val == "" || val == null)) {
+ sb.append(key + "=" + val + "&");
+ }
+ }
+ }
+ sb.append("key=" + key);
+ String sign = sha256_HMAC(sb.toString(), key).toUpperCase();
+ return sign;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ /**
+ * sha256_HMAC加密
+ * @param message 消息
+ * @param secret 秘钥
+ * @return 加密后字符串
+ */
+ public String sha256_HMAC(String message, String secret) {
+ String hash = "";
+ try {
+ Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
+ SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
+ sha256_HMAC.init(secret_key);
+ byte[] bytes = sha256_HMAC.doFinal(message.getBytes());
+ hash = byteArrayToHexString(bytes);
+ } catch (Exception e) {
+ System.out.println("Error HmacSHA256 ===========" + e.getMessage());
+ }
+ return hash;
+ }
/**
* 微信下单的签名算法
*
--
Gitblit v1.7.1