mirror of
https://gitee.com/dromara/dax-pay.git
synced 2025-09-29 06:52:41 +00:00
ref 支付同步逻辑, 支付单状态不一致修复逻辑, 单商户单独拆包
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
package cn.bootx.platform.daxpay.code;
|
||||
|
||||
/**
|
||||
* 支付网关同步状态
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2021/4/21
|
||||
*/
|
||||
public interface PaySyncStatus {
|
||||
|
||||
/** 不需要同步 */
|
||||
String NOT_SYNC = "not_sync";
|
||||
|
||||
/** 远程支付成功 */
|
||||
String TRADE_SUCCESS = "trade_success";
|
||||
|
||||
/** 交易创建,等待买家付款 */
|
||||
String WAIT_BUYER_PAY = "wait_buyer_pay";
|
||||
|
||||
/** 已关闭 */
|
||||
String TRADE_CLOSED = "trade_closed";
|
||||
|
||||
/** 已退款 */
|
||||
String TRADE_REFUND = "trade_refund";
|
||||
|
||||
/** 查询不到订单 */
|
||||
String NOT_FOUND = "not_found";
|
||||
|
||||
/** 查询失败 */
|
||||
String FAIL = "fail";
|
||||
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package cn.bootx.platform.daxpay.common.context;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayWayEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@@ -14,12 +15,21 @@ import java.time.LocalDateTime;
|
||||
@Accessors(chain = true)
|
||||
public class AsyncPayLocal {
|
||||
|
||||
/** 异步支付方式 */
|
||||
private PayWayEnum payWay;
|
||||
|
||||
|
||||
/**
|
||||
* 第三方支付平台订单号
|
||||
* 1. 如付款码支付直接成功时会出现
|
||||
* 2. 回调或者支付同步时也会有这个值
|
||||
*/
|
||||
private String tradeNo;
|
||||
|
||||
|
||||
/** 支付参数体(通常用于发起支付的参数) */
|
||||
private String payBody;
|
||||
|
||||
/** 第三方支付平台订单号(如付款码支付直接成功时会出现) */
|
||||
private String tradeNo;
|
||||
|
||||
/** 订单失效时间, 优先用这个 */
|
||||
private LocalDateTime expiredTime;
|
||||
|
||||
|
@@ -21,8 +21,8 @@ public class PaymentContext {
|
||||
/** 异步支付相关信息 */
|
||||
private final AsyncPayLocal asyncPayInfo = new AsyncPayLocal();
|
||||
|
||||
/** 退款相关信息 */
|
||||
private final AsyncRefundLocal refundInfo = new AsyncRefundLocal();
|
||||
/** 异步退款相关信息 */
|
||||
private final AsyncRefundLocal asyncRefundInfo = new AsyncRefundLocal();
|
||||
|
||||
/** 消息通知相关信息 */
|
||||
private final NoticeLocal noticeInfo = new NoticeLocal();
|
||||
|
@@ -24,6 +24,9 @@ public class AliPayOrder extends BasePayOrder implements EntityBaseFunction<AliP
|
||||
/** 支付宝交易号 */
|
||||
private String tradeNo;
|
||||
|
||||
/** 支付方式 */
|
||||
private String payWay;
|
||||
|
||||
@Override
|
||||
public AliPaymentDto toDto() {
|
||||
AliPaymentDto dto = new AliPaymentDto();
|
||||
|
@@ -2,7 +2,7 @@ package cn.bootx.platform.daxpay.core.channel.alipay.service;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import cn.bootx.platform.daxpay.common.context.AsyncPayLocal;
|
||||
import cn.bootx.platform.daxpay.common.entity.OrderRefundableInfo;
|
||||
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.core.channel.alipay.dao.AliPayOrderManager;
|
||||
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayOrder;
|
||||
@@ -10,8 +10,6 @@ import cn.bootx.platform.daxpay.core.order.pay.dao.PayOrderChannelManager;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.dao.PayOrderManager;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrderChannel;
|
||||
import cn.bootx.platform.daxpay.common.entity.OrderRefundableInfo;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayWayParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -46,8 +44,7 @@ public class AliPayOrderService {
|
||||
* 支付调起成功 更新payment中异步支付类型信息, 如果支付完成, 创建支付宝支付单
|
||||
*/
|
||||
public void updatePaySuccess(PayOrder payOrder, PayWayParam payWayParam) {
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
|
||||
payOrder.setAsyncPayMode(true)
|
||||
payOrder.setAsyncPay(true)
|
||||
.setAsyncPayChannel(PayChannelEnum.ALI.getCode());
|
||||
|
||||
// 更新支付宝异步支付类型信息
|
||||
@@ -80,29 +77,31 @@ public class AliPayOrderService {
|
||||
payOrder.setRefundableInfos(refundableInfos);
|
||||
// 如果支付完成(付款码情况) 调用 updateSyncSuccess 创建支付宝支付记录
|
||||
if (Objects.equals(payOrder.getStatus(), PayStatusEnum.SUCCESS.getCode())) {
|
||||
this.createAliPayment(payOrder, payWayParam, asyncPayInfo.getTradeNo());
|
||||
this.updateAsyncSuccess(payOrder, payWayParam.getAmount());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新异步支付记录成功状态, 并创建支付宝支付记录
|
||||
*/
|
||||
public void updateAsyncSuccess(Long id, PayWayParam payWayParam, String tradeNo) {
|
||||
// 更新支付记录
|
||||
PayOrder payOrder = payOrderManager.findById(id).orElseThrow(() -> new PayFailureException("支付记录不存在"));
|
||||
this.createAliPayment(payOrder,payWayParam,tradeNo);
|
||||
public void updateAsyncSuccess(PayOrder payOrder, Integer amount) {
|
||||
// 创建支付宝支付订单
|
||||
this.createAliPayOrder(payOrder,amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建支付宝支付记录(支付调起成功后才会创建)
|
||||
* 创建支付宝支付订单(支付成功后才会创建)
|
||||
*/
|
||||
private void createAliPayment(PayOrder payOrder, PayWayParam payWayParam, String tradeNo) {
|
||||
// 创建支付宝支付记录
|
||||
private void createAliPayOrder(PayOrder payOrder, Integer amount) {
|
||||
String tradeNo = PaymentContextLocal.get()
|
||||
.getAsyncPayInfo()
|
||||
.getTradeNo();
|
||||
|
||||
AliPayOrder aliPayOrder = new AliPayOrder();
|
||||
aliPayOrder.setTradeNo(tradeNo)
|
||||
.setPaymentId(payOrder.getId())
|
||||
.setAmount(payWayParam.getAmount())
|
||||
.setRefundableBalance(payWayParam.getAmount())
|
||||
.setAmount(amount)
|
||||
.setRefundableBalance(amount)
|
||||
.setBusinessNo(payOrder.getBusinessNo())
|
||||
.setStatus(PayStatusEnum.SUCCESS.getCode())
|
||||
.setPayTime(LocalDateTime.now());
|
||||
|
@@ -37,7 +37,7 @@ public class AliPayRefundService {
|
||||
refundModel.setRefundAmount(refundAmount);
|
||||
|
||||
// 设置退款信息
|
||||
AsyncRefundLocal refundInfo = PaymentContextLocal.get().getRefundInfo();
|
||||
AsyncRefundLocal refundInfo = PaymentContextLocal.get().getAsyncRefundInfo();
|
||||
refundInfo.setRefundNo(IdUtil.getSnowflakeNextIdStr());
|
||||
refundModel.setOutRequestNo(refundInfo.getRefundNo());
|
||||
try {
|
||||
|
@@ -1,8 +1,8 @@
|
||||
package cn.bootx.platform.daxpay.core.channel.alipay.service;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.AliPayCode;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatus;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.PaySyncResult;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.SyncResult;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alipay.api.AlipayApiException;
|
||||
import com.alipay.api.domain.AlipayTradeQueryModel;
|
||||
@@ -29,8 +29,8 @@ public class AlipaySyncService {
|
||||
/**
|
||||
* 与支付宝网关同步状态 1 远程支付成功 2 交易创建,等待买家付款 3 超时关闭 4 查询不到 5 查询失败
|
||||
*/
|
||||
public PaySyncResult syncPayStatus(Long paymentId) {
|
||||
PaySyncResult paySyncResult = new PaySyncResult().setPaySyncStatus(PaySyncStatus.FAIL);
|
||||
public SyncResult syncPayStatus(Long paymentId) {
|
||||
SyncResult syncResult = new SyncResult().setSyncStatus(PaySyncStatusEnum.FAIL.getCode());
|
||||
|
||||
// 查询
|
||||
try {
|
||||
@@ -39,35 +39,35 @@ public class AlipaySyncService {
|
||||
// 查询退款参数
|
||||
AlipayTradeQueryResponse response = AliPayApi.tradeQueryToResponse(queryModel);
|
||||
String tradeStatus = response.getTradeStatus();
|
||||
paySyncResult.setJson(JSONUtil.toJsonStr(response));
|
||||
syncResult.setJson(JSONUtil.toJsonStr(response));
|
||||
// 支付完成
|
||||
if (Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_SUCCESS)
|
||||
|| Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_FINISHED)) {
|
||||
|
||||
HashMap<String, String> map = new HashMap<>(1);
|
||||
map.put(AliPayCode.TRADE_NO, response.getTradeNo());
|
||||
return paySyncResult.setPaySyncStatus(PaySyncStatus.TRADE_SUCCESS).setMap(map);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS.getCode()).setMap(map);
|
||||
}
|
||||
// 待支付
|
||||
if (Objects.equals(tradeStatus, AliPayCode.PAYMENT_WAIT_BUYER_PAY)) {
|
||||
return paySyncResult.setPaySyncStatus(PaySyncStatus.WAIT_BUYER_PAY);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_WAIT.getCode());
|
||||
}
|
||||
// 已关闭
|
||||
if (Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_CLOSED)) {
|
||||
return paySyncResult.setPaySyncStatus(PaySyncStatus.TRADE_CLOSED);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.CLOSED.getCode());
|
||||
}
|
||||
// 未找到
|
||||
if (Objects.equals(response.getSubCode(), AliPayCode.ACQ_TRADE_NOT_EXIST)) {
|
||||
return paySyncResult.setPaySyncStatus(PaySyncStatus.NOT_FOUND);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.NOT_FOUND.getCode());
|
||||
}
|
||||
// 退款 支付宝查不到
|
||||
|
||||
}
|
||||
catch (AlipayApiException e) {
|
||||
log.error("查询订单失败:", e);
|
||||
paySyncResult.setMsg(e.getErrMsg());
|
||||
syncResult.setMsg(e.getErrMsg());
|
||||
}
|
||||
return paySyncResult;
|
||||
return syncResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -62,7 +62,7 @@ public class WeChatPayCloseService {
|
||||
errorMsg = result.get(WeChatPayCode.RETURN_MSG);
|
||||
}
|
||||
log.error("订单关闭失败 {}", errorMsg);
|
||||
AsyncRefundLocal refundInfo = PaymentContextLocal.get().getRefundInfo();
|
||||
AsyncRefundLocal refundInfo = PaymentContextLocal.get().getAsyncRefundInfo();
|
||||
refundInfo.setErrorMsg(errorMsg);
|
||||
refundInfo.setErrorCode(Optional.ofNullable(resultCode).orElse(returnCode));
|
||||
throw new PayFailureException(errorMsg);
|
||||
|
@@ -42,7 +42,7 @@ public class WeChatPayOrderService {
|
||||
*/
|
||||
public void updatePaySuccess(PayOrder payOrder, PayWayParam payWayParam) {
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();;
|
||||
payOrder.setAsyncPayMode(true).setAsyncPayChannel(PayChannelEnum.WECHAT.getCode());
|
||||
payOrder.setAsyncPay(true).setAsyncPayChannel(PayChannelEnum.WECHAT.getCode());
|
||||
|
||||
List<PayOrderChannel> payTypeInfos = new ArrayList<>();
|
||||
List<OrderRefundableInfo> refundableInfos = new ArrayList<>();
|
||||
|
@@ -12,7 +12,7 @@ import cn.bootx.platform.daxpay.common.context.AsyncPayLocal;
|
||||
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayConfig;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.PaySyncResult;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.SyncResult;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.service.PaySyncService;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.param.channel.wechat.WeChatPayParam;
|
||||
@@ -40,7 +40,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static cn.bootx.platform.daxpay.code.PaySyncStatus.WAIT_BUYER_PAY;
|
||||
import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.PAY_WAIT;
|
||||
import static com.ijpay.wxpay.model.UnifiedOrderModel.UnifiedOrderModelBuilder;
|
||||
import static com.ijpay.wxpay.model.UnifiedOrderModel.builder;
|
||||
|
||||
@@ -272,14 +272,14 @@ public class WeChatPayService {
|
||||
*/
|
||||
@Async("bigExecutor")
|
||||
@Retryable(value = RetryableException.class, maxAttempts = 10, backoff = @Backoff(value = 5000L))
|
||||
public void rotationSync(PayOrder payment, WeChatPayConfig weChatPayConfig) {
|
||||
PaySyncResult paySyncResult = weChatPaySyncService.syncPayStatus(payment.getId(), weChatPayConfig);
|
||||
public void rotationSync(PayOrder payOrder, WeChatPayConfig weChatPayConfig) {
|
||||
SyncResult syncResult = weChatPaySyncService.syncPayStatus(payOrder.getId(), weChatPayConfig);
|
||||
// 不为支付中状态后, 调用系统同步更新状态, 支付状态则继续重试
|
||||
if (Objects.equals(WAIT_BUYER_PAY, paySyncResult.getPaySyncStatus())) {
|
||||
if (Objects.equals(PAY_WAIT.getCode(), syncResult.getSyncStatus())) {
|
||||
throw new RetryableException();
|
||||
}
|
||||
else {
|
||||
paySyncService.sync(payment);
|
||||
paySyncService.syncPayOrder(payOrder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
package cn.bootx.platform.daxpay.core.channel.wechat.service;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatus;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.code.WeChatPayCode;
|
||||
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayConfig;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.PaySyncResult;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.SyncResult;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.ijpay.core.enums.SignType;
|
||||
import com.ijpay.core.kit.WxPayKit;
|
||||
@@ -30,8 +30,8 @@ public class WeChatPaySyncService {
|
||||
/**
|
||||
* 同步查询
|
||||
*/
|
||||
public PaySyncResult syncPayStatus(Long paymentId, WeChatPayConfig weChatPayConfig) {
|
||||
PaySyncResult paySyncResult = new PaySyncResult().setPaySyncStatus(PaySyncStatus.FAIL);
|
||||
public SyncResult syncPayStatus(Long paymentId, WeChatPayConfig weChatPayConfig) {
|
||||
SyncResult syncResult = new SyncResult().setSyncStatus(PaySyncStatusEnum.FAIL.getCode());
|
||||
Map<String, String> params = UnifiedOrderModel.builder()
|
||||
.appid(weChatPayConfig.getWxAppId())
|
||||
.mch_id(weChatPayConfig.getWxMchId())
|
||||
@@ -42,47 +42,47 @@ public class WeChatPaySyncService {
|
||||
try {
|
||||
String xmlResult = WxPayApi.orderQuery(params);
|
||||
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
|
||||
paySyncResult.setJson(JSONUtil.toJsonStr(result));
|
||||
syncResult.setJson(JSONUtil.toJsonStr(result));
|
||||
// 查询失败
|
||||
if (!WxPayKit.codeIsOk(result.get(WeChatPayCode.RETURN_CODE))) {
|
||||
log.warn("查询微信订单失败:{}", result);
|
||||
return paySyncResult;
|
||||
return syncResult;
|
||||
}
|
||||
|
||||
// 未查到订单
|
||||
if (!WxPayKit.codeIsOk(result.get(WeChatPayCode.RESULT_CODE))) {
|
||||
log.warn("疑似未查询到订单:{}", result);
|
||||
return paySyncResult.setPaySyncStatus(PaySyncStatus.NOT_FOUND);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.NOT_FOUND.getCode());
|
||||
}
|
||||
String tradeStatus = result.get(WeChatPayCode.TRADE_STATE);
|
||||
// 支付完成
|
||||
if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_SUCCESS)
|
||||
|| Objects.equals(tradeStatus, WeChatPayCode.TRADE_ACCEPT)) {
|
||||
return paySyncResult.setPaySyncStatus(PaySyncStatus.TRADE_SUCCESS).setMap(result);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS.getCode()).setMap(result);
|
||||
}
|
||||
// 待支付
|
||||
if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_NOTPAY)
|
||||
|| Objects.equals(tradeStatus, WeChatPayCode.TRADE_USERPAYING)) {
|
||||
return paySyncResult.setPaySyncStatus(PaySyncStatus.WAIT_BUYER_PAY);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_WAIT.getCode());
|
||||
}
|
||||
|
||||
// 已退款/退款中
|
||||
if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_REFUND)) {
|
||||
return paySyncResult.setPaySyncStatus(PaySyncStatus.TRADE_REFUND);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.REFUND.getCode());
|
||||
}
|
||||
// 已关闭
|
||||
if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_CLOSED)
|
||||
|| Objects.equals(tradeStatus, WeChatPayCode.TRADE_REVOKED)
|
||||
|| Objects.equals(tradeStatus, WeChatPayCode.TRADE_PAYERROR)) {
|
||||
return paySyncResult.setPaySyncStatus(PaySyncStatus.TRADE_CLOSED);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.CLOSED.getCode());
|
||||
}
|
||||
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
log.error("查询订单失败:", e);
|
||||
paySyncResult.setMsg(e.getMessage());
|
||||
syncResult.setMsg(e.getMessage());
|
||||
}
|
||||
return paySyncResult;
|
||||
return syncResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -47,7 +47,7 @@ public class WechatRefundService {
|
||||
String refundFee = String.valueOf(amount);
|
||||
String totalFee = refundableInfo.getAmount().toString();
|
||||
// 设置退款信息
|
||||
AsyncRefundLocal refundInfo = PaymentContextLocal.get().getRefundInfo();
|
||||
AsyncRefundLocal refundInfo = PaymentContextLocal.get().getAsyncRefundInfo();
|
||||
refundInfo.setRefundNo(IdUtil.getSnowflakeNextIdStr());
|
||||
Map<String, String> params = RefundModel.builder()
|
||||
.appid(weChatPayConfig.getWxAppId())
|
||||
@@ -86,7 +86,7 @@ public class WechatRefundService {
|
||||
errorMsg = result.get(WeChatPayCode.RETURN_MSG);
|
||||
}
|
||||
log.error("订单退款失败 {}", errorMsg);
|
||||
AsyncRefundLocal refundInfo = PaymentContextLocal.get().getRefundInfo();
|
||||
AsyncRefundLocal refundInfo = PaymentContextLocal.get().getAsyncRefundInfo();
|
||||
refundInfo.setErrorMsg(errorMsg);
|
||||
refundInfo.setErrorCode(Optional.ofNullable(resultCode).orElse(returnCode));
|
||||
throw new PayFailureException(errorMsg);
|
||||
|
@@ -56,8 +56,8 @@ public class PaymentBuilder {
|
||||
.setRefundableInfos(refundableInfos)
|
||||
.setStatus(PayStatusEnum.PROGRESS.getCode())
|
||||
.setAmount(sumAmount)
|
||||
.setCombinationPayMode(payParam.getPayWays().size() > 1)
|
||||
.setAsyncPayMode(asyncPayMode.isPresent())
|
||||
.setCombinationPay(payParam.getPayWays().size() > 1)
|
||||
.setAsyncPay(asyncPayMode.isPresent())
|
||||
.setAsyncPayChannel(asyncPayMode.orElse(null))
|
||||
.setRefundableBalance(sumAmount);
|
||||
}
|
||||
@@ -123,7 +123,7 @@ public class PaymentBuilder {
|
||||
PayResult paymentResult;
|
||||
paymentResult = new PayResult();
|
||||
paymentResult.setPaymentId(payOrder.getId());
|
||||
paymentResult.setAsyncPayMode(payOrder.isAsyncPayMode());
|
||||
paymentResult.setAsyncPayMode(payOrder.isAsyncPay());
|
||||
paymentResult.setAsyncPayChannel(payOrder.getAsyncPayChannel());
|
||||
paymentResult.setStatus(payOrder.getStatus());
|
||||
|
||||
|
@@ -42,11 +42,11 @@ public class PayOrder extends MpBaseEntity {
|
||||
|
||||
/** 是否是异步支付 */
|
||||
@DbColumn(comment = "是否是异步支付")
|
||||
private boolean asyncPayMode;
|
||||
private boolean asyncPay;
|
||||
|
||||
/** 是否是组合支付 */
|
||||
@DbColumn(comment = "是否是组合支付")
|
||||
private boolean combinationPayMode;
|
||||
private boolean combinationPay;
|
||||
|
||||
/**
|
||||
* 异步支付渠道
|
||||
|
@@ -49,6 +49,9 @@ public class PayRefundOrder extends MpBaseEntity implements EntityBaseFunction<P
|
||||
/** 退款终端ip */
|
||||
private String clientIp;
|
||||
|
||||
/** 退款原因 */
|
||||
private String reason;
|
||||
|
||||
/** 退款时间 */
|
||||
private LocalDateTime refundTime;
|
||||
|
||||
|
@@ -0,0 +1,19 @@
|
||||
package cn.bootx.platform.daxpay.core.order.sync.convert;
|
||||
|
||||
import cn.bootx.platform.daxpay.core.order.sync.entity.PaySyncOrder;
|
||||
import cn.bootx.platform.daxpay.dto.order.sync.PaySyncOrderDto;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 支付同步记录同步
|
||||
* @author xxm
|
||||
* @since 2023/7/14
|
||||
*/
|
||||
@Mapper
|
||||
public interface PaySyncOrderConvert {
|
||||
PaySyncOrderConvert CONVERT = Mappers.getMapper(PaySyncOrderConvert.class);
|
||||
|
||||
PaySyncOrderDto convert(PaySyncOrder in);
|
||||
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package cn.bootx.platform.daxpay.core.order.sync.dao;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.daxpay.core.order.sync.entity.PaySyncOrder;
|
||||
import cn.bootx.platform.daxpay.dto.order.sync.PaySyncOrderDto;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2023/7/14
|
||||
*/
|
||||
@Slf4j
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class PaySyncOrderManager extends BaseManager<PaySyncOrderMapper, PaySyncOrder> {
|
||||
|
||||
public Page<PaySyncOrder> page(PageParam pageParam, PaySyncOrderDto param) {
|
||||
Page<PaySyncOrder> mpPage = MpUtil.getMpPage(pageParam, PaySyncOrder.class);
|
||||
return lambdaQuery().orderByDesc(MpIdEntity::getId)
|
||||
.like(Objects.nonNull(param.getPaymentId()), PaySyncOrder::getPaymentId, param.getPaymentId())
|
||||
.eq(Objects.nonNull(param.getChannel()), PaySyncOrder::getChannel, param.getChannel())
|
||||
.eq(Objects.nonNull(param.getStatus()), PaySyncOrder::getStatus, param.getStatus())
|
||||
.page(mpPage);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package cn.bootx.platform.daxpay.core.order.sync.dao;
|
||||
|
||||
import cn.bootx.platform.daxpay.core.order.sync.entity.PaySyncOrder;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 支付同步记录
|
||||
* @author xxm
|
||||
* @since 2023/7/14
|
||||
*/
|
||||
@Mapper
|
||||
public interface PaySyncOrderMapper extends BaseMapper<PaySyncOrder> {
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
package cn.bootx.platform.daxpay.core.order.sync.entity;
|
||||
|
||||
import cn.bootx.platform.common.core.function.EntityBaseFunction;
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.core.order.sync.convert.PaySyncOrderConvert;
|
||||
import cn.bootx.platform.daxpay.dto.order.sync.PaySyncOrderDto;
|
||||
import cn.bootx.table.modify.annotation.DbComment;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
import cn.bootx.table.modify.mysql.annotation.DbMySqlFieldType;
|
||||
import cn.bootx.table.modify.mysql.constants.MySqlFieldTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付同步订单
|
||||
* @author xxm
|
||||
* @since 2023/7/14
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@DbTable(comment = "支付同步订单")
|
||||
@Accessors(chain = true)
|
||||
@TableName("pay_sync_order")
|
||||
public class PaySyncOrder extends MpCreateEntity implements EntityBaseFunction<PaySyncOrderDto> {
|
||||
|
||||
/** 支付记录id */
|
||||
@DbComment("支付记录id")
|
||||
private Long paymentId;
|
||||
|
||||
|
||||
/**
|
||||
* 支付渠道
|
||||
* @see PayChannelEnum#getCode()
|
||||
*/
|
||||
@DbComment("支付渠道")
|
||||
private String channel;
|
||||
|
||||
/** 通知消息 */
|
||||
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
|
||||
@DbComment("通知消息")
|
||||
private String syncInfo;
|
||||
|
||||
/**
|
||||
* 同步状态
|
||||
* @see PaySyncStatusEnum
|
||||
*/
|
||||
@DbComment("同步状态")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 支付单如果状态不一致, 是否修复成功
|
||||
*/
|
||||
private boolean repairOrder;
|
||||
|
||||
@DbComment("错误消息")
|
||||
private String msg;
|
||||
|
||||
/** 同步时间 */
|
||||
@DbComment("同步时间")
|
||||
private LocalDateTime syncTime;
|
||||
|
||||
/**
|
||||
* 转换
|
||||
*/
|
||||
@Override
|
||||
public PaySyncOrderDto toDto() {
|
||||
return PaySyncOrderConvert.CONVERT.convert(this);
|
||||
}
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
package cn.bootx.platform.daxpay.core.order.sync.service;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
import cn.bootx.platform.common.core.rest.PageResult;
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.core.order.sync.dao.PaySyncOrderManager;
|
||||
import cn.bootx.platform.daxpay.core.order.sync.entity.PaySyncOrder;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.SyncResult;
|
||||
import cn.bootx.platform.daxpay.dto.order.sync.PaySyncOrderDto;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付同步记录
|
||||
* @author xxm
|
||||
* @since 2023/7/14
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PaySyncOrderService {
|
||||
private final PaySyncOrderManager orderManager;
|
||||
|
||||
/**
|
||||
* 记录同步记录
|
||||
*/
|
||||
@Transactional(propagation= Propagation.REQUIRES_NEW)
|
||||
public void saveRecord(SyncResult paySyncResult, PayOrder payment){
|
||||
PaySyncOrder paySyncOrder = new PaySyncOrder()
|
||||
.setPaymentId(payment.getId())
|
||||
.setChannel(payment.getAsyncPayChannel())
|
||||
.setSyncInfo(paySyncResult.getJson())
|
||||
.setStatus(paySyncResult.getSyncStatus())
|
||||
.setMsg(paySyncResult.getMsg())
|
||||
.setSyncTime(LocalDateTime.now());
|
||||
orderManager.save(paySyncOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*/
|
||||
public PageResult<PaySyncOrderDto> page(PageParam pageParam, PaySyncOrderDto param) {
|
||||
Page<PaySyncOrder> page = orderManager.page(pageParam, param);
|
||||
return MpUtil.convert2DtoPageResult(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询
|
||||
*/
|
||||
public PaySyncOrderDto findById(Long id) {
|
||||
return orderManager.findById(id).map(PaySyncOrder::toDto).orElseThrow(DataNotExistException::new);
|
||||
}
|
||||
}
|
@@ -75,7 +75,7 @@ public class PayService {
|
||||
payAssistService.initPayContext(payOrder, payParam);
|
||||
|
||||
// 异步支付且非第一次支付
|
||||
if (Objects.nonNull(payOrder) && payOrder.isAsyncPayMode()) {
|
||||
if (Objects.nonNull(payOrder) && payOrder.isAsyncPay()) {
|
||||
return this.paySyncNotFirst(payParam, payOrder);
|
||||
} else {
|
||||
// 第一次发起支付或同步支付
|
||||
|
@@ -3,6 +3,7 @@ package cn.bootx.platform.daxpay.core.payment.pay.strategy;
|
||||
import cn.bootx.platform.daxpay.code.AliPayCode;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.common.exception.ExceptionInfo;
|
||||
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
|
||||
import cn.bootx.platform.daxpay.core.channel.alipay.service.*;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException;
|
||||
@@ -106,8 +107,8 @@ public class AliPayStrategy extends AbsPayStrategy {
|
||||
*/
|
||||
@Override
|
||||
public void doAsyncSuccessHandler(Map<String, String> map) {
|
||||
String tradeNo = map.get(AliPayCode.TRADE_NO);
|
||||
aliPaymentService.updateAsyncSuccess(this.getOrder().getId(), this.getPayWayParam(), tradeNo);
|
||||
PaymentContextLocal.get().getAsyncPayInfo().setTradeNo( map.get(AliPayCode.TRADE_NO));
|
||||
aliPaymentService.updateAsyncSuccess(this.getOrder(), this.getPayWayParam().getAmount());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -11,8 +11,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
|
||||
|
||||
/**
|
||||
@@ -53,7 +51,7 @@ public class VoucherPayStrategy extends AbsPayStrategy {
|
||||
@Override
|
||||
public void doPayHandler() {
|
||||
VoucherRecord voucherRecord;
|
||||
if (this.getOrder().isAsyncPayMode()){
|
||||
if (this.getOrder().isAsyncPay()){
|
||||
voucherRecord = voucherPayService.freezeBalance(this.getPayWayParam().getAmount(), this.getOrder(), this.vouchers);
|
||||
} else {
|
||||
voucherRecord = voucherPayService.pay(this.getPayWayParam().getAmount(), this.getOrder(), this.vouchers);
|
||||
@@ -66,7 +64,7 @@ public class VoucherPayStrategy extends AbsPayStrategy {
|
||||
*/
|
||||
@Override
|
||||
public void doSuccessHandler() {
|
||||
if (this.getOrder().isAsyncPayMode()){
|
||||
if (this.getOrder().isAsyncPay()){
|
||||
voucherPayService.paySuccess(this.getOrder().getId());
|
||||
}
|
||||
voucherPaymentService.updateSuccess(this.getOrder().getId());
|
||||
|
@@ -82,7 +82,7 @@ public class WalletPayStrategy extends AbsPayStrategy {
|
||||
@Override
|
||||
public void doPayHandler() {
|
||||
// 异步支付方式时使用冻结方式
|
||||
if (this.getOrder().isAsyncPayMode()){
|
||||
if (this.getOrder().isAsyncPay()){
|
||||
walletPayService.freezeBalance(getPayWayParam().getAmount(), this.getOrder(), this.wallet);
|
||||
} else {
|
||||
walletPayService.pay(getPayWayParam().getAmount(), this.getOrder(), this.wallet);
|
||||
@@ -95,7 +95,7 @@ public class WalletPayStrategy extends AbsPayStrategy {
|
||||
*/
|
||||
@Override
|
||||
public void doSuccessHandler() {
|
||||
if (this.getOrder().isAsyncPayMode()){
|
||||
if (this.getOrder().isAsyncPay()){
|
||||
walletPayService.paySuccess(this.getOrder().getId());
|
||||
}
|
||||
walletPaymentService.updateSuccess(this.getOrder().getId());
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package cn.bootx.platform.daxpay.core.payment.refund.factory;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.core.payment.refund.func.AbsPayRefundStrategy;
|
||||
import cn.bootx.platform.daxpay.func.AbsPayRefundStrategy;
|
||||
import cn.bootx.platform.daxpay.core.payment.refund.strategy.*;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException;
|
||||
import cn.bootx.platform.daxpay.param.pay.RefundChannelParam;
|
||||
|
@@ -1,17 +0,0 @@
|
||||
package cn.bootx.platform.daxpay.core.payment.refund.func;
|
||||
|
||||
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 支付退款策略接口
|
||||
* @author xxm
|
||||
* @since 2023/7/5
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface PayRefundStrategyConsumer<T extends List<AbsPayRefundStrategy>, S extends PayOrder> {
|
||||
|
||||
void accept(T t, S s);
|
||||
|
||||
}
|
@@ -2,19 +2,27 @@ package cn.bootx.platform.daxpay.core.payment.refund.service;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.ValidationFailedException;
|
||||
import cn.bootx.platform.common.core.util.CollUtil;
|
||||
import cn.bootx.platform.daxpay.code.PayRefundStatusEnum;
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import cn.bootx.platform.daxpay.common.context.AsyncRefundLocal;
|
||||
import cn.bootx.platform.daxpay.common.context.NoticeLocal;
|
||||
import cn.bootx.platform.daxpay.common.context.PlatformLocal;
|
||||
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.dao.PayOrderManager;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.core.order.refund.dao.PayRefundOrderManager;
|
||||
import cn.bootx.platform.daxpay.core.order.refund.entity.PayRefundOrder;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.param.pay.RefundChannelParam;
|
||||
import cn.bootx.platform.daxpay.param.pay.RefundParam;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -30,14 +38,14 @@ import java.util.Objects;
|
||||
public class PayRefundAssistService {
|
||||
private final PayOrderManager payOrderManager;
|
||||
|
||||
private final PayRefundOrderManager payRefundOrderManager;
|
||||
|
||||
/**
|
||||
* 初始化上下文
|
||||
*/
|
||||
public void initRefundContext(RefundParam param, PayOrder payOrder){
|
||||
public void initRefundContext(RefundParam param){
|
||||
// 初始化通知相关上下文
|
||||
this.initNotice(param);
|
||||
// 初始化请求相关上下文
|
||||
this.initRequest(param);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,20 +63,16 @@ public class PayRefundAssistService {
|
||||
}
|
||||
}
|
||||
|
||||
public void initRequest(RefundParam param){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据退款参数获取支付订单, 并进行检查
|
||||
*/
|
||||
public PayOrder getPayOrderAndCheckByRefundParam(RefundParam param, boolean simple){
|
||||
|
||||
if (!param.isRefundAll()){
|
||||
if (CollUtil.isEmpty(param.getRefundChannels())){
|
||||
if (!param.isRefundAll()) {
|
||||
if (CollUtil.isEmpty(param.getRefundChannels())) {
|
||||
throw new ValidationFailedException("退款通道参数不能为空");
|
||||
}
|
||||
if (Objects.isNull(param.getRefundNo())){
|
||||
if (Objects.isNull(param.getRefundNo())) {
|
||||
throw new ValidationFailedException("部分退款时退款单号必传");
|
||||
}
|
||||
}
|
||||
@@ -84,7 +88,7 @@ public class PayRefundAssistService {
|
||||
}
|
||||
|
||||
// 简单退款校验
|
||||
if (payOrder.isCombinationPayMode() != simple){
|
||||
if (payOrder.isCombinationPay() != simple){
|
||||
throw new PayFailureException("组合支付不可以使用简单退款方式");
|
||||
}
|
||||
// 状态判断, 支付中/失败/取消等不能进行退款
|
||||
@@ -99,4 +103,31 @@ public class PayRefundAssistService {
|
||||
}
|
||||
return payOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存退款记录 成不成功都记录
|
||||
*/
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void saveRefundOrder(RefundParam refundParam, PayOrder payOrder){
|
||||
AsyncRefundLocal asyncRefundInfo = PaymentContextLocal.get().getAsyncRefundInfo();
|
||||
// 退款金额
|
||||
Integer amount = refundParam.getRefundChannels()
|
||||
.stream()
|
||||
.map(RefundChannelParam::getAmount)
|
||||
.reduce(0, Integer::sum);
|
||||
|
||||
PayRefundOrder refundOrder = new PayRefundOrder()
|
||||
.setRefundRequestNo(asyncRefundInfo.getRefundNo())
|
||||
.setAmount(amount)
|
||||
.setClientIp(refundParam.getClientIp())
|
||||
.setPaymentId(payOrder.getId())
|
||||
.setBusinessNo(payOrder.getBusinessNo())
|
||||
.setRefundTime(LocalDateTime.now())
|
||||
.setTitle(payOrder.getTitle())
|
||||
.setErrorMsg(asyncRefundInfo.getErrorMsg())
|
||||
.setErrorCode(asyncRefundInfo.getErrorCode())
|
||||
.setStatus(Objects.isNull(asyncRefundInfo.getErrorCode()) ? PayRefundStatusEnum.SUCCESS.getCode()
|
||||
: PayRefundStatusEnum.FAIL.getCode());
|
||||
payRefundOrderManager.save(refundOrder);
|
||||
}
|
||||
}
|
||||
|
@@ -5,8 +5,7 @@ import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.dao.PayOrderManager;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.core.payment.refund.factory.PayRefundStrategyFactory;
|
||||
import cn.bootx.platform.daxpay.core.payment.refund.func.AbsPayRefundStrategy;
|
||||
import cn.bootx.platform.daxpay.core.payment.refund.func.PayRefundStrategyConsumer;
|
||||
import cn.bootx.platform.daxpay.func.AbsPayRefundStrategy;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException;
|
||||
import cn.bootx.platform.daxpay.param.pay.RefundChannelParam;
|
||||
import cn.bootx.platform.daxpay.param.pay.RefundParam;
|
||||
@@ -21,8 +20,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -73,7 +70,7 @@ public class PayRefundService {
|
||||
ValidationUtil.validateParam(param);
|
||||
PayOrder payOrder = payRefundAssistService.getPayOrderAndCheckByRefundParam(param, simple);
|
||||
// 退款上下文初始化
|
||||
payRefundAssistService.initRefundContext(param,payOrder);
|
||||
payRefundAssistService.initRefundContext(param);
|
||||
// 是否全部退款
|
||||
if (param.isRefundAll()){
|
||||
// 全部退款根据支付订单的退款信息构造退款参数
|
||||
@@ -90,67 +87,42 @@ public class PayRefundService {
|
||||
/**
|
||||
* 分支付通道进行退款
|
||||
*/
|
||||
public RefundResult refundByChannel(RefundParam param,PayOrder order){
|
||||
List<RefundChannelParam> refundChannels = param.getRefundChannels();
|
||||
public RefundResult refundByChannel(RefundParam refundParam, PayOrder payOrder){
|
||||
List<RefundChannelParam> refundChannels = refundParam.getRefundChannels();
|
||||
// 1.获取退款参数方式,通过工厂生成对应的策略组
|
||||
List<AbsPayRefundStrategy> payRefundStrategies = PayRefundStrategyFactory.create(refundChannels);
|
||||
if (CollectionUtil.isEmpty(payRefundStrategies)) {
|
||||
throw new PayUnsupportedMethodException();
|
||||
}
|
||||
|
||||
// 2.初始化支付的参数
|
||||
for (AbsPayRefundStrategy refundStrategy : payRefundStrategies) {
|
||||
refundStrategy.initPayParam(order, param);
|
||||
}
|
||||
// 2.初始化退款策略的参数
|
||||
payRefundStrategies.forEach(refundStrategy -> refundStrategy.initPayParam(payOrder, refundParam));
|
||||
|
||||
// 3.支付前准备
|
||||
this.doHandler(refundChannels, order, payRefundStrategies, AbsPayRefundStrategy::doBeforeRefundHandler, null);
|
||||
|
||||
// 4.执行退款
|
||||
this.doHandler(refundChannels,order, payRefundStrategies, AbsPayRefundStrategy::doRefundHandler, (strategyList, payOrder) -> {
|
||||
this.paymentHandler(payOrder, refundChannels);
|
||||
});
|
||||
return new RefundResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理方法
|
||||
* @param channelParams 退款方式参数
|
||||
* @param payOrder 支付记录
|
||||
* @param strategyList 退款策略
|
||||
* @param refundStrategy 执行方法
|
||||
* @param successCallback 成功操作
|
||||
*/
|
||||
private void doHandler( List<RefundChannelParam> channelParams,
|
||||
PayOrder payOrder,
|
||||
List<AbsPayRefundStrategy> strategyList,
|
||||
Consumer<AbsPayRefundStrategy> refundStrategy,
|
||||
PayRefundStrategyConsumer<List<AbsPayRefundStrategy>, PayOrder> successCallback) {
|
||||
try {
|
||||
// 执行策略操作,如退款前/退款时
|
||||
// 等同strategyList.forEach(payMethod.accept(PaymentStrategy))
|
||||
strategyList.forEach(refundStrategy);
|
||||
// 3.退款前准备
|
||||
payRefundStrategies.forEach(AbsPayRefundStrategy::doBeforeRefundHandler);
|
||||
|
||||
// 执行操作成功的处
|
||||
Optional.ofNullable(successCallback).ifPresent(fun -> fun.accept(strategyList, payOrder));
|
||||
// 4.执行退款策略
|
||||
payRefundStrategies.forEach(AbsPayRefundStrategy::doRefundHandler);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// 记录退款失败的记录
|
||||
Integer i = channelParams.stream()
|
||||
.map(RefundChannelParam::getAmount)
|
||||
.reduce(0,Integer::sum);
|
||||
// TODO 保存
|
||||
// SpringUtil.getBean(this.getClass()).saveRefund(payOrder, amount, channelParams);
|
||||
payRefundAssistService.saveRefundOrder(refundParam,payOrder);
|
||||
throw e;
|
||||
}
|
||||
|
||||
// 5.支付成功后处理
|
||||
this.paymentHandler(refundParam, payOrder);
|
||||
|
||||
// 返回结果
|
||||
return new RefundResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付订单处理
|
||||
*/
|
||||
private void paymentHandler(PayOrder payOrder, List<RefundChannelParam> refundModeParams) {
|
||||
Integer amount = refundModeParams.stream()
|
||||
private void paymentHandler(RefundParam refundParam,PayOrder payOrder) {
|
||||
Integer amount = refundParam.getRefundChannels().stream()
|
||||
.map(RefundChannelParam::getAmount)
|
||||
.reduce(0, Integer::sum);
|
||||
// 剩余可退款余额
|
||||
@@ -165,7 +137,6 @@ public class PayRefundService {
|
||||
}
|
||||
payOrder.setRefundableBalance(refundableBalance);
|
||||
payOrderManager.updateById(payOrder);
|
||||
// TODO 记录退款成功的记录
|
||||
// SpringUtil.getBean(this.getClass()).saveRefund(payOrder, amount, refundModeParams);
|
||||
payRefundAssistService.saveRefundOrder(refundParam,payOrder);
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayOrderService;
|
||||
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayRefundService;
|
||||
import cn.bootx.platform.daxpay.core.channel.alipay.service.AlipayConfigService;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.core.payment.refund.func.AbsPayRefundStrategy;
|
||||
import cn.bootx.platform.daxpay.func.AbsPayRefundStrategy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@@ -3,7 +3,7 @@ package cn.bootx.platform.daxpay.core.payment.refund.strategy;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.core.channel.cash.service.CashService;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.core.payment.refund.func.AbsPayRefundStrategy;
|
||||
import cn.bootx.platform.daxpay.func.AbsPayRefundStrategy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package cn.bootx.platform.daxpay.core.payment.refund.strategy;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.core.payment.refund.func.AbsPayRefundStrategy;
|
||||
import cn.bootx.platform.daxpay.func.AbsPayRefundStrategy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@@ -4,7 +4,7 @@ import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPayService;
|
||||
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPaymentService;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.core.payment.refund.func.AbsPayRefundStrategy;
|
||||
import cn.bootx.platform.daxpay.func.AbsPayRefundStrategy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@@ -4,7 +4,7 @@ import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletPayService;
|
||||
import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletPaymentService;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.core.payment.refund.func.AbsPayRefundStrategy;
|
||||
import cn.bootx.platform.daxpay.func.AbsPayRefundStrategy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@@ -6,7 +6,7 @@ import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPayConfigServi
|
||||
import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPayOrderService;
|
||||
import cn.bootx.platform.daxpay.core.channel.wechat.service.WechatRefundService;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.core.payment.refund.func.AbsPayRefundStrategy;
|
||||
import cn.bootx.platform.daxpay.func.AbsPayRefundStrategy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@@ -0,0 +1,20 @@
|
||||
package cn.bootx.platform.daxpay.core.payment.repair.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 支付订单修复参数
|
||||
* @author xxm
|
||||
* @since 2023/12/27
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PayOrderRepairParam {
|
||||
|
||||
@Schema(description = "支付ID")
|
||||
private Long paymentId;
|
||||
|
||||
|
||||
}
|
@@ -1,16 +1,21 @@
|
||||
package cn.bootx.platform.daxpay.core.payment.sync.service;
|
||||
package cn.bootx.platform.daxpay.core.payment.repair.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 退款状态同步服务
|
||||
* 支付修复服务
|
||||
* @author xxm
|
||||
* @since 2023/12/18
|
||||
* @since 2023/12/27
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RefundSyncService {
|
||||
public class PayRepairService {
|
||||
|
||||
public void repair(){
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
package cn.bootx.platform.daxpay.core.payment.repair.strategy;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayOrderService;
|
||||
import cn.bootx.platform.daxpay.func.AbsPayRepairStrategy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
|
||||
|
||||
/**
|
||||
* 支付宝支付单修复策略
|
||||
* @author xxm
|
||||
* @since 2023/12/27
|
||||
*/
|
||||
@Slf4j
|
||||
@Scope(SCOPE_PROTOTYPE)
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AliPayRepairStrategy extends AbsPayRepairStrategy {
|
||||
private final AliPayOrderService orderService;
|
||||
@Override
|
||||
public PayChannelEnum getType() {
|
||||
return PayChannelEnum.ALI;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付成功处理
|
||||
*/
|
||||
@Override
|
||||
public void successHandler() {
|
||||
orderService.updateAsyncSuccess(this.getOrder(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消支付
|
||||
*/
|
||||
@Override
|
||||
public void closeHandler() {
|
||||
orderService.updateClose(this.getOrder().getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款
|
||||
*/
|
||||
@Override
|
||||
public void refundHandler() {
|
||||
orderService.updatePayRefund(this.getOrder().getId(), 0);
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@ package cn.bootx.platform.daxpay.core.payment.sync.factory;
|
||||
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.func.AbsPaySyncStrategy;
|
||||
import cn.bootx.platform.daxpay.func.AbsPaySyncStrategy;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.strategy.AliPaySyncStrategy;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.strategy.WeChatPaySyncStrategy;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException;
|
||||
|
@@ -1,28 +1,28 @@
|
||||
package cn.bootx.platform.daxpay.core.payment.sync.result;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatus;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.bootx.platform.daxpay.code.PaySyncStatus.NOT_SYNC;
|
||||
import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.NOT_SYNC;
|
||||
|
||||
/**
|
||||
* 支付网关通知状态对象
|
||||
* 支付网关同步状态记录对象
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2021/4/21
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PaySyncResult {
|
||||
public class SyncResult {
|
||||
|
||||
/**
|
||||
* 支付网关同步状态
|
||||
* @see PaySyncStatus#NOT_SYNC
|
||||
* @see PaySyncStatusEnum#NOT_SYNC
|
||||
*/
|
||||
private String paySyncStatus = NOT_SYNC;
|
||||
private String syncStatus = NOT_SYNC.getCode();
|
||||
|
||||
/** 网关返回参数(会被用到的参数) */
|
||||
private Map<String, String> map;
|
@@ -1,10 +1,26 @@
|
||||
package cn.bootx.platform.daxpay.core.payment.sync.service;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.BizException;
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.dao.PayOrderManager;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.core.order.sync.service.PaySyncOrderService;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.factory.PaySyncStrategyFactory;
|
||||
import cn.bootx.platform.daxpay.func.AbsPaySyncStrategy;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.SyncResult;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.func.AbsPayStrategy;
|
||||
import cn.bootx.platform.daxpay.param.pay.PaySyncParam;
|
||||
import cn.bootx.platform.daxpay.result.pay.PaySyncResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 支付同步服务
|
||||
* @author xxm
|
||||
@@ -14,8 +30,146 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PaySyncService {
|
||||
private final PayOrderManager payOrderManager;
|
||||
|
||||
public void sync(PayOrder payment) {
|
||||
private final PaySyncOrderService syncOrderService;
|
||||
|
||||
/**
|
||||
* 支付同步
|
||||
*/
|
||||
public PaySyncResult sync(PaySyncParam param) {
|
||||
PayOrder payOrder = null;
|
||||
if (Objects.nonNull(param.getPaymentId())){
|
||||
payOrder = payOrderManager.findById(param.getPaymentId())
|
||||
.orElseThrow(() -> new PayFailureException("未查询到支付订单"));
|
||||
}
|
||||
if (Objects.isNull(payOrder)){
|
||||
payOrder = payOrderManager.findByBusinessNo(param.getBusinessNo())
|
||||
.orElseThrow(() -> new PayFailureException("未查询到支付订单"));
|
||||
}
|
||||
// 如果不是异步支付, 直接返回不需要同步的结果
|
||||
if (!payOrder.isAsyncPay()){
|
||||
return new PaySyncResult().setSuccess(true).setStatus(PaySyncStatusEnum.NOT_SYNC.getCode());
|
||||
}
|
||||
|
||||
// 执行逻辑
|
||||
return this.syncPayOrder(payOrder);
|
||||
}
|
||||
/**
|
||||
* 同步支付状态 传入 payment 对象
|
||||
*/
|
||||
public PaySyncResult syncPayOrder(PayOrder order) {
|
||||
// 获取同步策略类
|
||||
AbsPaySyncStrategy syncPayStrategy = PaySyncStrategyFactory.create(order.getAsyncPayChannel());
|
||||
syncPayStrategy.initPayParam(order);
|
||||
// 同步支付状态
|
||||
SyncResult syncResult = syncPayStrategy.doSyncPayStatusHandler();
|
||||
// 根据同步记录对支付单进行处理处理
|
||||
this.resultHandler(syncResult,order);
|
||||
|
||||
// 记录同步的结果
|
||||
syncOrderService.saveRecord(syncResult,order);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据同步的结果对支付单进行处理
|
||||
*/
|
||||
public void resultHandler(SyncResult syncResult, PayOrder payment){
|
||||
PaySyncStatusEnum syncStatusEnum = PaySyncStatusEnum.getByCode(syncResult.getSyncStatus());
|
||||
// 对同步结果处理
|
||||
switch (syncStatusEnum) {
|
||||
// 支付成功 支付宝退款时也是支付成功状态, 除非支付完成
|
||||
case PaySyncStatusEnum.PAY_SUCCESS: {
|
||||
this.paymentSuccess(payment, syncPayStrategy, syncResult);
|
||||
break;
|
||||
}
|
||||
// 待付款/ 支付中
|
||||
case PaySyncStatusEnum.PAY_WAIT: {
|
||||
log.info("依然是付款状态");
|
||||
break;
|
||||
}
|
||||
// 订单已经关闭超时关闭 和 网关没找到记录, 支付宝退款完成也是这个状态
|
||||
case PaySyncStatusEnum.CLOSED:
|
||||
case PaySyncStatusEnum.NOT_FOUND: {
|
||||
// 判断下是否超时, 同时payment 变更为取消支付
|
||||
this.paymentCancel(payment, paymentStrategyList);
|
||||
break;
|
||||
}
|
||||
// 交易退款 支付宝没这个状态
|
||||
case PaySyncStatusEnum.REFUND: {
|
||||
this.paymentRefund(payment, syncPayStrategy, syncResult);
|
||||
break;
|
||||
}
|
||||
// 调用出错
|
||||
case PaySyncStatusEnum.FAIL: {
|
||||
// 不进行处理
|
||||
log.warn("支付状态同步接口调用出错");
|
||||
break;
|
||||
}
|
||||
case PaySyncStatusEnum.NOT_SYNC:
|
||||
default: {
|
||||
throw new BizException("代码有问题");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* payment 变更为已支付
|
||||
*/
|
||||
private void paymentSuccess(PayOrder payment, AbsPayStrategy syncPayStrategy, SyncResult syncResult) {
|
||||
|
||||
// 已支付不在重复处理
|
||||
if (Objects.equals(payment.getStatus(), PayStatusEnum.SUCCESS.getCode())) {
|
||||
return;
|
||||
}
|
||||
// 退款的不处理
|
||||
if (Objects.equals(payment.getStatus(), PayStatusEnum.PARTIAL_REFUND.getCode())
|
||||
|| Objects.equals(payment.getStatus(), PayStatusEnum.REFUNDED.getCode())) {
|
||||
return;
|
||||
}
|
||||
// 修改payment支付状态为成功
|
||||
syncPayStrategy.doAsyncSuccessHandler(syncResult.getMap());
|
||||
payment.setStatus(PayStatusEnum.SUCCESS.getCode());
|
||||
payment.setPayTime(LocalDateTime.now());
|
||||
paymentService.updateById(payment);
|
||||
|
||||
// 发送成功事件
|
||||
eventSender.sendPayComplete(PayEventBuilder.buildPayComplete(payment));
|
||||
}
|
||||
|
||||
/**
|
||||
* payment 变更为取消支付
|
||||
*/
|
||||
private void paymentCancel(Payment payment, List<AbsPayStrategy> absPayStrategies) {
|
||||
try {
|
||||
// 已关闭的不再进行关闭
|
||||
if (Objects.equals(payment.getPayStatus(), TRADE_CANCEL)) {
|
||||
return;
|
||||
}
|
||||
// 修改payment支付状态为取消, 退款状态则不进行更新
|
||||
if (Objects.equals(payment.getPayStatus(), TRADE_REFUNDED)
|
||||
|| Objects.equals(payment.getPayStatus(), TRADE_REFUNDING)) {
|
||||
return;
|
||||
}
|
||||
payment.setPayStatus(TRADE_CANCEL);
|
||||
// 执行策略的关闭方法
|
||||
absPayStrategies.forEach(AbsPayStrategy::doCloseHandler);
|
||||
paymentService.updateById(payment);
|
||||
// 发送事件
|
||||
eventSender.sendPayCancel(PayEventBuilder.buildPayCancel(payment));
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("支付状态同步后关闭支付单报错了", e);
|
||||
throw new PayFailureException("支付状态同步后关闭支付单报错了");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* payment 退款处理 TODO 需要考虑退款详情的合并处理
|
||||
*/
|
||||
private void paymentRefund(Payment payment, AbsPayStrategy syncPayStrategy, PaySyncResult paySyncResult) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -4,8 +4,8 @@ package cn.bootx.platform.daxpay.core.payment.sync.strategy;
|
||||
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
|
||||
import cn.bootx.platform.daxpay.core.channel.alipay.service.AlipayConfigService;
|
||||
import cn.bootx.platform.daxpay.core.channel.alipay.service.AlipaySyncService;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.func.AbsPaySyncStrategy;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.PaySyncResult;
|
||||
import cn.bootx.platform.daxpay.func.AbsPaySyncStrategy;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.SyncResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -30,7 +30,7 @@ public class AliPaySyncStrategy extends AbsPaySyncStrategy {
|
||||
* 异步支付单与支付网关进行状态比对
|
||||
*/
|
||||
@Override
|
||||
public PaySyncResult doSyncPayStatusHandler() {
|
||||
public SyncResult doSyncPayStatusHandler() {
|
||||
this.initAlipayConfig();
|
||||
return alipaySyncService.syncPayStatus(this.getOrder().getId());
|
||||
}
|
||||
|
@@ -3,8 +3,8 @@ package cn.bootx.platform.daxpay.core.payment.sync.strategy;
|
||||
import cn.bootx.platform.daxpay.core.channel.wechat.dao.WeChatPayConfigManager;
|
||||
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayConfig;
|
||||
import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPaySyncService;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.func.AbsPaySyncStrategy;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.PaySyncResult;
|
||||
import cn.bootx.platform.daxpay.func.AbsPaySyncStrategy;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.SyncResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -31,7 +31,7 @@ public class WeChatPaySyncStrategy extends AbsPaySyncStrategy {
|
||||
* 异步支付单与支付网关进行状态比对
|
||||
*/
|
||||
@Override
|
||||
public PaySyncResult doSyncPayStatusHandler() {
|
||||
public SyncResult doSyncPayStatusHandler() {
|
||||
// 检查并获取微信支付配置
|
||||
this.initWeChatPayConfig();
|
||||
return weChatPaySyncService.syncPayStatus(this.getOrder().getId(), this.weChatPayConfig);
|
||||
|
@@ -0,0 +1,52 @@
|
||||
package cn.bootx.platform.daxpay.dto.order.sync;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.dto.BaseDto;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付同步记录
|
||||
* @author xxm
|
||||
* @since 2023/7/14
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "支付同步订单")
|
||||
public class PaySyncOrderDto extends BaseDto {
|
||||
|
||||
/** 支付记录id */
|
||||
@Schema(description = "支付记录id")
|
||||
private Long paymentId;
|
||||
|
||||
/**
|
||||
* 支付渠道
|
||||
* @see PayChannelEnum#getCode()
|
||||
*/
|
||||
@Schema(description = "支付渠道")
|
||||
private String channel;
|
||||
|
||||
/** 通知消息 */
|
||||
@Schema(description = "通知消息")
|
||||
private String syncInfo;
|
||||
|
||||
/**
|
||||
* 同步状态
|
||||
* @see PaySyncStatusEnum
|
||||
*/
|
||||
@Schema(description = "同步状态")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "错误消息")
|
||||
private String msg;
|
||||
|
||||
/** 同步时间 */
|
||||
@Schema(description = "同步时间")
|
||||
private LocalDateTime syncTime;
|
||||
}
|
@@ -22,7 +22,7 @@ import java.util.Map;
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public abstract class AbsPayCallbackStrategy {
|
||||
public abstract class AbsPayCallbackStrategy implements PayStrategy {
|
||||
|
||||
protected static final ThreadLocal<Map<String, String>> PARAMS = new TransmittableThreadLocal<>();
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package cn.bootx.platform.daxpay.core.payment.refund.func;
|
||||
package cn.bootx.platform.daxpay.func;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.common.exception.ExceptionInfo;
|
||||
@@ -16,7 +16,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class AbsPayRefundStrategy {
|
||||
public abstract class AbsPayRefundStrategy implements PayStrategy{
|
||||
|
||||
/** 支付对象 */
|
||||
private PayOrder order = null;
|
@@ -0,0 +1,55 @@
|
||||
package cn.bootx.platform.daxpay.func;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.core.payment.repair.param.PayOrderRepairParam;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 支付订单修复策略
|
||||
* @author xxm
|
||||
* @since 2023/12/27
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class AbsPayRepairStrategy {
|
||||
|
||||
|
||||
/** 支付对象 */
|
||||
private PayOrder order = null;
|
||||
|
||||
/** 支付对象 */
|
||||
private PayOrderRepairParam repairParam = null;
|
||||
|
||||
|
||||
/**
|
||||
* 初始化修复参数
|
||||
*/
|
||||
public void initRepairParam(PayOrder order,PayOrderRepairParam repairParam){
|
||||
this.order = order;
|
||||
this.repairParam = repairParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* 策略标识
|
||||
* @see PayChannelEnum
|
||||
*/
|
||||
public abstract PayChannelEnum getType();
|
||||
|
||||
/**
|
||||
* 支付成功处理
|
||||
*/
|
||||
public abstract void successHandler();
|
||||
|
||||
/**
|
||||
* 取消支付
|
||||
*/
|
||||
public abstract void closeHandler();
|
||||
|
||||
/**
|
||||
* 退款
|
||||
*/
|
||||
public abstract void refundHandler();
|
||||
|
||||
}
|
@@ -18,7 +18,7 @@ import java.util.Map;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class AbsPayStrategy {
|
||||
public abstract class AbsPayStrategy implements PayStrategy{
|
||||
|
||||
|
||||
/** 支付对象 */
|
||||
@@ -31,7 +31,7 @@ public abstract class AbsPayStrategy {
|
||||
private PayWayParam payWayParam = null;
|
||||
|
||||
/**
|
||||
* 策略标示
|
||||
* 策略标识
|
||||
* @see PayChannelEnum
|
||||
*/
|
||||
public abstract PayChannelEnum getType();
|
||||
@@ -71,12 +71,14 @@ public abstract class AbsPayStrategy {
|
||||
/**
|
||||
* 异步支付成功的处理方式
|
||||
*/
|
||||
@Deprecated
|
||||
public void doAsyncSuccessHandler(Map<String, String> map) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步支付失败的处理方式, 默认使用支付失败的处理方式 同步支付方式调用时同 this#doErrorHandler
|
||||
*/
|
||||
@Deprecated
|
||||
public void doAsyncErrorHandler(ExceptionInfo exceptionInfo) {
|
||||
this.doErrorHandler(exceptionInfo);
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
package cn.bootx.platform.daxpay.core.payment.sync.func;
|
||||
package cn.bootx.platform.daxpay.func;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.PaySyncResult;
|
||||
import cn.bootx.platform.daxpay.core.payment.sync.result.SyncResult;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@@ -12,7 +13,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class AbsPaySyncStrategy {
|
||||
public abstract class AbsPaySyncStrategy implements PayStrategy{
|
||||
|
||||
/** 支付对象 */
|
||||
private PayOrder order = null;
|
||||
@@ -27,8 +28,8 @@ public abstract class AbsPaySyncStrategy {
|
||||
|
||||
/**
|
||||
* 异步支付单与支付网关进行状态比对
|
||||
* @see cn.bootx.platform.daxpay.code.PaySyncStatus
|
||||
* @see PaySyncStatusEnum
|
||||
*/
|
||||
public abstract PaySyncResult doSyncPayStatusHandler();
|
||||
public abstract SyncResult doSyncPayStatusHandler();
|
||||
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
package cn.bootx.platform.daxpay.func;
|
||||
|
||||
/**
|
||||
* 支付相关策略标识接口
|
||||
* @author xxm
|
||||
* @since 2023/12/27
|
||||
*/
|
||||
public interface PayStrategy {
|
||||
}
|
@@ -5,14 +5,19 @@ import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 支付策略接口
|
||||
* 支付策略消费者接口
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2020/12/9
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface PayStrategyConsumer<T extends List<AbsPayStrategy>, S extends PayOrder> {
|
||||
public interface PayStrategyConsumer<T extends List<? extends PayStrategy>, S extends PayOrder> {
|
||||
|
||||
/**
|
||||
* 消费者接口
|
||||
* @param t 策略结论
|
||||
* @param s
|
||||
*/
|
||||
void accept(T t, S s);
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user