mirror of
https://gitee.com/dromara/dax-pay.git
synced 2025-09-03 19:16:21 +00:00
feat 微信支付退款同步和一些订单记录的数据填充
This commit is contained in:
@@ -34,8 +34,8 @@ public class PayRepairRecordController {
|
||||
|
||||
@Operation(summary = "查询单条")
|
||||
@GetMapping("/findById")
|
||||
public ResResult<PayRepairRecordDto> findById(Long paymentId){
|
||||
return Res.ok(service.findById(paymentId));
|
||||
public ResResult<PayRepairRecordDto> findById(Long id){
|
||||
return Res.ok(service.findById(id));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -79,6 +79,9 @@ public interface AliPayCode {
|
||||
/** 退款成功 */
|
||||
String REFUND_SUCCESS = "REFUND_SUCCESS";
|
||||
|
||||
// 参数
|
||||
/** 返回退款时间 */
|
||||
String GMT_REFUND_PAY = "gmt_refund_pay";
|
||||
|
||||
// 错误提示
|
||||
/** 交易不存在 */
|
||||
|
@@ -66,23 +66,32 @@ public interface WeChatPayCode {
|
||||
/** 交易状态 */
|
||||
String TRADE_STATE = "trade_state";
|
||||
|
||||
// 回调参数
|
||||
/** 支付金额 */
|
||||
String TOTAL_FEE = "total_fee";
|
||||
|
||||
/** 微信退款单号 */
|
||||
String REFUND_ID = "refund_id";
|
||||
String CALLBACK_REFUND_ID = "refund_id";
|
||||
|
||||
/** 商户退款单号 */
|
||||
String OUT_REFUND_NO = "out_refund_no";
|
||||
String CALLBACK_OUT_REFUND_NO = "out_refund_no";
|
||||
|
||||
/** 退款状态 */
|
||||
String REFUND_STATUS = "refund_status";
|
||||
String CALLBACK_REFUND_STATUS = "refund_status";
|
||||
|
||||
/** 申请退款金额 */
|
||||
String REFUND_FEE = "refund_fee";
|
||||
String CALLBACK_REFUND_FEE = "refund_fee";
|
||||
|
||||
/** 退款成功时间 yyyyMMddHHmmss */
|
||||
String SUCCESS_TIME = "success_time";
|
||||
String CALLBACK_SUCCESS_TIME = "success_time";
|
||||
|
||||
// 退款信息查询参数
|
||||
/** 退款成功时间 yyyy-MM-dd HH:mm:ss */
|
||||
String REFUND_SUCCESS_TIME = "refund_success_time_0";
|
||||
/** 网关退款订单号 */
|
||||
String REFUND_ID = "refund_id_0";
|
||||
/** 退款成状态 */
|
||||
String REFUND_STATUS = "refund_status_0";
|
||||
|
||||
/** 当前返回退款笔数 */
|
||||
String REFUND_COUNT = "refund_count";
|
||||
@@ -116,7 +125,7 @@ public interface WeChatPayCode {
|
||||
String PAY_USERPAYING = "USERPAYING";
|
||||
|
||||
/** 退款成功 */
|
||||
String REFUND_USERPAYING = "SUCCESS";
|
||||
String REFUND_SUCCESS = "SUCCESS";
|
||||
|
||||
/** 退款异常 */
|
||||
String REFUND_CHANGE = "CHANGE";
|
||||
@@ -124,6 +133,9 @@ public interface WeChatPayCode {
|
||||
/** 退款关闭 */
|
||||
String REFUND_REFUNDCLOSE = "REFUNDCLOSE";
|
||||
|
||||
/** 退款处理中 */
|
||||
String REFUND_PROCESSING = "PROCESSING";
|
||||
|
||||
/** 支付失败(刷卡支付) */
|
||||
String TRADE_PAYERROR = "PAYERROR";
|
||||
|
||||
|
@@ -14,13 +14,5 @@ import java.time.LocalDateTime;
|
||||
@Accessors(chain = true)
|
||||
public class PaySyncLocal {
|
||||
|
||||
/**
|
||||
* 第三方支付网关生成的订单号, 用与将记录关联起来
|
||||
* 1. 如付款码支付直接成功时会出现
|
||||
*/
|
||||
private String gatewayOrderNo;
|
||||
|
||||
/** 支付完成时间(通常用于接收异步支付返回的时间) */
|
||||
private LocalDateTime payTime;
|
||||
|
||||
}
|
||||
|
@@ -49,9 +49,8 @@ public class AliPayRefundService {
|
||||
}
|
||||
// 接口返回fund_change=Y为退款成功,fund_change=N或无此字段值返回时需通过退款查询接口进一步确认退款状态
|
||||
if (response.getFundChange().equals("Y")){
|
||||
// TODO 测试退款同步
|
||||
// refundInfo.setStatus(PayRefundStatusEnum.SUCCESS)
|
||||
// .setGatewayOrderNo(response.getTradeNo());
|
||||
refundInfo.setStatus(PayRefundStatusEnum.SUCCESS)
|
||||
.setGatewayOrderNo(response.getTradeNo());
|
||||
}
|
||||
refundInfo.setStatus(PayRefundStatusEnum.PROGRESS)
|
||||
.setGatewayOrderNo(response.getTradeNo());
|
||||
|
@@ -4,6 +4,7 @@ import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
|
||||
import cn.bootx.platform.daxpay.code.PayRefundSyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.service.code.AliPayCode;
|
||||
import cn.bootx.platform.daxpay.service.common.context.PaySyncLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.refund.entity.PayRefundOrder;
|
||||
@@ -21,8 +22,11 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.bootx.platform.daxpay.service.code.AliPayCode.GMT_REFUND_PAY;
|
||||
|
||||
/**
|
||||
* 支付宝同步
|
||||
*
|
||||
@@ -34,7 +38,7 @@ import java.util.Objects;
|
||||
@RequiredArgsConstructor
|
||||
public class AliPaySyncService {
|
||||
/**
|
||||
* 与支付宝网关同步状态, 退款状态会
|
||||
* 与支付宝网关同步状态, 退款状态有
|
||||
* 1 远程支付成功
|
||||
* 2 交易创建,等待买家付款
|
||||
* 3 超时关闭
|
||||
@@ -42,6 +46,7 @@ public class AliPaySyncService {
|
||||
* 5 查询失败
|
||||
*/
|
||||
public PayGatewaySyncResult syncPayStatus(PayOrder payOrder) {
|
||||
PaySyncLocal paySyncLocal = PaymentContextLocal.get().getPaySyncInfo();
|
||||
PayGatewaySyncResult syncResult = new PayGatewaySyncResult().setSyncStatus(PaySyncStatusEnum.FAIL);
|
||||
// 查询
|
||||
try {
|
||||
@@ -58,13 +63,13 @@ public class AliPaySyncService {
|
||||
syncResult.setErrorMsg(response.getSubMsg());
|
||||
return syncResult;
|
||||
}
|
||||
// 设置网关订单号
|
||||
syncResult.setGatewayOrderNo(response.getTradeNo());
|
||||
// 支付完成 TODO 部分退款也在这个地方, 但无法进行区分, 需要借助对账进行处理
|
||||
if (Objects.equals(tradeStatus, AliPayCode.NOTIFY_TRADE_SUCCESS) || Objects.equals(tradeStatus, AliPayCode.NOTIFY_TRADE_FINISHED)) {
|
||||
PaymentContextLocal.get().getPaySyncInfo().setGatewayOrderNo(response.getTradeNo());
|
||||
// 支付完成时间
|
||||
LocalDateTime payTime = LocalDateTimeUtil.of(response.getSendPayDate());
|
||||
PaymentContextLocal.get().getPaySyncInfo().setPayTime(payTime);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS).setPayTime(payTime);
|
||||
}
|
||||
// 待支付
|
||||
if (Objects.equals(tradeStatus, AliPayCode.NOTIFY_WAIT_BUYER_PAY)) {
|
||||
@@ -78,7 +83,6 @@ public class AliPaySyncService {
|
||||
} else {
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.CLOSED);
|
||||
}
|
||||
|
||||
}
|
||||
// 支付宝支付后, 客户未进行操作将不会创建出订单, 所以交易不存在约等于未查询订单
|
||||
if (Objects.equals(response.getSubCode(), AliPayCode.ACQ_TRADE_NOT_EXIST)) {
|
||||
@@ -103,6 +107,8 @@ public class AliPaySyncService {
|
||||
queryModel.setOutRequestNo(String.valueOf(refundOrder.getId()));
|
||||
// 商户订单号
|
||||
queryModel.setOutTradeNo(String.valueOf(refundOrder.getPaymentId()));
|
||||
// 设置返回退款完成时间
|
||||
queryModel.setQueryOptions(Collections.singletonList(GMT_REFUND_PAY));
|
||||
AlipayTradeFastpayRefundQueryResponse response = AliPayApi.tradeRefundQueryToResponse(queryModel);
|
||||
syncResult.setSyncInfo(JSONUtil.toJsonStr(response));
|
||||
// 失败
|
||||
@@ -113,9 +119,12 @@ public class AliPaySyncService {
|
||||
return syncResult;
|
||||
}
|
||||
String tradeStatus = response.getRefundStatus();
|
||||
// 设置网关订单号
|
||||
syncResult.setGatewayOrderNo(response.getTradeNo());
|
||||
// 成功
|
||||
if (Objects.equals(tradeStatus, AliPayCode.REFUND_SUCCESS)){
|
||||
return syncResult.setSyncStatus(PayRefundSyncStatusEnum.SUCCESS);
|
||||
LocalDateTime localDateTime = LocalDateTimeUtil.of(response.getGmtRefundPay());
|
||||
return syncResult.setRefundTime(localDateTime).setSyncStatus(PayRefundSyncStatusEnum.SUCCESS);
|
||||
} else {
|
||||
return syncResult.setSyncStatus(PayRefundSyncStatusEnum.FAIL).setErrorMsg("支付宝网关反正退款未成功");
|
||||
}
|
||||
|
@@ -118,18 +118,19 @@ public class WeChatPayCallbackService extends AbsCallbackStrategy {
|
||||
callbackParam = WxPayKit.xmlToMap(decryptData);
|
||||
callbackInfo.setCallbackParam(callbackParam);
|
||||
// 网关订单号
|
||||
callbackInfo.setGatewayOrderNo(callbackParam.get(REFUND_ID));
|
||||
callbackInfo.setGatewayOrderNo(callbackParam.get(CALLBACK_REFUND_ID));
|
||||
// 退款订单Id
|
||||
callbackInfo.setOrderId(Long.valueOf(callbackParam.get(OUT_REFUND_NO)));
|
||||
callbackInfo.setOrderId(Long.valueOf(callbackParam.get(CALLBACK_OUT_REFUND_NO)));
|
||||
// 退款金额
|
||||
callbackInfo.setAmount(callbackParam.get(REFUND_FEE));
|
||||
callbackInfo.setAmount(callbackParam.get(CALLBACK_REFUND_FEE));
|
||||
|
||||
// 交易状态
|
||||
PayStatusEnum payStatus = Objects.equals(callbackParam.get(REFUND_STATUS), REFUND_USERPAYING) ? PayStatusEnum.SUCCESS : PayStatusEnum.FAIL;
|
||||
PayStatusEnum payStatus = Objects.equals(callbackParam.get(CALLBACK_REFUND_STATUS), REFUND_SUCCESS)
|
||||
? PayStatusEnum.SUCCESS : PayStatusEnum.FAIL;
|
||||
callbackInfo.setGatewayStatus(payStatus.getCode());
|
||||
|
||||
// 退款时间
|
||||
String timeEnd = callbackParam.get(SUCCESS_TIME);
|
||||
String timeEnd = callbackParam.get(CALLBACK_SUCCESS_TIME);
|
||||
if (StrUtil.isNotBlank(timeEnd)) {
|
||||
LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.NORM_DATETIME_PATTERN);
|
||||
callbackInfo.setFinishTime(time);
|
||||
|
@@ -1,17 +1,11 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.wechat.service;
|
||||
|
||||
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.code.PayRefundSyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.service.code.WeChatPayCode;
|
||||
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.order.pay.dao.PayChannelOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.refund.dao.PayRefundChannelOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.refund.entity.PayRefundChannelOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.refund.entity.PayRefundOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.sync.result.PayGatewaySyncResult;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.sync.result.RefundGatewaySyncResult;
|
||||
@@ -30,6 +24,8 @@ import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.bootx.platform.daxpay.service.code.WeChatPayCode.TRANSACTION_ID;
|
||||
|
||||
/**
|
||||
* 微信支付同步服务
|
||||
*
|
||||
@@ -40,11 +36,9 @@ import java.util.Objects;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class WeChatPaySyncService {
|
||||
private final PayChannelOrderManager payChannelOrderManager;
|
||||
private final PayRefundChannelOrderManager refundChannelOrderManager;
|
||||
|
||||
/**
|
||||
* 同步查询
|
||||
* 支付信息查询
|
||||
*/
|
||||
public PayGatewaySyncResult syncPayStatus(PayOrder order, WeChatPayConfig weChatPayConfig) {
|
||||
PayGatewaySyncResult syncResult = new PayGatewaySyncResult().setSyncStatus(PaySyncStatusEnum.FAIL);
|
||||
@@ -70,14 +64,16 @@ public class WeChatPaySyncService {
|
||||
log.warn("疑似未查询到订单:{}", result);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.NOT_FOUND);
|
||||
}
|
||||
|
||||
// 设置微信支付网关订单号
|
||||
syncResult.setGatewayOrderNo(result.get(TRANSACTION_ID));
|
||||
// 查询到订单的状态
|
||||
String tradeStatus = result.get(WeChatPayCode.TRADE_STATE);
|
||||
// 支付完成
|
||||
if (Objects.equals(tradeStatus, WeChatPayCode.PAY_SUCCESS) || Objects.equals(tradeStatus, WeChatPayCode.PAY_ACCEPT)) {
|
||||
String timeEnd = result.get(WeChatPayCode.TIME_END);
|
||||
LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.PURE_DATETIME_PATTERN);
|
||||
PaymentContextLocal.get().getPaySyncInfo().setPayTime(time);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS);
|
||||
return syncResult.setPayTime(time).setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS);
|
||||
}
|
||||
// 待支付
|
||||
if (Objects.equals(tradeStatus, WeChatPayCode.PAY_NOTPAY)
|
||||
@@ -97,7 +93,7 @@ public class WeChatPaySyncService {
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
log.error("查询订单失败:", e);
|
||||
log.error("查询支付订单失败:", e);
|
||||
syncResult.setErrorMsg(e.getMessage());
|
||||
}
|
||||
return syncResult;
|
||||
@@ -107,26 +103,41 @@ public class WeChatPaySyncService {
|
||||
* 退款信息查询
|
||||
*/
|
||||
public RefundGatewaySyncResult syncRefundStatus(PayRefundOrder refundOrder, WeChatPayConfig weChatPayConfig){
|
||||
PayRefundChannelOrder orderChannel = refundChannelOrderManager.findByRefundIdAndChannel(refundOrder.getId(), PayChannelEnum.WECHAT.getCode())
|
||||
.orElseThrow(() -> new PayFailureException("支付订单通道信息不存在"));
|
||||
|
||||
RefundGatewaySyncResult syncResult = new RefundGatewaySyncResult();
|
||||
Map<String, String> params = RefundQueryModel.builder()
|
||||
.appid(weChatPayConfig.getWxAppId())
|
||||
.mch_id(weChatPayConfig.getWxMchId())
|
||||
.nonce_str(WxPayKit.generateStr())
|
||||
// 使用退款单号查询, 只返回当前这条, 如果使用支付订单号查询,
|
||||
.out_refund_no(String.valueOf(refundOrder.getId()))
|
||||
.build()
|
||||
.createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256);
|
||||
String xmlResult = WxPayApi.orderRefundQuery(false, params);
|
||||
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
|
||||
// TODO 处理退款同步的情况
|
||||
|
||||
try {
|
||||
String xmlResult = WxPayApi.orderRefundQuery(false, params);
|
||||
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
|
||||
syncResult.setSyncInfo(JSONUtil.toJsonStr(result));
|
||||
|
||||
|
||||
Integer refundFee = Integer.valueOf(result.get(WeChatPayCode.REFUND_FEE));
|
||||
if (Objects.equals(refundFee, orderChannel.getAmount())){
|
||||
return new RefundGatewaySyncResult().setSyncStatus(PayRefundSyncStatusEnum.REFUNDING);
|
||||
// 设置微信支付网关订单号
|
||||
syncResult.setGatewayOrderNo(result.get(WeChatPayCode.REFUND_ID));
|
||||
// 状态
|
||||
String tradeStatus = result.get(WeChatPayCode.REFUND_STATUS);
|
||||
// 退款成功
|
||||
if (Objects.equals(tradeStatus, WeChatPayCode.REFUND_SUCCESS)) {
|
||||
String timeEnd = result.get(WeChatPayCode.REFUND_SUCCESS_TIME);
|
||||
LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.NORM_DATETIME_PATTERN);
|
||||
return syncResult.setRefundTime(time).setSyncStatus(PayRefundSyncStatusEnum.SUCCESS);
|
||||
}
|
||||
// 退款中
|
||||
if (Objects.equals(tradeStatus, WeChatPayCode.REFUND_PROCESSING)) {
|
||||
return syncResult.setSyncStatus(PayRefundSyncStatusEnum.REFUNDING);
|
||||
}
|
||||
return syncResult.setSyncStatus(PayRefundSyncStatusEnum.FAIL);
|
||||
} catch (Exception e) {
|
||||
log.error("查询退款订单失败:", e);
|
||||
syncResult.setSyncStatus(PayRefundSyncStatusEnum.REFUNDING).setErrorMsg(e.getMessage());
|
||||
}
|
||||
return new RefundGatewaySyncResult().setSyncInfo(JSONUtil.toJsonStr(result));
|
||||
return syncResult;
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -9,9 +9,9 @@ import cn.bootx.platform.daxpay.service.core.notice.result.PayChannelResult;
|
||||
import cn.bootx.platform.daxpay.service.core.notice.result.PayNoticeResult;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderExtraManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService;
|
||||
import cn.bootx.platform.daxpay.util.PaySignUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.ContentType;
|
||||
@@ -35,7 +35,7 @@ import java.util.stream.Collectors;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PayNoticeService {
|
||||
private final PayOrderManager payOrderManager;
|
||||
private final PayOrderQueryService payOrderQueryService;
|
||||
private final PayOrderExtraManager payOrderExtraManager;
|
||||
private final PayChannelOrderManager payChannelOrderManager;
|
||||
|
||||
@@ -49,7 +49,7 @@ public class PayNoticeService {
|
||||
PlatformLocal platform = PaymentContextLocal.get().getPlatformInfo();
|
||||
// 首先判断接口是开启了通知回调功能
|
||||
if (apiInfo.isNotice()){
|
||||
PayOrder payOrder = payOrderManager.findById(paymentId).orElseThrow(DataNotExistException::new);
|
||||
PayOrder payOrder = payOrderQueryService.findById(paymentId).orElseThrow(DataNotExistException::new);
|
||||
// 判断是否是同步支付, 并且配置不进行消息通知
|
||||
if (!payOrder.isAsyncPay() && apiInfo.isOnlyAsyncNotice()){
|
||||
return;
|
||||
|
@@ -6,18 +6,18 @@ import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.common.query.generator.QueryGenerator;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.param.order.PayOrderQuery;
|
||||
import cn.hutool.core.text.NamingCase;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
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;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 支付订单
|
||||
* 注意: 增删改需要使用 PayOrderQueryService 服务类, 不可以直接使用此dao, 因为订单超时任务需要处理
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2023/12/18
|
||||
*/
|
||||
|
@@ -7,6 +7,8 @@ import cn.bootx.platform.daxpay.service.core.order.refund.convert.RefundOrderCha
|
||||
import cn.bootx.platform.daxpay.service.dto.order.refund.RefundChannelOrderDto;
|
||||
import cn.bootx.table.modify.annotation.DbColumn;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -44,6 +46,10 @@ public class PayRefundChannelOrder extends MpCreateEntity implements EntityBaseF
|
||||
@DbColumn(comment = "退款金额")
|
||||
private Integer amount;
|
||||
|
||||
@DbColumn(comment = "剩余可退余额")
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private Integer refundableAmount;
|
||||
|
||||
/**
|
||||
* 退款状态
|
||||
* @see PayRefundStatusEnum
|
||||
@@ -51,7 +57,7 @@ public class PayRefundChannelOrder extends MpCreateEntity implements EntityBaseF
|
||||
@DbColumn(comment = "退款状态")
|
||||
private String status;
|
||||
|
||||
@DbColumn(comment = "退款时间")
|
||||
@DbColumn(comment = "退款完成时间")
|
||||
private LocalDateTime refundTime;
|
||||
|
||||
/**
|
||||
|
@@ -90,7 +90,7 @@ public class PayRefundOrder extends MpBaseEntity implements EntityBaseFunction<P
|
||||
private String reason;
|
||||
|
||||
/** 退款时间 */
|
||||
@DbColumn(comment = "退款时间")
|
||||
@DbColumn(comment = "退款完成时间")
|
||||
private LocalDateTime refundTime;
|
||||
|
||||
/**
|
||||
|
@@ -115,7 +115,6 @@ public class PayRepairService {
|
||||
.getFinishTime();
|
||||
// 执行个通道的成功处理方法
|
||||
strategies.forEach(AbsPayRepairStrategy::doPaySuccessHandler);
|
||||
|
||||
// 修改订单支付状态为成功
|
||||
order.setStatus(PayStatusEnum.SUCCESS.getCode());
|
||||
// 读取支付网关中的时间
|
||||
|
@@ -7,9 +7,10 @@ import cn.bootx.platform.daxpay.service.code.PaymentTypeEnum;
|
||||
import cn.bootx.platform.daxpay.service.code.RefundRepairWayEnum;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.service.core.order.refund.dao.PayRefundChannelOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.refund.dao.PayRefundOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.refund.entity.PayRefundChannelOrder;
|
||||
@@ -39,7 +40,9 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class RefundRepairService {
|
||||
|
||||
private final PayOrderManager payOrderManager;
|
||||
private final PayOrderService payOrderService;
|
||||
|
||||
private final PayOrderQueryService payOrderQueryService;
|
||||
|
||||
private final PayChannelOrderManager payChannelOrderManager;
|
||||
|
||||
@@ -56,7 +59,7 @@ public class RefundRepairService {
|
||||
public RefundRepairResult repair(PayRefundOrder refundOrder, RefundRepairWayEnum repairType){
|
||||
|
||||
// 获取关联支付单
|
||||
PayOrder payOrder = payOrderManager.findById(refundOrder.getPaymentId())
|
||||
PayOrder payOrder = payOrderQueryService.findById(refundOrder.getPaymentId())
|
||||
.orElseThrow(() -> new RuntimeException("支付单不存在"));
|
||||
// 关联支付通道支付单
|
||||
Map<String, PayChannelOrder> payChannelOrderMap = payChannelOrderManager.findAllByPaymentId(refundOrder.getPaymentId())
|
||||
@@ -127,7 +130,7 @@ public class RefundRepairService {
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 更新订单和退款相关订单
|
||||
payOrderManager.updateById(payOrder);
|
||||
payOrderService.updateById(payOrder);
|
||||
refundOrderManager.updateById(refundOrder);
|
||||
payChannelOrderManager.updateAllById(payChannelOrders);
|
||||
refundChannelOrderManager.updateAllById(refundChannelOrders);
|
||||
@@ -183,7 +186,7 @@ public class RefundRepairService {
|
||||
|
||||
// 更新订单和退款相关订单
|
||||
payChannelOrderManager.updateAllById(payChannelOrders);
|
||||
payOrderManager.updateById(payOrder);
|
||||
payOrderService.updateById(payOrder);
|
||||
refundOrderManager.updateById(refundOrder);
|
||||
refundChannelOrderManager.updateAllById(refundChannelOrders);
|
||||
return repairResult;
|
||||
|
@@ -4,6 +4,8 @@ import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.FAIL;
|
||||
|
||||
/**
|
||||
@@ -22,6 +24,14 @@ public class PayGatewaySyncResult {
|
||||
*/
|
||||
private PaySyncStatusEnum syncStatus = FAIL;
|
||||
|
||||
/**
|
||||
* 第三方支付网关生成的订单号, 用与将记录关联起来
|
||||
*/
|
||||
private String gatewayOrderNo;
|
||||
|
||||
/** 支付完成时间(通常用于接收异步支付返回的时间) */
|
||||
private LocalDateTime payTime;
|
||||
|
||||
/** 同步时网关返回的对象, 序列化为json字符串 */
|
||||
private String syncInfo;
|
||||
|
||||
|
@@ -4,7 +4,9 @@ import cn.bootx.platform.daxpay.code.PayRefundSyncStatusEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import static cn.bootx.platform.daxpay.code.PayRefundSyncStatusEnum.FAIL;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.bootx.platform.daxpay.code.PayRefundSyncStatusEnum.REFUNDING;
|
||||
|
||||
/**
|
||||
* 支付退款同步结果
|
||||
@@ -16,14 +18,22 @@ import static cn.bootx.platform.daxpay.code.PayRefundSyncStatusEnum.FAIL;
|
||||
public class RefundGatewaySyncResult {
|
||||
|
||||
/**
|
||||
* 支付网关订单状态
|
||||
* 支付网关订单状态, 默认为退款中
|
||||
* @see PayRefundSyncStatusEnum
|
||||
*/
|
||||
private PayRefundSyncStatusEnum syncStatus = FAIL;
|
||||
private PayRefundSyncStatusEnum syncStatus = REFUNDING;
|
||||
|
||||
/** 同步时网关返回的对象, 序列化为json字符串 */
|
||||
private String syncInfo;
|
||||
|
||||
/**
|
||||
* 第三方支付网关生成的订单号, 用与将记录关联起来
|
||||
*/
|
||||
private String gatewayOrderNo;
|
||||
|
||||
/** 退款完成时间(通常用于接收网关返回的时间) */
|
||||
private LocalDateTime refundTime;
|
||||
|
||||
/** 错误提示码 */
|
||||
private String errorCode;
|
||||
|
||||
|
@@ -2,6 +2,7 @@ package cn.bootx.platform.daxpay.service.core.payment.sync.service;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.BizException;
|
||||
import cn.bootx.platform.common.core.exception.RepetitiveOperationException;
|
||||
import cn.bootx.platform.daxpay.code.PayRefundStatusEnum;
|
||||
import cn.bootx.platform.daxpay.code.PayRefundSyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.param.pay.RefundSyncParam;
|
||||
@@ -53,19 +54,23 @@ public class PayRefundSyncService {
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
|
||||
public SyncResult sync(RefundSyncParam param){
|
||||
// 先获取退款单
|
||||
PayRefundOrder requestOrder;
|
||||
PayRefundOrder refundOrder;
|
||||
if (Objects.nonNull(param.getRefundId())){
|
||||
requestOrder = refundOrderManager.findById(param.getRefundId())
|
||||
refundOrder = refundOrderManager.findById(param.getRefundId())
|
||||
.orElseThrow(() -> new PayFailureException("未查询到退款订单"));
|
||||
} else {
|
||||
requestOrder = refundOrderManager.findByRefundNo(param.getRefundNo())
|
||||
refundOrder = refundOrderManager.findByRefundNo(param.getRefundNo())
|
||||
.orElseThrow(() -> new PayFailureException("未查询到退款订单"));
|
||||
}
|
||||
// 如果不是异步支付, 直接返回返回
|
||||
if (!requestOrder.isAsyncPay()){
|
||||
if (!refundOrder.isAsyncPay()){
|
||||
return new SyncResult().setSuccess(false).setRepair(false).setErrorMsg("订单没有异步通道的退款,不需要同步");
|
||||
}
|
||||
return this.syncRefundOrder(requestOrder);
|
||||
// 如果订单已经关闭, 直接返回失败
|
||||
if (Objects.equals(refundOrder.getStatus(), PayRefundStatusEnum.CLOSE.getCode())){
|
||||
return new SyncResult().setSuccess(false).setRepair(false).setErrorMsg("订单已经关闭,不需要同步");
|
||||
}
|
||||
return this.syncRefundOrder(refundOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,6 +87,8 @@ public class PayRefundSyncService {
|
||||
// 获取支付同步策略类
|
||||
AbsRefundSyncStrategy syncPayStrategy = RefundSyncStrategyFactory.create(refundOrder.getAsyncChannel());
|
||||
syncPayStrategy.initRefundParam(refundOrder);
|
||||
// 同步前处理, 主要预防请求过于迅速
|
||||
syncPayStrategy.doBeforeHandler();
|
||||
// 执行操作, 获取支付网关同步的结果
|
||||
RefundGatewaySyncResult syncResult = syncPayStrategy.doSyncStatus();
|
||||
|
||||
@@ -90,12 +97,23 @@ public class PayRefundSyncService {
|
||||
// 同步失败, 返回失败响应, 同时记录失败的日志
|
||||
return new SyncResult().setErrorMsg(syncResult.getErrorMsg());
|
||||
}
|
||||
// 支付订单的网关订单号是否一致, 不一致进行更新
|
||||
if (!Objects.equals(syncResult.getGatewayOrderNo(), refundOrder.getGatewayOrderNo())){
|
||||
refundOrder.setGatewayOrderNo(syncResult.getGatewayOrderNo());
|
||||
refundOrderManager.updateById(refundOrder);
|
||||
}
|
||||
// 判断网关状态是否和支付单一致, 同时特定情况下更新网关同步状态
|
||||
boolean statusSync = this.checkSyncStatus(syncResult, refundOrder);
|
||||
RefundRepairResult repairResult = new RefundRepairResult();
|
||||
try {
|
||||
// 状态不一致,执行退款单修复逻辑
|
||||
if (!statusSync) {
|
||||
// 如果没有支付来源, 设置支付来源为同步
|
||||
RepairLocal repairInfo = PaymentContextLocal.get().getRepairInfo();
|
||||
if (Objects.isNull(repairInfo.getSource())){
|
||||
repairInfo.setSource(PayRepairSourceEnum.SYNC);
|
||||
}
|
||||
repairInfo.setFinishTime(syncResult.getRefundTime());
|
||||
repairResult = this.repairHandler(syncResult, refundOrder);
|
||||
}
|
||||
} catch (PayFailureException e) {
|
||||
@@ -119,11 +137,29 @@ public class PayRefundSyncService {
|
||||
|
||||
/**
|
||||
* 检查状态是否一致
|
||||
* @see PayRefundSyncStatusEnum 同步返回类型
|
||||
* @see PayRefundStatusEnum 退款单状态
|
||||
*/
|
||||
private boolean checkSyncStatus(RefundGatewaySyncResult syncResult, PayRefundOrder order){
|
||||
PayRefundSyncStatusEnum syncStatus = syncResult.getSyncStatus();
|
||||
String orderStatus = order.getStatus();
|
||||
return Objects.equals(orderStatus, syncStatus.getCode());
|
||||
// 退款完成
|
||||
if (Objects.equals(syncStatus, PayRefundSyncStatusEnum.SUCCESS)&&
|
||||
Objects.equals(orderStatus, PayRefundStatusEnum.SUCCESS.getCode())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 退款失败
|
||||
if (Objects.equals(syncStatus, PayRefundSyncStatusEnum.FAIL)&&
|
||||
Objects.equals(orderStatus, PayRefundStatusEnum.FAIL.getCode())) {
|
||||
return true;
|
||||
}
|
||||
// 退款中
|
||||
if (Objects.equals(syncStatus, PayRefundSyncStatusEnum.REFUNDING)&&
|
||||
Objects.equals(orderStatus, PayRefundStatusEnum.PROGRESS.getCode())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,11 +167,6 @@ public class PayRefundSyncService {
|
||||
*/
|
||||
private RefundRepairResult repairHandler(RefundGatewaySyncResult syncResult, PayRefundOrder order){
|
||||
PayRefundSyncStatusEnum syncStatusEnum = syncResult.getSyncStatus();
|
||||
// 如果没有支付来源, 设置支付来源为同步
|
||||
RepairLocal repairInfo = PaymentContextLocal.get().getRepairInfo();
|
||||
if (Objects.isNull(repairInfo.getSource())){
|
||||
repairInfo.setSource(PayRepairSourceEnum.SYNC);
|
||||
}
|
||||
RefundRepairResult repair = new RefundRepairResult();
|
||||
// 对支付网关同步的结果进行处理
|
||||
switch (syncStatusEnum) {
|
||||
@@ -158,21 +189,20 @@ public class PayRefundSyncService {
|
||||
return repair;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 保存同步记录
|
||||
* @param payOrder 支付单
|
||||
* @param refundOrder 支付单
|
||||
* @param syncResult 同步结果
|
||||
* @param repair 是否修复
|
||||
* @param errorMsg 错误信息
|
||||
*/
|
||||
private void saveRecord(PayRefundOrder payOrder, RefundGatewaySyncResult syncResult, boolean repair, Long repairOrderId, String errorMsg){
|
||||
private void saveRecord(PayRefundOrder refundOrder, RefundGatewaySyncResult syncResult, boolean repair, Long repairOrderId, String errorMsg){
|
||||
PaySyncRecord paySyncRecord = new PaySyncRecord()
|
||||
.setOrderId(payOrder.getId())
|
||||
.setOrderNo(payOrder.getBusinessNo())
|
||||
.setOrderId(refundOrder.getId())
|
||||
.setOrderNo(refundOrder.getRefundNo())
|
||||
.setSyncType(PaymentTypeEnum.REFUND.getCode())
|
||||
.setAsyncChannel(payOrder.getAsyncChannel())
|
||||
.setAsyncChannel(refundOrder.getAsyncChannel())
|
||||
.setGatewayOrderNo(syncResult.getGatewayOrderNo())
|
||||
.setSyncInfo(syncResult.getSyncInfo())
|
||||
.setGatewayStatus(syncResult.getSyncStatus().getCode())
|
||||
.setRepairOrder(repair)
|
||||
|
@@ -15,6 +15,7 @@ import cn.bootx.platform.daxpay.service.common.context.RepairLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.repair.result.PayRepairResult;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.repair.service.PayRepairService;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.sync.factory.PaySyncStrategyFactory;
|
||||
@@ -49,6 +50,8 @@ import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.*;
|
||||
public class PaySyncService {
|
||||
private final PayOrderQueryService payOrderQueryService;
|
||||
|
||||
private final PayOrderService payOrderService;
|
||||
|
||||
private final PaySyncRecordService paySyncRecordService;
|
||||
|
||||
private final PayRepairService repairService;
|
||||
@@ -79,8 +82,8 @@ public class PaySyncService {
|
||||
/**
|
||||
* 同步支付状态, 开启一个新的事务, 不受外部抛出异常的影响
|
||||
* 1. 如果状态一致, 不进行处理
|
||||
* 2. 如果状态不一致, 调用修复逻辑进行修复
|
||||
* todo 需要进行异常处理, 现在会有 Transaction rolled back because it has been marked as rollback-only 问题
|
||||
* 2. 如果状态不一致, 调用修复逻辑进行修复, 更新状态和完成时间
|
||||
* 3. 会更新关联网关订单号
|
||||
*/
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
|
||||
public SyncResult syncPayOrder(PayOrder payOrder) {
|
||||
@@ -102,13 +105,24 @@ public class PaySyncService {
|
||||
this.saveRecord(payOrder, syncResult, false, null, syncResult.getErrorMsg());
|
||||
return new SyncResult().setErrorMsg(syncResult.getErrorMsg());
|
||||
}
|
||||
|
||||
// 支付订单的网关订单号是否一致, 不一致进行更新
|
||||
if (!Objects.equals(syncResult.getGatewayOrderNo(), payOrder.getGatewayOrderNo())){
|
||||
payOrder.setGatewayOrderNo(syncResult.getGatewayOrderNo());
|
||||
payOrderService.updateById(payOrder);
|
||||
}
|
||||
// 判断网关状态是否和支付单一致, 同时特定情况下更新网关同步状态
|
||||
boolean statusSync = this.checkAndAdjustSyncStatus(syncResult,payOrder);
|
||||
PayRepairResult repairResult = new PayRepairResult();
|
||||
try {
|
||||
// 状态不一致,执行支付单修复逻辑
|
||||
if (!statusSync){
|
||||
// 如果没有修复触发来源, 设置修复触发来源为同步
|
||||
RepairLocal repairInfo = PaymentContextLocal.get().getRepairInfo();
|
||||
if (Objects.isNull(repairInfo.getSource())){
|
||||
repairInfo.setSource(PayRepairSourceEnum.SYNC);
|
||||
}
|
||||
// 设置支付单完成时间
|
||||
repairInfo.setFinishTime(syncResult.getPayTime());
|
||||
repairResult = this.repairHandler(syncResult, payOrder);
|
||||
}
|
||||
} catch (PayFailureException e) {
|
||||
@@ -178,11 +192,6 @@ public class PaySyncService {
|
||||
*/
|
||||
private PayRepairResult repairHandler(PayGatewaySyncResult syncResult, PayOrder payOrder){
|
||||
PaySyncStatusEnum syncStatusEnum = syncResult.getSyncStatus();
|
||||
// 如果没有支付来源, 设置支付来源为同步
|
||||
RepairLocal repairInfo = PaymentContextLocal.get().getRepairInfo();
|
||||
if (Objects.isNull(repairInfo.getSource())){
|
||||
repairInfo.setSource(PayRepairSourceEnum.SYNC);
|
||||
}
|
||||
PayRepairResult repair = new PayRepairResult();
|
||||
// 对支付网关同步的结果进行处理
|
||||
switch (syncStatusEnum) {
|
||||
|
@@ -3,6 +3,7 @@ package cn.bootx.platform.daxpay.service.core.record.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.PayRefundSyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.service.code.PaymentTypeEnum;
|
||||
import cn.bootx.platform.daxpay.service.core.record.sync.convert.PaySyncRecordConvert;
|
||||
@@ -36,6 +37,10 @@ public class PaySyncRecord extends MpCreateEntity implements EntityBaseFunction<
|
||||
@DbColumn(comment = "本地业务号")
|
||||
private String orderNo;
|
||||
|
||||
/** 网关订单号 */
|
||||
@DbColumn(comment = "网关订单号")
|
||||
private String gatewayOrderNo;
|
||||
|
||||
/**
|
||||
* 同步类型 支付/退款
|
||||
* @see PaymentTypeEnum
|
||||
@@ -43,14 +48,11 @@ public class PaySyncRecord extends MpCreateEntity implements EntityBaseFunction<
|
||||
@DbColumn(comment = "同步类型")
|
||||
private String syncType;
|
||||
|
||||
@DbColumn(comment = "同步的异步通道")
|
||||
private String syncChannel;
|
||||
|
||||
/**
|
||||
* 同步通道
|
||||
* 同步的异步通道
|
||||
* @see PayChannelEnum#getCode()
|
||||
*/
|
||||
@DbColumn(comment = "同步通道")
|
||||
@DbColumn(comment = "同步的异步通道")
|
||||
private String asyncChannel;
|
||||
|
||||
/** 网关返回的同步消息 */
|
||||
@@ -61,6 +63,7 @@ public class PaySyncRecord extends MpCreateEntity implements EntityBaseFunction<
|
||||
/**
|
||||
* 网关返回状态
|
||||
* @see PaySyncStatusEnum
|
||||
* @see PayRefundSyncStatusEnum
|
||||
*/
|
||||
@DbColumn(comment = "网关返回状态")
|
||||
private String gatewayStatus;
|
||||
|
@@ -38,6 +38,9 @@ public class RefundChannelOrderDto extends BaseDto {
|
||||
@Schema(description = "退款金额")
|
||||
private Integer amount;
|
||||
|
||||
@Schema(description = "剩余可退余额")
|
||||
private Integer refundableAmount;
|
||||
|
||||
/**
|
||||
* 退款状态
|
||||
* @see PayRefundStatusEnum
|
||||
|
@@ -2,6 +2,7 @@ package cn.bootx.platform.daxpay.service.dto.record.sync;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.dto.BaseDto;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.code.PayRefundSyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.table.modify.mysql.annotation.DbMySqlFieldType;
|
||||
import cn.bootx.table.modify.mysql.constants.MySqlFieldTypeEnum;
|
||||
@@ -21,19 +22,27 @@ import lombok.experimental.Accessors;
|
||||
@Schema(title = "支付同步订单")
|
||||
public class PaySyncRecordDto extends BaseDto {
|
||||
|
||||
/** 支付记录id */
|
||||
@Schema(description = "支付记录id")
|
||||
private Long paymentId;
|
||||
/** 本地订单ID */
|
||||
@Schema(description = "本地订单ID")
|
||||
private Long orderId;
|
||||
|
||||
/** 业务号 */
|
||||
@Schema(description = "业务号")
|
||||
private String businessNo;
|
||||
/** 本地业务号 */
|
||||
@Schema(description = "本地业务号")
|
||||
private String orderNo;
|
||||
|
||||
/** 网关订单号 */
|
||||
@Schema(description = "网关订单号")
|
||||
private String gatewayOrderNo;
|
||||
|
||||
/** 同步类型 */
|
||||
@Schema(description = "同步类型")
|
||||
private String syncType;
|
||||
|
||||
/**
|
||||
* 同步通道
|
||||
* 同步的异步通道
|
||||
* @see PayChannelEnum#getCode()
|
||||
*/
|
||||
@Schema(description = "同步通道")
|
||||
@Schema(description = "同步的异步通道")
|
||||
private String asyncChannel;
|
||||
|
||||
/** 通知消息 */
|
||||
@@ -44,6 +53,7 @@ public class PaySyncRecordDto extends BaseDto {
|
||||
/**
|
||||
* 网关返回状态
|
||||
* @see PaySyncStatusEnum
|
||||
* @see PayRefundSyncStatusEnum
|
||||
*/
|
||||
@Schema(description = "网关返回状态")
|
||||
private String gatewayStatus;
|
||||
|
@@ -72,6 +72,8 @@ public abstract class AbsRefundRepairStrategy implements PayStrategy{
|
||||
payChannelOrder.setStatus(PayStatusEnum.PARTIAL_REFUND.getCode());
|
||||
|
||||
}
|
||||
// 如果失败, 可退余额设置为null
|
||||
refundChannelOrder.setRefundableAmount(null);
|
||||
refundChannelOrder.setStatus(PayRefundStatusEnum.CLOSE.getCode());
|
||||
}
|
||||
|
||||
|
@@ -76,8 +76,7 @@ public abstract class AbsRefundStrategy implements PayStrategy{
|
||||
*/
|
||||
public void doSuccessHandler() {
|
||||
// 更新退款订单数据状态
|
||||
this.refundChannelOrder.setStatus(PayRefundStatusEnum.SUCCESS.getCode())
|
||||
.setRefundTime(LocalDateTime.now());
|
||||
this.refundChannelOrder.setStatus(PayRefundStatusEnum.SUCCESS.getCode()).setRefundTime(LocalDateTime.now());
|
||||
|
||||
// 支付通道订单可退余额
|
||||
int refundableBalance = this.getPayChannelOrder().getRefundableBalance() - this.refundChannelOrder.getAmount();
|
||||
@@ -91,11 +90,14 @@ public abstract class AbsRefundStrategy implements PayStrategy{
|
||||
* 生成通道退款订单对象
|
||||
*/
|
||||
public void generateChannelOrder() {
|
||||
int refundableAmount = this.getPayChannelOrder().getRefundableBalance() - this.getRefundChannelParam().getAmount();
|
||||
|
||||
this.refundChannelOrder = new PayRefundChannelOrder()
|
||||
.setPayChannelId(this.getPayChannelOrder().getId())
|
||||
.setAsync(this.getPayChannelOrder().isAsync())
|
||||
.setChannel(this.getPayChannelOrder().getChannel())
|
||||
.setOrderAmount(this.getPayChannelOrder().getAmount())
|
||||
.setRefundableAmount(refundableAmount)
|
||||
.setAmount(this.getRefundChannelParam().getAmount());
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user