优化微信V3支付

This commit is contained in:
zhuxiao 2022-03-02 09:49:15 +08:00
parent ac6e491ef6
commit 676e0d0f8a
9 changed files with 25 additions and 176 deletions

View File

@ -92,7 +92,7 @@ public class WxpayPayOrderCloseService implements IPayOrderCloseService {
reqJson.put("mchid", wxServiceWrapper.getWxPayService().getConfig().getMchId());
}
WxpayV3Util.closeOrderV3(reqUrl, reqJson, wxServiceWrapper.getWxPayService().getConfig());
WxpayV3Util.closeOrderV3(reqUrl, reqJson, wxServiceWrapper.getWxPayService());
return ChannelRetMsg.confirmSuccess(null);
}
return ChannelRetMsg.confirmFail();

View File

@ -94,7 +94,7 @@ public class WxpayPayOrderQueryService implements IPayOrderQueryService {
reqUrl = String.format("/v3/pay/transactions/out-trade-no/%s", payOrder.getPayOrderId());
query = String.format("?mchid=%s", wxServiceWrapper.getWxPayService().getConfig().getMchId());
}
JSONObject resultJSON = WxpayV3Util.queryOrderV3(reqUrl + query, wxServiceWrapper.getWxPayService().getConfig());
JSONObject resultJSON = WxpayV3Util.queryOrderV3(reqUrl + query, wxServiceWrapper.getWxPayService());
String channelState = resultJSON.getString("trade_state");
if ("SUCCESS".equals(channelState)) {

View File

@ -25,9 +25,7 @@ import com.github.binarywang.wxpay.service.WxPayService;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.entity.RefundOrder;
import com.jeequan.jeepay.core.model.params.wxpay.WxpayIsvParams;
import com.jeequan.jeepay.core.model.params.wxpay.WxpayIsvsubMchParams;
import com.jeequan.jeepay.core.model.params.wxpay.WxpayNormalMchParams;
import com.jeequan.jeepay.pay.channel.AbstractRefundService;
import com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit;
import com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayV3Util;
@ -81,7 +79,6 @@ public class WxpayRefundService extends AbstractRefundService {
req.setRefundFee(refundOrder.getRefundAmount().intValue()); // 退款金额
req.setNotifyUrl(getNotifyUrl(refundOrder.getRefundOrderId())); // 回调url
WxPayService wxPayService = wxServiceWrapper.getWxPayService();
setCretPath(mchAppConfigContext, wxPayService); // 证书路径
WxPayRefundResult result = wxPayService.refundV2(req);
if("SUCCESS".equals(result.getResultCode())){ // 退款发起成功,结果主动查询
@ -104,15 +101,13 @@ public class WxpayRefundService extends AbstractRefundService {
amountJson.put("total", payOrder.getAmount());// 订单总金额
amountJson.put("currency", "CNY");// 币种
reqJSON.put("amount", amountJson);
WxPayService wxPayService = wxServiceWrapper.getWxPayService();
setCretPath(mchAppConfigContext, wxPayService); // 证书路径
if(mchAppConfigContext.isIsvsubMch()){ // 特约商户
WxpayIsvsubMchParams isvsubMchParams = (WxpayIsvsubMchParams)configContextQueryService.queryIsvsubMchParams(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId(), getIfCode());
reqJSON.put("sub_mchid", isvsubMchParams.getSubMchId());
}
JSONObject resultJSON = WxpayV3Util.refundV3(reqJSON, wxServiceWrapper.getWxPayService().getConfig());
JSONObject resultJSON = WxpayV3Util.refundV3(reqJSON, wxServiceWrapper.getWxPayService());
String status = resultJSON.getString("status");
if("SUCCESS".equals(status)){ // 退款成功
String refundId = resultJSON.getString("refund_id");
@ -159,7 +154,6 @@ public class WxpayRefundService extends AbstractRefundService {
req.setOutRefundNo(refundOrder.getRefundOrderId()); // 退款单号
WxPayService wxPayService = wxServiceWrapper.getWxPayService();
setCretPath(mchAppConfigContext, wxPayService); // 证书路径
WxPayRefundQueryResult result = wxPayService.refundQueryV2(req);
if("SUCCESS".equals(result.getResultCode())){ // 退款成功
@ -171,14 +165,13 @@ public class WxpayRefundService extends AbstractRefundService {
}else if (CS.PAY_IF_VERSION.WX_V3.equals(wxServiceWrapper.getApiVersion())) { //V3
WxPayService wxPayService = wxServiceWrapper.getWxPayService();
setCretPath(mchAppConfigContext, wxPayService); // 证书路径
JSONObject resultJSON = null;
if (mchAppConfigContext.isIsvsubMch()) {
WxpayIsvsubMchParams isvsubMchParams = (WxpayIsvsubMchParams)configContextQueryService.queryIsvsubMchParams(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId(), getIfCode());
wxPayService.getConfig().setSubMchId(isvsubMchParams.getSubMchId());
resultJSON = WxpayV3Util.refundQueryV3Isv(refundOrder.getRefundOrderId(), wxPayService.getConfig());
resultJSON = WxpayV3Util.refundQueryV3Isv(refundOrder.getRefundOrderId(), wxPayService);
}else {
resultJSON = WxpayV3Util.refundQueryV3(refundOrder.getRefundOrderId(), wxPayService.getConfig());
resultJSON = WxpayV3Util.refundQueryV3(refundOrder.getRefundOrderId(), wxPayService);
}
String status = resultJSON.getString("status");
if("SUCCESS".equals(status)){ // 退款成功
@ -198,16 +191,4 @@ public class WxpayRefundService extends AbstractRefundService {
}
}
private void setCretPath(MchAppConfigContext mchAppConfigContext, WxPayService wxPayService) {
if(mchAppConfigContext.isIsvsubMch()){
// 获取服务商配置信息
WxpayIsvParams wxpayIsvParams = (WxpayIsvParams)configContextQueryService.queryIsvParams(mchAppConfigContext.getMchInfo().getIsvNo(), CS.IF_CODE.WXPAY);
wxPayService.getConfig().setKeyPath(channelCertConfigKitBean.getCertFilePath(wxpayIsvParams.getCert()));
}else{
// 获取商户配置信息
WxpayNormalMchParams normalMchParams = (WxpayNormalMchParams)configContextQueryService.queryNormalMchParams(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId(), CS.IF_CODE.WXPAY);
wxPayService.getConfig().setKeyPath(channelCertConfigKitBean.getCertFilePath(normalMchParams.getCert()));
}
}
}

View File

@ -21,30 +21,13 @@ import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.v3.WxPayV3HttpClientBuilder;
import com.github.binarywang.wxpay.v3.auth.AutoUpdateCertificatesVerifier;
import com.github.binarywang.wxpay.v3.auth.PrivateKeySigner;
import com.github.binarywang.wxpay.v3.auth.WxPayCredentials;
import com.github.binarywang.wxpay.v3.auth.WxPayValidator;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.util.PemUtils;
import com.github.binarywang.wxpay.v3.util.SignUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.HashMap;
import java.util.Map;
@ -73,154 +56,39 @@ public class WxpayV3Util {
ISV_URL_MAP.put(WxPayConstants.TradeType.MWEB, "/v3/pay/partner/transactions/h5");
}
public static JSONObject unifiedOrderV3(String reqUrl, JSONObject reqJSON, WxPayConfig wxPayConfig) throws WxPayException {
String response = postV3(PAY_BASE_URL + reqUrl, reqJSON.toJSONString(), wxPayConfig);
return JSONObject.parseObject(getPayInfo(response, wxPayConfig));
public static JSONObject unifiedOrderV3(String reqUrl, JSONObject reqJSON, WxPayService wxPayService) throws WxPayException {
String response = wxPayService.postV3(PAY_BASE_URL + reqUrl, reqJSON.toJSONString());
return JSONObject.parseObject(getPayInfo(response, wxPayService.getConfig()));
}
public static JSONObject queryOrderV3(String url, WxPayConfig wxPayConfig) throws WxPayException {
String response = getV3(PAY_BASE_URL + url, wxPayConfig);
public static JSONObject queryOrderV3(String url, WxPayService wxPayService) throws WxPayException {
String response = wxPayService.getV3(PAY_BASE_URL + url);
return JSON.parseObject(response);
}
public static JSONObject closeOrderV3(String url, JSONObject reqJSON, WxPayConfig wxPayConfig) throws WxPayException {
String response = postV3(PAY_BASE_URL + url, reqJSON.toJSONString(), wxPayConfig);
public static JSONObject closeOrderV3(String url, JSONObject reqJSON, WxPayService wxPayService) throws WxPayException {
String response = wxPayService.postV3(PAY_BASE_URL + url, reqJSON.toJSONString());
return JSON.parseObject(response);
}
public static JSONObject refundV3(JSONObject reqJSON, WxPayConfig wxPayConfig) throws WxPayException {
public static JSONObject refundV3(JSONObject reqJSON, WxPayService wxPayService) throws WxPayException {
String url = String.format("%s/v3/refund/domestic/refunds", PAY_BASE_URL);
String response = postV3(url, reqJSON.toJSONString(), wxPayConfig);
String response = wxPayService.postV3(url, reqJSON.toJSONString());
return JSON.parseObject(response);
}
public static JSONObject refundQueryV3(String refundOrderId, WxPayConfig wxPayConfig) throws WxPayException {
public static JSONObject refundQueryV3(String refundOrderId, WxPayService wxPayService) throws WxPayException {
String url = String.format("%s/v3/refund/domestic/refunds/%s", PAY_BASE_URL, refundOrderId);
String response = getV3(url, wxPayConfig);
String response = wxPayService.getV3(url);
return JSON.parseObject(response);
}
public static JSONObject refundQueryV3Isv(String refundOrderId, WxPayConfig wxPayConfig) throws WxPayException {
String url = String.format("%s/v3/refund/domestic/refunds/%s?sub_mchid=%s", PAY_BASE_URL, refundOrderId, wxPayConfig.getSubMchId());
String response = getV3(url, wxPayConfig);
public static JSONObject refundQueryV3Isv(String refundOrderId, WxPayService wxPayService) throws WxPayException {
String url = String.format("%s/v3/refund/domestic/refunds/%s?sub_mchid=%s", PAY_BASE_URL, refundOrderId, wxPayService.getConfig().getSubMchId());
String response = wxPayService.getV3(url);
return JSON.parseObject(response);
}
public static String postV3(String url, String requestStr, WxPayConfig wxPayConfig) throws WxPayException {
CloseableHttpClient httpClient = createApiV3HttpClient(wxPayConfig);
HttpPost httpPost = createHttpPost(url, requestStr);
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-Type", "application/json");
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
//v3已经改为通过状态码判断200 204 成功
int statusCode = response.getStatusLine().getStatusCode();
//post方法有可能会没有返回值的情况
String responseString;
if (response.getEntity() == null) {
responseString = null;
} else {
responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
}
log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据】{}", url, requestStr, responseString);
if (HttpStatus.SC_OK == statusCode || HttpStatus.SC_NO_CONTENT == statusCode) {
return responseString;
} else {
//有错误提示信息返回
JSONObject jsonObject = JSON.parseObject(responseString);
WxPayException wxPayException = new WxPayException(jsonObject.getString("message"));
wxPayException.setErrCode(jsonObject.getString("code"));
wxPayException.setErrCodeDes(jsonObject.getString("message"));
throw wxPayException;
}
} catch (Exception e) {
log.error("\n【异常信息】{}", e.getMessage());
throw (e instanceof WxPayException) ? (WxPayException) e : new WxPayException(e.getMessage(), e);
} finally {
httpPost.releaseConnection();
}
}
public static String getV3(String url, WxPayConfig wxPayConfig) throws WxPayException {
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader("Accept", "application/json");
httpGet.addHeader("Content-Type", "application/json");
httpGet.setConfig(RequestConfig.custom()
.setConnectionRequestTimeout(5000)
.setConnectTimeout(5000)
.setSocketTimeout(10000)
.build());
CloseableHttpClient httpClient = createApiV3HttpClient(wxPayConfig);
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
//v3已经改为通过状态码判断200 204 成功
int statusCode = response.getStatusLine().getStatusCode();
//post方法有可能会没有返回值的情况
String responseString;
if (response.getEntity() == null) {
responseString = null;
} else {
responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
}
if (HttpStatus.SC_OK == statusCode || HttpStatus.SC_NO_CONTENT == statusCode) {
log.info("\n【请求地址】{}\n【响应数据】{}", url, responseString);
return responseString;
} else {
//有错误提示信息返回
JSONObject jsonObject = JSON.parseObject(responseString);
WxPayException wxPayException = new WxPayException(jsonObject.getString("message"));
wxPayException.setErrCode(jsonObject.getString("code"));
wxPayException.setErrCodeDes(jsonObject.getString("message"));
throw wxPayException;
}
} catch (Exception e) {
log.error("\n【异常信息】{}e={}", url, e.getMessage());
throw (e instanceof WxPayException) ? (WxPayException) e : new WxPayException(e.getMessage(), e);
} finally {
httpGet.releaseConnection();
}
}
private static CloseableHttpClient createApiV3HttpClient(WxPayConfig wxPayConfig) throws WxPayException {
try {
// 自动获取微信平台证书
PrivateKey privateKey = PemUtils.loadPrivateKey(new FileInputStream(wxPayConfig.getPrivateKeyPath()));
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WxPayCredentials(wxPayConfig.getMchId(), new PrivateKeySigner(wxPayConfig.getCertSerialNo(), privateKey)),
wxPayConfig.getApiV3Key().getBytes("utf-8"));
WxPayV3HttpClientBuilder builder = WxPayV3HttpClientBuilder.create()
.withMerchant(wxPayConfig.getMchId(), wxPayConfig.getCertSerialNo(), privateKey)
.withValidator(new WxPayValidator(verifier));
CloseableHttpClient apiV3HttpClient = builder.build();
return apiV3HttpClient;
} catch (FileNotFoundException | UnsupportedEncodingException e) {
log.error("", e);
}
CloseableHttpClient apiV3HttpClient = wxPayConfig.getApiV3HttpClient();
if (null == apiV3HttpClient) {
return wxPayConfig.initApiV3HttpClient();
}
return null;
}
private static HttpPost createHttpPost(String url, String requestStr) {
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(requestStr, ContentType.create("application/json", "utf-8")));
httpPost.setConfig(RequestConfig.custom()
.setConnectionRequestTimeout(5000)
.setConnectTimeout(5000)
.setSocketTimeout(10000)
.build());
return httpPost;
}
public static String getPayInfo(String response, WxPayConfig wxPayConfig) throws WxPayException {

View File

@ -82,7 +82,7 @@ public class WxApp extends WxpayPaymentService {
// 1. 如果抛异常则订单状态为 生成状态此时没有查单处理操作 订单将超时关闭
// 2. 接口调用成功 后续异常需进行捕捉 如果 逻辑代码出现异常则需要走完正常流程此时订单状态为 支付中 需要查单处理
try {
JSONObject resJSON = WxpayV3Util.unifiedOrderV3(reqUrl, reqJSON, wxPayService.getConfig());
JSONObject resJSON = WxpayV3Util.unifiedOrderV3(reqUrl, reqJSON, wxPayService);
res.setPayInfo(resJSON.toJSONString());

View File

@ -86,7 +86,7 @@ public class WxH5 extends WxpayPaymentService {
// 1. 如果抛异常则订单状态为 生成状态此时没有查单处理操作 订单将超时关闭
// 2. 接口调用成功 后续异常需进行捕捉 如果 逻辑代码出现异常则需要走完正常流程此时订单状态为 支付中 需要查单处理
try {
JSONObject resJSON = WxpayV3Util.unifiedOrderV3(reqUrl, reqJSON, wxPayService.getConfig());
JSONObject resJSON = WxpayV3Util.unifiedOrderV3(reqUrl, reqJSON, wxPayService);
String payUrl = resJSON.getString("h5_url");
payUrl = sysConfigService.getDBApplicationConfig().getPaySiteUrl() + "/api/common/payUrl/" + Base64.encode(payUrl);

View File

@ -89,7 +89,7 @@ public class WxJsapi extends WxpayPaymentService {
// 1. 如果抛异常则订单状态为 生成状态此时没有查单处理操作 订单将超时关闭
// 2. 接口调用成功 后续异常需进行捕捉 如果 逻辑代码出现异常则需要走完正常流程此时订单状态为 支付中 需要查单处理
try {
JSONObject resJSON = WxpayV3Util.unifiedOrderV3(reqUrl, reqJSON, wxPayService.getConfig());
JSONObject resJSON = WxpayV3Util.unifiedOrderV3(reqUrl, reqJSON, wxPayService);
res.setPayInfo(resJSON.toJSONString());

View File

@ -90,7 +90,7 @@ public class WxLite extends WxpayPaymentService {
// 1. 如果抛异常则订单状态为 生成状态此时没有查单处理操作 订单将超时关闭
// 2. 接口调用成功 后续异常需进行捕捉 如果 逻辑代码出现异常则需要走完正常流程此时订单状态为 支付中 需要查单处理
try {
JSONObject resJSON = WxpayV3Util.unifiedOrderV3(reqUrl, reqJSON, wxPayService.getConfig());
JSONObject resJSON = WxpayV3Util.unifiedOrderV3(reqUrl, reqJSON, wxPayService);
res.setPayInfo(resJSON.toJSONString());

View File

@ -78,7 +78,7 @@ public class WxNative extends WxpayPaymentService {
// 1. 如果抛异常则订单状态为 生成状态此时没有查单处理操作 订单将超时关闭
// 2. 接口调用成功 后续异常需进行捕捉 如果 逻辑代码出现异常则需要走完正常流程此时订单状态为 支付中 需要查单处理
try {
JSONObject resJSON = WxpayV3Util.unifiedOrderV3(reqUrl, reqJSON, wxPayService.getConfig());
JSONObject resJSON = WxpayV3Util.unifiedOrderV3(reqUrl, reqJSON, wxPayService);
String codeUrl = resJSON.getString("code_url");
if (CS.PAY_DATA_TYPE.CODE_IMG_URL.equals(bizRQ.getPayDataType())){ //二维码图片地址