feat:【PAY 支付】AbstractAlipayPayClient,支付宝增加回调解析
This commit is contained in:
parent
7653be9d48
commit
f81dc105a2
|
@ -81,24 +81,11 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
||||||
@Override
|
@Override
|
||||||
public PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body, Map<String, String> headers) throws Throwable {
|
public PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body, Map<String, String> headers) throws Throwable {
|
||||||
// 1. 校验回调数据
|
// 1. 校验回调数据
|
||||||
Map<String, String> bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8);
|
verifyNotifyData(params);
|
||||||
boolean verify;
|
|
||||||
if (Objects.equals(config.getMode(), MODE_PUBLIC_KEY)) {
|
|
||||||
verify = AlipaySignature.rsaCheckV1(params, config.getAlipayPublicKey(),
|
|
||||||
StandardCharsets.UTF_8.name(), config.getSignType());
|
|
||||||
} else if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
|
|
||||||
// 由于 rsaCertCheckV1 的第二个参数是 path,所以不能这么调用!!!通过阅读源码,发现可以采用如下方式!
|
|
||||||
X509Certificate cert = AntCertificationUtil.getCertFromContent(config.getAlipayPublicCertContent());
|
|
||||||
String publicKey = Base64.encodeBase64String(cert.getEncoded());
|
|
||||||
verify = AlipaySignature.rsaCheckV1(bodyObj, publicKey,
|
|
||||||
StandardCharsets.UTF_8.name(), config.getSignType());
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("未知的公钥类型:" + config.getMode());
|
|
||||||
}
|
|
||||||
Assert.isTrue(verify, "验签结果不通过");
|
|
||||||
|
|
||||||
// 2. 解析订单的状态
|
// 2. 解析订单的状态
|
||||||
// 额外说明:支付宝不仅仅支付成功会回调,再各种触发支付单数据变化时,都会进行回调,所以这里 status 的解析会写的比较复杂
|
// 额外说明:支付宝不仅仅支付成功会回调,再各种触发支付单数据变化时,都会进行回调,所以这里 status 的解析会写的比较复杂
|
||||||
|
Map<String, String> bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8);
|
||||||
Integer status = parseStatus(bodyObj.get("trade_status"));
|
Integer status = parseStatus(bodyObj.get("trade_status"));
|
||||||
// 特殊逻辑: 支付宝没有退款成功的状态,所以,如果有退款金额,我们认为是退款成功
|
// 特殊逻辑: 支付宝没有退款成功的状态,所以,如果有退款金额,我们认为是退款成功
|
||||||
if (MapUtil.getDouble(bodyObj, "refund_fee", 0D) > 0) {
|
if (MapUtil.getDouble(bodyObj, "refund_fee", 0D) > 0) {
|
||||||
|
@ -324,10 +311,55 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
||||||
response.getOutBizNo(), response);
|
response.getOutBizNo(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @chihuo:这里是不是也要实现,支付宝的。
|
// TODO @芋艿:由于支付宝一直没触发回调,这个方法暂时没办法测试
|
||||||
@Override
|
@Override
|
||||||
protected PayTransferRespDTO doParseTransferNotify(Map<String, String> params, String body, Map<String, String> headers) {
|
protected PayTransferRespDTO doParseTransferNotify(Map<String, String> params, String body, Map<String, String> headers)
|
||||||
throw new UnsupportedOperationException("未实现");
|
throws Throwable {
|
||||||
|
// 1. 校验回调数据
|
||||||
|
verifyNotifyData(params);
|
||||||
|
|
||||||
|
// 2. 解析转账状态
|
||||||
|
Map<String, String> bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8);
|
||||||
|
String status = bodyObj.get("status");
|
||||||
|
String outBizNo = bodyObj.get("out_biz_no");
|
||||||
|
String orderId = bodyObj.get("order_id");
|
||||||
|
String payDate = bodyObj.get("pay_date");
|
||||||
|
|
||||||
|
// 3. 根据状态返回对应的结果
|
||||||
|
if (Objects.equals(status, "SUCCESS")) {
|
||||||
|
return PayTransferRespDTO.successOf(orderId, parseTime(payDate), outBizNo, bodyObj);
|
||||||
|
}
|
||||||
|
if (Objects.equals(status, "DEALING")) {
|
||||||
|
return PayTransferRespDTO.processingOf(orderId, outBizNo, bodyObj);
|
||||||
|
}
|
||||||
|
if (ObjectUtils.equalsAny(status, "REFUND", "FAIL")) {
|
||||||
|
return PayTransferRespDTO.closedOf(bodyObj.get("sub_code"), bodyObj.get("sub_msg"),
|
||||||
|
outBizNo, bodyObj);
|
||||||
|
}
|
||||||
|
return PayTransferRespDTO.waitingOf(orderId, outBizNo, bodyObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验回调数据
|
||||||
|
*
|
||||||
|
* @param params 回调参数
|
||||||
|
* @throws Throwable 验签失败时抛出异常
|
||||||
|
*/
|
||||||
|
protected void verifyNotifyData(Map<String, String> params) throws Throwable {
|
||||||
|
boolean verify;
|
||||||
|
if (Objects.equals(config.getMode(), MODE_PUBLIC_KEY)) {
|
||||||
|
verify = AlipaySignature.rsaCheckV1(params, config.getAlipayPublicKey(),
|
||||||
|
StandardCharsets.UTF_8.name(), config.getSignType());
|
||||||
|
} else if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
|
||||||
|
// 由于 rsaCertCheckV1 的第二个参数是 path,所以不能这么调用!!!通过阅读源码,发现可以采用如下方式!
|
||||||
|
X509Certificate cert = AntCertificationUtil.getCertFromContent(config.getAlipayPublicCertContent());
|
||||||
|
String publicKey = Base64.encodeBase64String(cert.getEncoded());
|
||||||
|
verify = AlipaySignature.rsaCheckV1(params, publicKey,
|
||||||
|
StandardCharsets.UTF_8.name(), config.getSignType());
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("未知的公钥类型:" + config.getMode());
|
||||||
|
}
|
||||||
|
Assert.isTrue(verify, "验签结果不通过");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 各种工具方法 ==========
|
// ========== 各种工具方法 ==========
|
||||||
|
|
Loading…
Reference in New Issue