549 lines
24 KiB
C#
549 lines
24 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
||
using Microsoft.Extensions.Hosting;
|
||
using Microsoft.Extensions.Logging;
|
||
using YD_Event.Core.Entities;
|
||
using YD_Event.Core.Enum;
|
||
using YD_Event.Core.Infrastructure.WeChat;
|
||
using YD_Event.Core.Infrastructure.WeChat.Dto;
|
||
|
||
namespace YD_Event.Application.Event;
|
||
|
||
/// <summary>
|
||
/// 支付超时处理后台服务
|
||
/// </summary>
|
||
public class PaymentExpirationBackgroundService : BackgroundService
|
||
{
|
||
private readonly IServiceProvider _serviceProvider;
|
||
private readonly ILogger<PaymentExpirationBackgroundService> _logger;
|
||
private readonly PeriodicTimer _timer;
|
||
|
||
public PaymentExpirationBackgroundService(
|
||
IServiceProvider serviceProvider,
|
||
ILogger<PaymentExpirationBackgroundService> logger)
|
||
{
|
||
_serviceProvider = serviceProvider;
|
||
_logger = logger;
|
||
_timer = new PeriodicTimer(TimeSpan.FromMinutes(5));
|
||
}
|
||
|
||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||
{
|
||
_logger.LogInformation("支付超时处理后台服务已启动");
|
||
|
||
try
|
||
{
|
||
while (await _timer.WaitForNextTickAsync(stoppingToken))
|
||
{
|
||
await ProcessExpiredPaymentsAsync(stoppingToken);
|
||
await ProcessUnpaidWeChatOrdersAsync(stoppingToken);
|
||
await ProcessRefundingWeChatOrdersAsync(stoppingToken);
|
||
}
|
||
}
|
||
catch (OperationCanceledException)
|
||
{
|
||
_logger.LogInformation("支付超时处理后台服务已停止");
|
||
}
|
||
}
|
||
|
||
private async Task ProcessExpiredPaymentsAsync(CancellationToken stoppingToken)
|
||
{
|
||
try
|
||
{
|
||
_logger.LogInformation("开始处理超时未支付订单");
|
||
|
||
using var scope = _serviceProvider.CreateScope();
|
||
var registrationRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<EventRegistration>>();
|
||
var orderRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<YD_Event.Core.Entities.Order>>();
|
||
var userCouponRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<YD_Event.Core.Entities.UserCoupon>>();
|
||
var couponRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<YD_Event.Core.Entities.Coupon>>();
|
||
|
||
var now = DateTime.Now;
|
||
var expirationTime = now.AddMinutes(-30);
|
||
|
||
var expiredRegistrations = await registrationRepository.AsQueryable()
|
||
.Where(x => x.PaymentMethod == 2
|
||
&& x.PaymentStatus == 0
|
||
&& x.CreatedTime <= expirationTime
|
||
&& !x.DeleteMark)
|
||
.ToListAsync(stoppingToken);
|
||
|
||
if (expiredRegistrations.Any())
|
||
{
|
||
_logger.LogInformation("发现 {Count} 个超时未支付的线上订单", expiredRegistrations.Count);
|
||
|
||
var idsToCancel = expiredRegistrations.Select(x => x.Id).ToList();
|
||
var orderNos = expiredRegistrations.Where(x => !string.IsNullOrEmpty(x.OrderNo)).Select(x => x.OrderNo).ToList();
|
||
|
||
await registrationRepository.UpdateAsync(x => new EventRegistration
|
||
{
|
||
PaymentStatus = 4,
|
||
UpdatedTime = now
|
||
}, x => idsToCancel.Contains(x.Id));
|
||
|
||
if (orderNos.Any())
|
||
{
|
||
// 获取这些订单并释放优惠券
|
||
var orders = await orderRepository.AsQueryable()
|
||
.Where(x => orderNos.Contains(x.OrderNo) && x.CouponId.HasValue)
|
||
.ToListAsync(stoppingToken);
|
||
|
||
foreach (var order in orders)
|
||
{
|
||
await ReleaseCouponAsync(order.CouponId.Value, order.CreatedUserId, order.Id,
|
||
userCouponRepository, couponRepository, stoppingToken);
|
||
}
|
||
|
||
// 更新订单状态
|
||
await orderRepository.UpdateAsync(x => new YD_Event.Core.Entities.Order
|
||
{
|
||
OrderStatus = OrderStatus.Cancelled,
|
||
UpdatedTime = now
|
||
}, x => orderNos.Contains(x.OrderNo));
|
||
}
|
||
|
||
_logger.LogInformation("已成功取消 {Count} 个超时未支付订单", expiredRegistrations.Count);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "处理超时未支付订单时发生错误");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 释放优惠券,恢复为未使用状态
|
||
/// </summary>
|
||
private async Task ReleaseCouponAsync(long couponId, long userId, long orderId,
|
||
ISqlSugarRepository<YD_Event.Core.Entities.UserCoupon> userCouponRepository,
|
||
ISqlSugarRepository<YD_Event.Core.Entities.Coupon> couponRepository,
|
||
CancellationToken stoppingToken)
|
||
{
|
||
var userCoupon = await userCouponRepository.GetFirstAsync(uc =>
|
||
uc.CouponId == couponId &&
|
||
uc.UserId == userId &&
|
||
uc.OrderId == orderId &&
|
||
!uc.DeleteMark, stoppingToken);
|
||
|
||
if (userCoupon != null && userCoupon.Status == 1)
|
||
{
|
||
userCoupon.Status = 0;
|
||
userCoupon.UseTime = null;
|
||
userCoupon.OrderId = null;
|
||
await userCouponRepository.UpdateAsync(userCoupon, stoppingToken);
|
||
|
||
// 减少优惠券的已使用数量
|
||
var coupon = await couponRepository.GetByIdAsync(couponId, stoppingToken);
|
||
if (coupon != null && coupon.UsedQuantity > 0)
|
||
{
|
||
coupon.UsedQuantity--;
|
||
await couponRepository.UpdateAsync(coupon, stoppingToken);
|
||
}
|
||
|
||
_logger.LogInformation($"优惠券已释放,用户优惠券ID={userCoupon.Id},订单ID={orderId}");
|
||
}
|
||
else if (userCoupon != null && userCoupon.Status == 0)
|
||
{
|
||
// 如果优惠券还没有被标记为已使用,只需要清空OrderId
|
||
userCoupon.OrderId = null;
|
||
await userCouponRepository.UpdateAsync(userCoupon, stoppingToken);
|
||
_logger.LogInformation($"优惠券OrderId已清空,用户优惠券ID={userCoupon.Id},订单ID={orderId}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理微信未支付订单:定期检查并更新订单状态
|
||
/// </summary>
|
||
private async Task ProcessUnpaidWeChatOrdersAsync(CancellationToken stoppingToken)
|
||
{
|
||
try
|
||
{
|
||
_logger.LogInformation("开始检查微信未支付订单");
|
||
|
||
using var scope = _serviceProvider.CreateScope();
|
||
var registrationRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<EventRegistration>>();
|
||
var orderRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<YD_Event.Core.Entities.Order>>();
|
||
var weChatPayConfigRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<WeChatPayConfig>>();
|
||
var weChatPayService = scope.ServiceProvider.GetRequiredService<WeChatPayService>();
|
||
var paymentRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<EventRegistrationPayment>>();
|
||
|
||
var now = DateTime.Now;
|
||
|
||
var unpaidRegistrations = await registrationRepository.AsQueryable()
|
||
.Where(x => x.PaymentMethod == 2
|
||
&& x.PaymentMethodType == PaymentMethodType.WeChatPay
|
||
&& x.PaymentStatus == 0
|
||
&& !x.DeleteMark)
|
||
.OrderBy(x => x.CreatedTime)
|
||
.Take(50)
|
||
.ToListAsync(stoppingToken);
|
||
|
||
if (!unpaidRegistrations.Any())
|
||
{
|
||
_logger.LogInformation("没有发现需要检查的微信未支付订单");
|
||
return;
|
||
}
|
||
|
||
_logger.LogInformation("发现 {Count} 个微信未支付订单需要检查", unpaidRegistrations.Count);
|
||
|
||
foreach (var registration in unpaidRegistrations)
|
||
{
|
||
try
|
||
{
|
||
if (string.IsNullOrEmpty(registration.OrderNo))
|
||
{
|
||
_logger.LogWarning("报名记录 {RegistrationId} 没有订单编号", registration.Id);
|
||
continue;
|
||
}
|
||
|
||
var order = await orderRepository.GetFirstAsync(o => o.OrderNo == registration.OrderNo, stoppingToken);
|
||
if (order == null)
|
||
{
|
||
_logger.LogWarning("找不到订单编号 {OrderNo} 对应的订单记录", registration.OrderNo);
|
||
continue;
|
||
}
|
||
|
||
var weChatPayConfig = await weChatPayConfigRepository.GetFirstAsync(
|
||
c => c.MerchantId == order.MerchantId && c.Status == AvailabilityStatus.Enable && !c.DeleteMark,
|
||
stoppingToken);
|
||
|
||
if (weChatPayConfig == null)
|
||
{
|
||
_logger.LogWarning("商户 {MerchantId} 没有找到可用的微信支付配置", order.MerchantId);
|
||
continue;
|
||
}
|
||
|
||
var queryResult = await weChatPayService.QueryOrderAsync(weChatPayConfig, registration.OrderNo);
|
||
|
||
if (!queryResult.Success)
|
||
{
|
||
_logger.LogWarning("查询订单 {OrderNo} 状态失败: {Message}", registration.OrderNo, queryResult.Message);
|
||
continue;
|
||
}
|
||
|
||
_logger.LogInformation("订单 {OrderNo} 微信支付状态: {TradeState}", registration.OrderNo, queryResult.TradeState);
|
||
|
||
if (queryResult.TradeState == "SUCCESS")
|
||
{
|
||
await ProcessWeChatPaymentSuccessAsync(
|
||
registration,
|
||
order,
|
||
queryResult,
|
||
now,
|
||
registrationRepository,
|
||
orderRepository,
|
||
paymentRepository,
|
||
stoppingToken);
|
||
}
|
||
else if (queryResult.TradeState == "CLOSED" || queryResult.TradeState == "REVOKED")
|
||
{
|
||
var userCouponRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<YD_Event.Core.Entities.UserCoupon>>();
|
||
var couponRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<YD_Event.Core.Entities.Coupon>>();
|
||
await ProcessWeChatPaymentClosedAsync(
|
||
registration,
|
||
order,
|
||
now,
|
||
registrationRepository,
|
||
orderRepository,
|
||
userCouponRepository,
|
||
couponRepository,
|
||
stoppingToken);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "处理报名记录 {RegistrationId} 时发生错误", registration.Id);
|
||
}
|
||
}
|
||
|
||
_logger.LogInformation("微信未支付订单检查完成");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "检查微信未支付订单时发生错误");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理微信支付成功的订单
|
||
/// </summary>
|
||
private async Task ProcessWeChatPaymentSuccessAsync(
|
||
EventRegistration registration,
|
||
YD_Event.Core.Entities.Order order,
|
||
WeChatPayQueryResult queryResult,
|
||
DateTime now,
|
||
ISqlSugarRepository<EventRegistration> registrationRepository,
|
||
ISqlSugarRepository<YD_Event.Core.Entities.Order> orderRepository,
|
||
ISqlSugarRepository<EventRegistrationPayment> paymentRepository,
|
||
CancellationToken stoppingToken)
|
||
{
|
||
_logger.LogInformation("订单 {OrderNo} 支付成功,更新订单状态", registration.OrderNo);
|
||
|
||
var paymentTime = queryResult.SuccessTime.HasValue ? queryResult.SuccessTime.Value.LocalDateTime : now;
|
||
|
||
registration.PaymentStatus = 1;
|
||
registration.PaymentTime = paymentTime;
|
||
registration.UpdatedTime = now;
|
||
await registrationRepository.UpdateAsync(registration);
|
||
|
||
order.OrderStatus = OrderStatus.Paid;
|
||
order.PaymentTime = paymentTime;
|
||
order.UpdatedTime = now;
|
||
await orderRepository.UpdateAsync(order);
|
||
|
||
var existingPayment = await paymentRepository.GetFirstAsync(p => p.RegistrationId == registration.Id, stoppingToken);
|
||
if (existingPayment != null)
|
||
{
|
||
existingPayment.PaymentStatus = 1;
|
||
existingPayment.PaymentTime = paymentTime;
|
||
existingPayment.UpdatedTime = now;
|
||
if (!string.IsNullOrEmpty(queryResult.TransactionId))
|
||
{
|
||
existingPayment.TransactionNo = queryResult.TransactionId;
|
||
}
|
||
await paymentRepository.UpdateAsync(existingPayment);
|
||
}
|
||
else
|
||
{
|
||
var idGenerator = _serviceProvider.GetRequiredService<IIdGenerator>();
|
||
var newPayment = new EventRegistrationPayment
|
||
{
|
||
Id = idGenerator.NextId(),
|
||
RegistrationId = registration.Id,
|
||
TransactionNo = queryResult.TransactionId ?? string.Empty,
|
||
PaymentChannel = 1,
|
||
PaymentAmount = order.ActualAmount,
|
||
PaymentTime = paymentTime,
|
||
PaymentStatus = 1,
|
||
RefundStatus = 0,
|
||
RefundAmount = 0,
|
||
PayeeAccount = string.Empty,
|
||
CreatedTime = now,
|
||
CreatedUserId = registration.CreatedUserId
|
||
};
|
||
await paymentRepository.InsertAsync(newPayment);
|
||
}
|
||
|
||
_logger.LogInformation("订单 {OrderNo} 支付状态更新成功", registration.OrderNo);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理微信支付关闭的订单
|
||
/// </summary>
|
||
private async Task ProcessWeChatPaymentClosedAsync(
|
||
EventRegistration registration,
|
||
YD_Event.Core.Entities.Order order,
|
||
DateTime now,
|
||
ISqlSugarRepository<EventRegistration> registrationRepository,
|
||
ISqlSugarRepository<YD_Event.Core.Entities.Order> orderRepository,
|
||
ISqlSugarRepository<YD_Event.Core.Entities.UserCoupon> userCouponRepository,
|
||
ISqlSugarRepository<YD_Event.Core.Entities.Coupon> couponRepository,
|
||
CancellationToken stoppingToken)
|
||
{
|
||
_logger.LogInformation("订单 {OrderNo} 支付已关闭,更新订单状态为已取消", registration.OrderNo);
|
||
|
||
registration.PaymentStatus = 4;
|
||
registration.UpdatedTime = now;
|
||
await registrationRepository.UpdateAsync(registration);
|
||
|
||
order.OrderStatus = OrderStatus.Cancelled;
|
||
order.UpdatedTime = now;
|
||
await orderRepository.UpdateAsync(order);
|
||
|
||
// 释放优惠券
|
||
if (order.CouponId.HasValue)
|
||
{
|
||
await ReleaseCouponAsync(order.CouponId.Value, order.CreatedUserId, order.Id,
|
||
userCouponRepository, couponRepository, stoppingToken);
|
||
}
|
||
|
||
_logger.LogInformation("订单 {OrderNo} 状态更新为已取消成功", registration.OrderNo);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理微信退款中的订单
|
||
/// </summary>
|
||
private async Task ProcessRefundingWeChatOrdersAsync(CancellationToken stoppingToken)
|
||
{
|
||
try
|
||
{
|
||
_logger.LogInformation("开始检查微信退款中的订单");
|
||
|
||
using var scope = _serviceProvider.CreateScope();
|
||
var refundRecordRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<RefundRecord>>();
|
||
var registrationRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<EventRegistration>>();
|
||
var orderRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<YD_Event.Core.Entities.Order>>();
|
||
var weChatPayConfigRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<WeChatPayConfig>>();
|
||
var weChatPayService = scope.ServiceProvider.GetRequiredService<WeChatPayService>();
|
||
var paymentRepository = scope.ServiceProvider.GetRequiredService<ISqlSugarRepository<EventRegistrationPayment>>();
|
||
|
||
var now = DateTime.Now;
|
||
|
||
var refundingRecords = await refundRecordRepository.AsQueryable()
|
||
.Where(x => x.RefundStatus == 0 && !x.DeleteMark)
|
||
.OrderBy(x => x.ApplyTime)
|
||
.Take(50)
|
||
.ToListAsync(stoppingToken);
|
||
|
||
if (!refundingRecords.Any())
|
||
{
|
||
_logger.LogInformation("没有发现需要检查的微信退款订单");
|
||
return;
|
||
}
|
||
|
||
_logger.LogInformation("发现 {Count} 个微信退款订单需要检查", refundingRecords.Count);
|
||
|
||
foreach (var refundRecord in refundingRecords)
|
||
{
|
||
try
|
||
{
|
||
if (string.IsNullOrEmpty(refundRecord.OutRefundNo))
|
||
{
|
||
_logger.LogWarning("退款记录 {RefundRecordId} 没有退款单号", refundRecord.Id);
|
||
continue;
|
||
}
|
||
|
||
WeChatPayConfig? weChatPayConfig = null;
|
||
if (refundRecord.WeChatPayConfigId.HasValue)
|
||
{
|
||
weChatPayConfig = await weChatPayConfigRepository.GetByIdAsync(refundRecord.WeChatPayConfigId.Value, stoppingToken);
|
||
}
|
||
else if (refundRecord.MerchantId.HasValue)
|
||
{
|
||
weChatPayConfig = await weChatPayConfigRepository.GetFirstAsync(
|
||
c => c.MerchantId == refundRecord.MerchantId && c.Status == AvailabilityStatus.Enable && !c.DeleteMark,
|
||
stoppingToken);
|
||
}
|
||
|
||
if (weChatPayConfig == null)
|
||
{
|
||
_logger.LogWarning("退款记录 {RefundRecordId} 没有找到可用的微信支付配置", refundRecord.Id);
|
||
continue;
|
||
}
|
||
|
||
var queryResult = await weChatPayService.QueryRefundAsync(weChatPayConfig, refundRecord.OutRefundNo);
|
||
|
||
if (!queryResult.Success)
|
||
{
|
||
_logger.LogWarning("查询退款 {OutRefundNo} 状态失败: {Message}", refundRecord.OutRefundNo, queryResult.Message);
|
||
continue;
|
||
}
|
||
|
||
_logger.LogInformation("退款 {OutRefundNo} 微信退款状态: {RefundStatus}", refundRecord.OutRefundNo, queryResult.RefundStatus);
|
||
|
||
if (queryResult.RefundStatus == "SUCCESS")
|
||
{
|
||
await ProcessWeChatRefundSuccessAsync(
|
||
refundRecord,
|
||
queryResult,
|
||
now,
|
||
refundRecordRepository,
|
||
registrationRepository,
|
||
orderRepository,
|
||
paymentRepository,
|
||
stoppingToken);
|
||
}
|
||
else if (queryResult.RefundStatus == "CLOSED" || queryResult.RefundStatus == "ABNORMAL")
|
||
{
|
||
await ProcessWeChatRefundFailedAsync(
|
||
refundRecord,
|
||
queryResult,
|
||
now,
|
||
refundRecordRepository,
|
||
stoppingToken);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "处理退款记录 {RefundRecordId} 时发生错误", refundRecord.Id);
|
||
}
|
||
}
|
||
|
||
_logger.LogInformation("微信退款订单检查完成");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "检查微信退款订单时发生错误");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理微信退款成功的订单
|
||
/// </summary>
|
||
private async Task ProcessWeChatRefundSuccessAsync(
|
||
RefundRecord refundRecord,
|
||
WeChatRefundQueryResult queryResult,
|
||
DateTime now,
|
||
ISqlSugarRepository<RefundRecord> refundRecordRepository,
|
||
ISqlSugarRepository<EventRegistration> registrationRepository,
|
||
ISqlSugarRepository<YD_Event.Core.Entities.Order> orderRepository,
|
||
ISqlSugarRepository<EventRegistrationPayment> paymentRepository,
|
||
CancellationToken stoppingToken)
|
||
{
|
||
_logger.LogInformation("退款 {OutRefundNo} 成功,更新退款状态", refundRecord.OutRefundNo);
|
||
|
||
var successTime = queryResult.SuccessTime.HasValue ? queryResult.SuccessTime.Value.LocalDateTime : now;
|
||
|
||
refundRecord.RefundStatus = 1;
|
||
refundRecord.SuccessTime = successTime;
|
||
refundRecord.RefundId = queryResult.RefundId ?? refundRecord.RefundId;
|
||
refundRecord.WeChatResponse = queryResult.WeChatResponse ?? refundRecord.WeChatResponse;
|
||
refundRecord.UpdatedTime = now;
|
||
await refundRecordRepository.UpdateAsync(refundRecord);
|
||
|
||
var registration = await registrationRepository.GetByIdAsync(refundRecord.RegistrationId, stoppingToken);
|
||
if (registration != null)
|
||
{
|
||
registration.PaymentStatus = 3;
|
||
registration.UpdatedTime = now;
|
||
await registrationRepository.UpdateAsync(registration);
|
||
}
|
||
|
||
var order = await orderRepository.GetFirstAsync(o => o.OrderNo == refundRecord.OutTradeNo, stoppingToken);
|
||
if (order != null)
|
||
{
|
||
order.OrderStatus = OrderStatus.Refunded;
|
||
order.UpdatedTime = now;
|
||
await orderRepository.UpdateAsync(order);
|
||
}
|
||
|
||
var payment = await paymentRepository.GetFirstAsync(p => p.RegistrationId == refundRecord.RegistrationId, stoppingToken);
|
||
if (payment != null)
|
||
{
|
||
payment.RefundStatus = 2;
|
||
payment.RefundAmount = refundRecord.RefundAmount;
|
||
payment.RefundTime = successTime;
|
||
payment.UpdatedTime = now;
|
||
await paymentRepository.UpdateAsync(payment);
|
||
}
|
||
|
||
_logger.LogInformation("退款 {OutRefundNo} 状态更新成功", refundRecord.OutRefundNo);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理微信退款失败的订单
|
||
/// </summary>
|
||
private async Task ProcessWeChatRefundFailedAsync(
|
||
RefundRecord refundRecord,
|
||
WeChatRefundQueryResult queryResult,
|
||
DateTime now,
|
||
ISqlSugarRepository<RefundRecord> refundRecordRepository,
|
||
CancellationToken stoppingToken)
|
||
{
|
||
_logger.LogInformation("退款 {OutRefundNo} 失败,更新退款状态", refundRecord.OutRefundNo);
|
||
|
||
refundRecord.RefundStatus = queryResult.RefundStatus == "CLOSED" ? 3 : 2;
|
||
refundRecord.ErrorMessage = queryResult.Message ?? "退款失败";
|
||
refundRecord.WeChatResponse = queryResult.WeChatResponse ?? refundRecord.WeChatResponse;
|
||
refundRecord.UpdatedTime = now;
|
||
await refundRecordRepository.UpdateAsync(refundRecord);
|
||
|
||
_logger.LogInformation("退款 {OutRefundNo} 状态更新为失败成功", refundRecord.OutRefundNo);
|
||
}
|
||
|
||
public override void Dispose()
|
||
{
|
||
_timer.Dispose();
|
||
base.Dispose();
|
||
}
|
||
}
|