mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2026-03-10 00:13:40 +08:00
🎨 #3056 【微信支付】优化支付/退款结果解析,增加对V3版本服务商的下单/退款支持
This commit is contained in:
@@ -169,7 +169,7 @@ public interface WxPayService {
|
||||
* <p>
|
||||
* 部分字段会包含敏感信息,所以在提交前需要在请求头中会包含"Wechatpay-Serial"信息
|
||||
*
|
||||
* @param url 请求地址
|
||||
* @param url 请求地址
|
||||
* @return 返回请求结果字符串 string
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
@@ -550,6 +550,27 @@ public interface WxPayService {
|
||||
*/
|
||||
<T> T createOrderV3(TradeTypeEnum tradeType, WxPayUnifiedOrderV3Request request) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 服务商模式调用统一下单接口,并组装生成支付所需参数对象.
|
||||
*
|
||||
* @param <T> 请使用{@link com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result}里的内部类或字段
|
||||
* @param tradeType the trade type
|
||||
* @param request 统一下单请求参数
|
||||
* @return 返回 {@link com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result}里的内部类或字段
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
<T> T createPartnerOrderV3(TradeTypeEnum tradeType, WxPayPartnerUnifiedOrderV3Request request) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
|
||||
*
|
||||
* @param tradeType the trade type
|
||||
* @param request 请求对象,注意一些参数如spAppid、spMchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置)
|
||||
* @return the wx pay unified order result
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
WxPayUnifiedOrderV3Result unifiedPartnerOrderV3(TradeTypeEnum tradeType, WxPayPartnerUnifiedOrderV3Request request) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
|
||||
*
|
||||
@@ -802,7 +823,7 @@ public interface WxPayService {
|
||||
WxPayOrderNotifyResult parseOrderNotifyResult(String xmlData, String signType) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 解析支付结果v3通知.
|
||||
* 解析支付结果v3通知. 直连商户模式
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
|
||||
*
|
||||
* @param notifyData 通知数据
|
||||
@@ -810,7 +831,31 @@ public interface WxPayService {
|
||||
* @return the wx pay order notify result
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
WxPayOrderNotifyV3Result parseOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException;
|
||||
WxPayNotifyV3Result parseOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 服务商模式解析支付结果v3通知.
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_5.shtml
|
||||
*
|
||||
* @param notifyData 通知数据
|
||||
* @param header 通知头部数据,不传则表示不校验头
|
||||
* @return the wx pay order notify result
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
WxPayPartnerNotifyV3Result parsePartnerOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 支付服务商和直连商户两种模式
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
|
||||
*
|
||||
* @param notifyData 通知数据
|
||||
* @param header 通知头部数据,不传则表示不校验头
|
||||
* @param resultType 结果类型
|
||||
* @param dataType 结果数据类型
|
||||
* @return the wx pay order notify result
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
<T extends WxPayBaseNotifyV3Result<E>, E> T baseParseOrderNotifyV3Result(String notifyData, SignatureHeader header, Class<T> resultType, Class<E> dataType) throws WxPayException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
@@ -836,7 +881,7 @@ public interface WxPayService {
|
||||
WxPayRefundNotifyResult parseRefundNotifyResult(String xmlData) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 解析退款结果通知
|
||||
* 解析直连商户退款结果通知
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=9
|
||||
*
|
||||
* @param notifyData 通知数据
|
||||
@@ -846,6 +891,17 @@ public interface WxPayService {
|
||||
*/
|
||||
WxPayRefundNotifyV3Result parseRefundNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 解析服务商模式退款结果通知
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_11.shtml
|
||||
*
|
||||
* @param notifyData 通知数据
|
||||
* @param header 通知头部数据,不传则表示不校验头
|
||||
* @return the wx pay refund notify result
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
WxPayPartnerRefundNotifyV3Result parsePartnerRefundNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 解析扫码支付回调通知
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4
|
||||
@@ -1380,6 +1436,7 @@ public interface WxPayService {
|
||||
|
||||
/**
|
||||
* 获取服务商支付分服务类
|
||||
*
|
||||
* @return the partner pay score service
|
||||
*/
|
||||
PartnerPayScoreService getPartnerPayScoreService();
|
||||
|
||||
@@ -31,6 +31,7 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.chanjar.weixin.common.error.WxRuntimeException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.reflect.ConstructorUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -343,7 +344,17 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxPayOrderNotifyV3Result parseOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException {
|
||||
public WxPayNotifyV3Result parseOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException {
|
||||
return baseParseOrderNotifyV3Result(notifyData, header, WxPayNotifyV3Result.class, WxPayNotifyV3Result.DecryptNotifyResult.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxPayPartnerNotifyV3Result parsePartnerOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException {
|
||||
return this.baseParseOrderNotifyV3Result(notifyData, header, WxPayPartnerNotifyV3Result.class, WxPayPartnerNotifyV3Result.DecryptNotifyResult.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends WxPayBaseNotifyV3Result<E>, E> T baseParseOrderNotifyV3Result(String notifyData, SignatureHeader header, Class<T> resultType, Class<E> dataType) throws WxPayException {
|
||||
if (Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)) {
|
||||
throw new WxPayException("非法请求,头部信息验证失败");
|
||||
}
|
||||
@@ -355,12 +366,12 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
||||
String apiV3Key = this.getConfig().getApiV3Key();
|
||||
try {
|
||||
String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key);
|
||||
WxPayOrderNotifyV3Result.DecryptNotifyResult decryptNotifyResult = GSON.fromJson(result, WxPayOrderNotifyV3Result.DecryptNotifyResult.class);
|
||||
WxPayOrderNotifyV3Result notifyResult = new WxPayOrderNotifyV3Result();
|
||||
E decryptNotifyResult = GSON.fromJson(result, dataType);
|
||||
T notifyResult = ConstructorUtils.invokeConstructor(resultType);
|
||||
notifyResult.setRawData(response);
|
||||
notifyResult.setResult(decryptNotifyResult);
|
||||
return notifyResult;
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
} catch (Exception e) {
|
||||
throw new WxPayException("解析报文异常!", e);
|
||||
}
|
||||
}
|
||||
@@ -409,25 +420,12 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
||||
|
||||
@Override
|
||||
public WxPayRefundNotifyV3Result parseRefundNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException {
|
||||
if (Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)) {
|
||||
throw new WxPayException("非法请求,头部信息验证失败");
|
||||
}
|
||||
OriginNotifyResponse response = GSON.fromJson(notifyData, OriginNotifyResponse.class);
|
||||
OriginNotifyResponse.Resource resource = response.getResource();
|
||||
String cipherText = resource.getCiphertext();
|
||||
String associatedData = resource.getAssociatedData();
|
||||
String nonce = resource.getNonce();
|
||||
String apiV3Key = this.getConfig().getApiV3Key();
|
||||
try {
|
||||
String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key);
|
||||
WxPayRefundNotifyV3Result.DecryptNotifyResult decryptNotifyResult = GSON.fromJson(result, WxPayRefundNotifyV3Result.DecryptNotifyResult.class);
|
||||
WxPayRefundNotifyV3Result notifyResult = new WxPayRefundNotifyV3Result();
|
||||
notifyResult.setRawData(response);
|
||||
notifyResult.setResult(decryptNotifyResult);
|
||||
return notifyResult;
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
throw new WxPayException("解析报文异常!", e);
|
||||
}
|
||||
return this.baseParseOrderNotifyV3Result(notifyData, header, WxPayRefundNotifyV3Result.class, WxPayRefundNotifyV3Result.DecryptNotifyResult.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxPayPartnerRefundNotifyV3Result parsePartnerRefundNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException {
|
||||
return this.baseParseOrderNotifyV3Result(notifyData, header, WxPayPartnerRefundNotifyV3Result.class, WxPayPartnerRefundNotifyV3Result.DecryptNotifyResult.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -665,6 +663,37 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
||||
return result.getPayInfo(tradeType, request.getAppid(), request.getMchid(), this.getConfig().getPrivateKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T createPartnerOrderV3(TradeTypeEnum tradeType, WxPayPartnerUnifiedOrderV3Request request) throws WxPayException {
|
||||
WxPayUnifiedOrderV3Result result = this.unifiedPartnerOrderV3(tradeType, request);
|
||||
//获取应用ID
|
||||
String appId = StringUtils.isBlank(request.getSubAppid()) ? request.getSpAppid() : request.getSubAppid();
|
||||
return result.getPayInfo(tradeType, appId, request.getSubMchId(), this.getConfig().getPrivateKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxPayUnifiedOrderV3Result unifiedPartnerOrderV3(TradeTypeEnum tradeType, WxPayPartnerUnifiedOrderV3Request request) throws WxPayException {
|
||||
if (StringUtils.isBlank(request.getSpAppid())) {
|
||||
request.setSpAppid(this.getConfig().getAppId());
|
||||
}
|
||||
if (StringUtils.isBlank(request.getSpMchId())) {
|
||||
request.setSpMchId(this.getConfig().getMchId());
|
||||
}
|
||||
if (StringUtils.isBlank(request.getNotifyUrl())) {
|
||||
request.setNotifyUrl(this.getConfig().getNotifyUrl());
|
||||
}
|
||||
if (StringUtils.isBlank(request.getSubAppid())) {
|
||||
request.setSubAppid(this.getConfig().getSubAppId());
|
||||
}
|
||||
if (StringUtils.isBlank(request.getSubMchId())) {
|
||||
request.setSubMchId(this.getConfig().getSubMchId());
|
||||
}
|
||||
|
||||
String url = this.getPayBaseUrl() + tradeType.getPartnerUrl();
|
||||
String response = this.postV3(url, GSON.toJson(request));
|
||||
return GSON.fromJson(response, WxPayUnifiedOrderV3Result.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxPayUnifiedOrderV3Result unifiedOrderV3(TradeTypeEnum tradeType, WxPayUnifiedOrderV3Request request) throws WxPayException {
|
||||
if (StringUtils.isBlank(request.getAppid())) {
|
||||
|
||||
Reference in New Issue
Block a user