feat 支付退款状态同步

This commit is contained in:
bootx
2024-01-16 23:34:09 +08:00
parent 259bc77275
commit 273e26bd53
5 changed files with 44 additions and 13 deletions

View File

@@ -20,6 +20,9 @@ public enum PaySyncStatusEnum {
PAY_SUCCESS("pay_success", "支付成功"), PAY_SUCCESS("pay_success", "支付成功"),
PAY_WAIT("pay_wait", "待支付"), PAY_WAIT("pay_wait", "待支付"),
CLOSED("closed", "已关闭"), CLOSED("closed", "已关闭"),
/** 部分退款 */
PARTIAL_REFUND("partial_refund","部分退款"),
/** 全部退款 */
REFUND("refund", "已退款"), REFUND("refund", "已退款"),
NOT_FOUND("not_found", "交易不存在"), NOT_FOUND("not_found", "交易不存在"),
/** /**

View File

@@ -88,4 +88,7 @@ public interface WeChatPayCode {
/** 支付失败(刷卡支付) */ /** 支付失败(刷卡支付) */
String TRADE_PAYERROR = "PAYERROR"; String TRADE_PAYERROR = "PAYERROR";
/** 退款总金额(各退款单的退款金额累加) */
String REFUND_FEE = "refund_fee";
} }

View File

@@ -8,7 +8,9 @@ import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.payment.sync.result.GatewaySyncResult; import cn.bootx.platform.daxpay.service.core.payment.sync.result.GatewaySyncResult;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeFastpayRefundQueryModel;
import com.alipay.api.domain.AlipayTradeQueryModel; import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse; import com.alipay.api.response.AlipayTradeQueryResponse;
import com.ijpay.alipay.AliPayApi; import com.ijpay.alipay.AliPayApi;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -16,7 +18,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Objects; import java.util.Objects;
/** /**
@@ -43,13 +44,14 @@ public class AliPaySyncService {
try { try {
AlipayTradeQueryModel queryModel = new AlipayTradeQueryModel(); AlipayTradeQueryModel queryModel = new AlipayTradeQueryModel();
queryModel.setOutTradeNo(String.valueOf(payOrder.getId())); queryModel.setOutTradeNo(String.valueOf(payOrder.getId()));
queryModel.setQueryOptions(Collections.singletonList("trade_settle_info")); // queryModel.setQueryOptions(Collections.singletonList("trade_settle_info"));
// 查询参数 // 查询参数
AlipayTradeQueryResponse response = AliPayApi.tradeQueryToResponse(queryModel); AlipayTradeQueryResponse response = AliPayApi.tradeQueryToResponse(queryModel);
String tradeStatus = response.getTradeStatus(); String tradeStatus = response.getTradeStatus();
syncResult.setSyncInfo(JSONUtil.toJsonStr(response)); syncResult.setSyncInfo(JSONUtil.toJsonStr(response));
// 支付完成 TODO 部分退款也在这个地方, 但无法区分 // 支付完成 TODO 部分退款也在这个地方, 但无法进行区分, 需要借助对账进行处理
if (Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_SUCCESS) || Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_FINISHED)) { if (Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_SUCCESS) || Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_FINISHED)) {
this.syncRefundStatus(payOrder);
PaymentContextLocal.get().getAsyncPayInfo().setTradeNo(response.getTradeNo()); PaymentContextLocal.get().getAsyncPayInfo().setTradeNo(response.getTradeNo());
// 支付完成时间 // 支付完成时间
LocalDateTime payTime = LocalDateTimeUtil.of(response.getSendPayDate()); LocalDateTime payTime = LocalDateTimeUtil.of(response.getSendPayDate());
@@ -81,4 +83,14 @@ public class AliPaySyncService {
} }
return syncResult; return syncResult;
} }
/**
* 退款同步查询
*/
private void syncRefundStatus(PayOrder payOrder) throws AlipayApiException {
AlipayTradeFastpayRefundQueryModel queryModel = new AlipayTradeFastpayRefundQueryModel();
queryModel.setOutTradeNo(String.valueOf(payOrder.getId()));
AlipayTradeFastpayRefundQueryResponse response = AliPayApi.tradeRefundQueryToResponse(queryModel);
response.getRefundStatus();
}
} }

View File

@@ -5,6 +5,7 @@ import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
import cn.bootx.platform.daxpay.service.code.WeChatPayCode; import cn.bootx.platform.daxpay.service.code.WeChatPayCode;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig; import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.payment.sync.result.GatewaySyncResult; import cn.bootx.platform.daxpay.service.core.payment.sync.result.GatewaySyncResult;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
@@ -34,15 +35,15 @@ public class WeChatPaySyncService {
/** /**
* 同步查询 * 同步查询
*/ */
public GatewaySyncResult syncPayStatus(Long paymentId, WeChatPayConfig weChatPayConfig) { public GatewaySyncResult syncPayStatus(PayOrder order, WeChatPayConfig weChatPayConfig) {
GatewaySyncResult syncResult = new GatewaySyncResult().setSyncStatus(PaySyncStatusEnum.FAIL); GatewaySyncResult syncResult = new GatewaySyncResult().setSyncStatus(PaySyncStatusEnum.FAIL);
Map<String, String> params = UnifiedOrderModel.builder() Map<String, String> params = UnifiedOrderModel.builder()
.appid(weChatPayConfig.getWxAppId()) .appid(weChatPayConfig.getWxAppId())
.mch_id(weChatPayConfig.getWxMchId()) .mch_id(weChatPayConfig.getWxMchId())
.nonce_str(WxPayKit.generateStr()) .nonce_str(WxPayKit.generateStr())
.out_trade_no(String.valueOf(paymentId)) .out_trade_no(String.valueOf(order.getId()))
.build() .build()
.createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); .createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256);
try { try {
String xmlResult = WxPayApi.orderQuery(params); String xmlResult = WxPayApi.orderQuery(params);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult); Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
@@ -73,9 +74,9 @@ public class WeChatPaySyncService {
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_WAIT); return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_WAIT);
} }
// 已退款/退款中 // 已退款/退款中 触发一下退款记录的查询
if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_REFUND)) { if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_REFUND)) {
return syncResult.setSyncStatus(PaySyncStatusEnum.REFUND); this.syncRefundStatus(order.getId(), weChatPayConfig);
} }
// 已关闭 // 已关闭
if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_CLOSED) if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_CLOSED)
@@ -94,4 +95,16 @@ public class WeChatPaySyncService {
/** /**
* 退款查询 * 退款查询
*/ */
private GatewaySyncResult syncRefundStatus(Long paymentId, WeChatPayConfig weChatPayConfig){
Map<String, String> params = UnifiedOrderModel.builder()
.appid(weChatPayConfig.getWxAppId())
.mch_id(weChatPayConfig.getWxMchId())
.nonce_str(WxPayKit.generateStr())
.out_trade_no(String.valueOf(paymentId))
.build()
.createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256);
String xmlResult = WxPayApi.orderRefundQuery(false, params);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
return new GatewaySyncResult().setSyncInfo(JSONUtil.toJsonStr(result));
}
} }

View File

@@ -34,7 +34,7 @@ public class WeChatPaySyncStrategy extends AbsPaySyncStrategy {
public GatewaySyncResult doSyncStatus() { public GatewaySyncResult doSyncStatus() {
// 检查并获取微信支付配置 // 检查并获取微信支付配置
this.initWeChatPayConfig(); this.initWeChatPayConfig();
return weChatPaySyncService.syncPayStatus(this.getOrder().getId(), this.weChatPayConfig); return weChatPaySyncService.syncPayStatus(this.getOrder(), this.weChatPayConfig);
} }