mall + pay:

1. 增加支付宝退款查询接口
This commit is contained in:
YunaiV 2023-07-22 20:46:38 +08:00
parent ac5646b84d
commit 5b066ea693
6 changed files with 79 additions and 12 deletions

View File

@ -67,4 +67,13 @@ public interface PayClient {
*/
PayRefundRespDTO parseRefundNotify(Map<String, String> params, String body);
/**
* 获得退款订单信息
*
* @param outTradeNo 外部订单号
* @param outRefundNo 外部退款号
* @return 退款订单信息
*/
PayRefundRespDTO getRefund(String outTradeNo, String outRefundNo);
}

View File

@ -94,7 +94,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
throws Throwable;
@Override
public PayOrderRespDTO parseOrderNotify(Map<String, String> params, String body) {
public final PayOrderRespDTO parseOrderNotify(Map<String, String> params, String body) {
try {
return doParseOrderNotify(params, body);
} catch (Throwable ex) {
@ -108,7 +108,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
throws Throwable;
@Override
public PayOrderRespDTO getOrder(String outTradeNo) {
public final PayOrderRespDTO getOrder(String outTradeNo) {
try {
return doGetOrder(outTradeNo);
} catch (Throwable ex) {
@ -124,7 +124,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
// ============ 退款相关 ==========
@Override
public PayRefundRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
public final PayRefundRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
ValidationUtils.validate(reqDTO);
// 执行统一退款
PayRefundRespDTO resp;
@ -145,7 +145,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
protected abstract PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable;
@Override
public PayRefundRespDTO parseRefundNotify(Map<String, String> params, String body) {
public final PayRefundRespDTO parseRefundNotify(Map<String, String> params, String body) {
try {
return doParseRefundNotify(params, body);
} catch (Throwable ex) {
@ -158,6 +158,20 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
protected abstract PayRefundRespDTO doParseRefundNotify(Map<String, String> params, String body)
throws Throwable;
@Override
public final PayRefundRespDTO getRefund(String outTradeNo, String outRefundNo) {
try {
return doGetRefund(outTradeNo, outRefundNo);
} catch (Throwable ex) {
log.error("[getRefund][客户端({}) outTradeNo({}) outRefundNo({}) 查询退款单异常]",
getId(), outTradeNo, outRefundNo, ex);
throw buildPayException(ex);
}
}
protected abstract PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo)
throws Throwable;
// ========== 各种工具方法 ==========
private PayException buildPayException(Throwable ex) {

View File

@ -17,11 +17,14 @@ import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConfig;
import com.alipay.api.AlipayResponse;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeFastpayRefundQueryModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import lombok.SneakyThrows;
@ -29,6 +32,7 @@ import lombok.extern.slf4j.Slf4j;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
@ -102,7 +106,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
// 2.1 执行请求
AlipayTradeQueryResponse response = client.execute(request);
if (!response.isSuccess()) {
if (!response.isSuccess()) { // 不成功例如说订单不存在
return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
outTradeNo, response);
}
@ -143,15 +147,14 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
// 2.1 执行请求
AlipayTradeRefundResponse response = client.execute(request);
if (!response.isSuccess()) {
return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response);
}
// 2.2 创建返回结果
// 支付宝只要退款调用返回 success就认为退款成功不需要回调具体可见 parseNotify 方法的说明
// 另外支付宝没有退款单号所以不用设置
if (response.isSuccess()) {
return PayRefundRespDTO.successOf(null, LocalDateTimeUtil.of(response.getGmtRefundPay()),
reqDTO.getOutRefundNo(), response);
} else {
return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response);
}
}
@Override
@ -164,6 +167,35 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
throw new UnsupportedOperationException("支付宝无退款回调");
}
@Override
protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) throws AlipayApiException {
// 1.1 构建 AlipayTradeFastpayRefundQueryModel 请求
AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
model.setOutTradeNo(outTradeNo);
model.setOutRequestNo(outRefundNo);
model.setQueryOptions(Collections.singletonList("gmt_refund_pay"));
// 1.2 构建 AlipayTradeFastpayRefundQueryRequest 请求
AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
request.setBizModel(model);
// 2.1 执行请求
AlipayTradeFastpayRefundQueryResponse response = client.execute(request);
if (!response.isSuccess()) {
// 明确不存在的情况应该就是失败可进行关闭
if (ObjectUtils.equalsAny(response.getSubCode(), "TRADE_NOT_EXIST", "ACQ.TRADE_NOT_EXIST")) {
return PayRefundRespDTO.failureOf(outRefundNo, response);
}
// 可能存在ACQ.SYSTEM_ERROR系统错误等情况所以返回 WAIT 继续等待
return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
}
// 2.2 创建返回结果
if (Objects.equals(response.getRefundStatus(), "REFUND_SUCCESS")) {
return PayRefundRespDTO.successOf(null, LocalDateTimeUtil.of(response.getGmtRefundPay()),
outRefundNo, response);
}
return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
}
// ========== 各种工具方法 ==========
protected String formatAmount(Integer amount) {

View File

@ -307,6 +307,11 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
return PayRefundRespDTO.failureOf(result.getOutRefundNo(), response);
}
@Override
protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) {
return null;
}
// ========== 各种工具方法 ==========
static String formatDateV2(LocalDateTime time) {

View File

@ -4,6 +4,7 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;

View File

@ -70,6 +70,12 @@ public class PayRefundDO extends BaseDO {
* 关联 {@link PayOrderDO#getId()}
*/
private Long orderId;
/**
* 支付订单编号
*
* 冗余 {@link PayOrderDO#getNo()}
*/
private String orderNo;
// ========== 商户相关字段 ==========
/**