using System.Text.Json;
using HoneyBox.Core.Interfaces;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
using HoneyBox.Model.Models.Lottery;
using HoneyBox.Model.Models.Payment;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace HoneyBox.Core.Services;
///
/// 支付回调服务实现
///
public class PaymentNotifyService : IPaymentNotifyService
{
private readonly HoneyBoxDbContext _dbContext;
private readonly IWechatPayService _wechatPayService;
private readonly IWechatPayV3Service _wechatPayV3Service;
private readonly IWechatPayConfigService _wechatPayConfigService;
private readonly IPaymentService _paymentService;
private readonly ILotteryEngine _lotteryEngine;
private readonly ILogger _logger;
///
/// 一番赏类订单类型列表
///
private static readonly string[] LotteryOrderTypes = new[]
{
OrderAttachType.OrderYfs,
OrderAttachType.OrderLts,
OrderAttachType.OrderZzs,
OrderAttachType.OrderFlw,
OrderAttachType.OrderScs
};
///
/// 无限赏类订单类型列表
///
private static readonly string[] InfiniteOrderTypes = new[]
{
OrderAttachType.OrderWxs,
OrderAttachType.OrderFbs
};
public PaymentNotifyService(
HoneyBoxDbContext dbContext,
IWechatPayService wechatPayService,
IWechatPayV3Service wechatPayV3Service,
IWechatPayConfigService wechatPayConfigService,
IPaymentService paymentService,
ILotteryEngine lotteryEngine,
ILogger logger)
{
_dbContext = dbContext;
_wechatPayService = wechatPayService;
_wechatPayV3Service = wechatPayV3Service;
_wechatPayConfigService = wechatPayConfigService;
_paymentService = paymentService;
_lotteryEngine = lotteryEngine;
_logger = logger;
}
///
public async Task HandleWechatNotifyAsync(string notifyBody, WechatPayNotifyHeaders? headers = null)
{
// 自动识别回调格式
var version = _wechatPayV3Service.DetectNotifyVersion(notifyBody);
_logger.LogInformation("检测到微信支付回调版本: {Version}", version);
return version switch
{
NotifyVersion.V3 when headers != null => await HandleWechatV3NotifyAsync(notifyBody, headers),
NotifyVersion.V3 => new NotifyResult
{
Success = false,
Message = "V3 回调缺少请求头",
JsonResponse = JsonSerializer.Serialize(new WechatPayV3NotifyResponse { Code = "FAIL", Message = "缺少请求头" })
},
NotifyVersion.V2 => await HandleWechatV2NotifyAsync(notifyBody),
_ => new NotifyResult
{
Success = false,
Message = "无法识别的回调格式",
XmlResponse = _wechatPayService.GenerateNotifyResponseXml("FAIL", "无法识别的回调格式")
}
};
}
///
public async Task HandleWechatV2NotifyAsync(string xmlData)
{
var successResponse = _wechatPayService.GenerateNotifyResponseXml("SUCCESS", "OK");
var failResponse = _wechatPayService.GenerateNotifyResponseXml("FAIL", "处理失败");
try
{
// 1. 检查XML数据是否为空
if (string.IsNullOrEmpty(xmlData))
{
_logger.LogWarning("微信支付 V2 回调数据为空");
return new NotifyResult
{
Success = false,
Message = "回调数据为空",
XmlResponse = failResponse
};
}
// 2. 解析XML数据
var notifyData = _wechatPayService.ParseNotifyXml(xmlData);
if (notifyData == null || string.IsNullOrEmpty(notifyData.OutTradeNo))
{
_logger.LogWarning("解析微信支付 V2 回调XML失败");
return new NotifyResult
{
Success = false,
Message = "解析回调数据失败",
XmlResponse = failResponse
};
}
var orderNo = notifyData.OutTradeNo;
var attach = notifyData.Attach;
_logger.LogInformation("收到微信支付 V2 回调: OrderNo={OrderNo}, Attach={Attach}, TotalFee={TotalFee}",
orderNo, attach, notifyData.TotalFee);
// 3. 验证签名
if (!_wechatPayService.VerifyNotifySign(notifyData))
{
_logger.LogWarning("微信支付 V2 回调签名验证失败: OrderNo={OrderNo}", orderNo);
return new NotifyResult
{
Success = false,
Message = "签名验证失败",
XmlResponse = failResponse
};
}
// 4. 检查返回状态
if (notifyData.ReturnCode != "SUCCESS" || notifyData.ResultCode != "SUCCESS")
{
_logger.LogWarning("微信支付回调状态异常: OrderNo={OrderNo}, ReturnCode={ReturnCode}, ResultCode={ResultCode}",
orderNo, notifyData.ReturnCode, notifyData.ResultCode);
// 即使支付失败,也返回成功响应,避免微信重复通知
return new NotifyResult
{
Success = true,
Message = "支付未成功",
XmlResponse = successResponse
};
}
// 5. 幂等性检查 - 检查订单是否已处理
if (await IsOrderProcessedAsync(orderNo))
{
_logger.LogInformation("订单已处理,跳过重复回调: OrderNo={OrderNo}", orderNo);
return new NotifyResult
{
Success = true,
Message = "订单已处理",
XmlResponse = successResponse
};
}
// 6. 记录回调通知
await RecordNotifyAsync(orderNo, notifyData);
// 7. 根据订单类型路由处理
var processResult = await RouteOrderProcessingAsync(orderNo, attach, notifyData);
if (processResult)
{
_logger.LogInformation("微信支付回调处理成功: OrderNo={OrderNo}", orderNo);
return new NotifyResult
{
Success = true,
Message = "处理成功",
XmlResponse = successResponse
};
}
else
{
_logger.LogWarning("微信支付回调处理失败: OrderNo={OrderNo}", orderNo);
// 处理失败也返回成功,避免微信重复通知,后续通过其他机制处理
return new NotifyResult
{
Success = false,
Message = "处理失败",
XmlResponse = successResponse
};
}
}
catch (Exception ex)
{
_logger.LogError(ex, "处理微信支付回调异常");
// 异常情况也返回成功,避免微信重复通知
return new NotifyResult
{
Success = false,
Message = $"处理异常: {ex.Message}",
XmlResponse = successResponse
};
}
}
///
public async Task HandleWechatV3NotifyAsync(string jsonData, WechatPayNotifyHeaders headers)
{
var successResponse = JsonSerializer.Serialize(new WechatPayV3NotifyResponse { Code = "SUCCESS", Message = "成功" });
var failResponse = JsonSerializer.Serialize(new WechatPayV3NotifyResponse { Code = "FAIL", Message = "处理失败" });
try
{
// 1. 检查数据是否为空
if (string.IsNullOrEmpty(jsonData))
{
_logger.LogWarning("微信支付 V3 回调数据为空");
return new NotifyResult
{
Success = false,
Message = "回调数据为空",
JsonResponse = failResponse
};
}
// 2. 验证签名
if (!_wechatPayV3Service.VerifyNotifySignature(
headers.Timestamp,
headers.Nonce,
jsonData,
headers.Signature,
headers.Serial))
{
_logger.LogWarning("微信支付 V3 回调签名验证失败");
return new NotifyResult
{
Success = false,
Message = "签名验证失败",
JsonResponse = failResponse
};
}
// 3. 解析回调通知
var notification = JsonSerializer.Deserialize(jsonData);
if (notification == null || notification.Resource == null)
{
_logger.LogWarning("解析微信支付 V3 回调数据失败");
return new NotifyResult
{
Success = false,
Message = "解析回调数据失败",
JsonResponse = failResponse
};
}
_logger.LogInformation("收到微信支付 V3 回调: Id={Id}, EventType={EventType}",
notification.Id, notification.EventType);
// 4. 获取商户配置并解密数据
var merchantConfig = _wechatPayConfigService.GetDefaultConfig();
if (string.IsNullOrEmpty(merchantConfig.ApiV3Key))
{
_logger.LogError("APIv3 密钥未配置");
return new NotifyResult
{
Success = false,
Message = "APIv3 密钥未配置",
JsonResponse = failResponse
};
}
var decryptedJson = _wechatPayV3Service.DecryptNotifyResource(
notification.Resource.Ciphertext,
notification.Resource.Nonce,
notification.Resource.AssociatedData,
merchantConfig.ApiV3Key);
_logger.LogDebug("V3 回调解密成功: {DecryptedJson}", decryptedJson);
// 5. 解析支付结果
var paymentResult = JsonSerializer.Deserialize(decryptedJson);
if (paymentResult == null || string.IsNullOrEmpty(paymentResult.OutTradeNo))
{
_logger.LogWarning("解析 V3 支付结果失败");
return new NotifyResult
{
Success = false,
Message = "解析支付结果失败",
JsonResponse = failResponse
};
}
var orderNo = paymentResult.OutTradeNo;
var attach = paymentResult.Attach;
_logger.LogInformation("V3 支付结果: OrderNo={OrderNo}, TradeState={TradeState}, Attach={Attach}",
orderNo, paymentResult.TradeState, attach);
// 6. 检查支付状态
if (paymentResult.TradeState != WechatPayV3TradeState.Success)
{
_logger.LogWarning("V3 支付状态非成功: OrderNo={OrderNo}, TradeState={TradeState}",
orderNo, paymentResult.TradeState);
// 即使支付失败,也返回成功响应,避免微信重复通知
return new NotifyResult
{
Success = true,
Message = "支付未成功",
JsonResponse = successResponse
};
}
// 7. 幂等性检查 - 检查订单是否已处理
if (await IsOrderProcessedAsync(orderNo))
{
_logger.LogInformation("订单已处理,跳过重复回调: OrderNo={OrderNo}", orderNo);
return new NotifyResult
{
Success = true,
Message = "订单已处理",
JsonResponse = successResponse
};
}
// 8. 记录回调通知(转换为 V2 格式以复用现有逻辑)
var notifyData = ConvertV3ToV2NotifyData(paymentResult);
await RecordNotifyAsync(orderNo, notifyData);
// 9. 根据订单类型路由处理
var processResult = await RouteOrderProcessingAsync(orderNo, attach, notifyData);
if (processResult)
{
_logger.LogInformation("微信支付 V3 回调处理成功: OrderNo={OrderNo}", orderNo);
return new NotifyResult
{
Success = true,
Message = "处理成功",
JsonResponse = successResponse
};
}
else
{
_logger.LogWarning("微信支付 V3 回调处理失败: OrderNo={OrderNo}", orderNo);
// 处理失败也返回成功,避免微信重复通知
return new NotifyResult
{
Success = false,
Message = "处理失败",
JsonResponse = successResponse
};
}
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "V3 回调解密失败");
return new NotifyResult
{
Success = false,
Message = $"解密失败: {ex.Message}",
JsonResponse = failResponse
};
}
catch (Exception ex)
{
_logger.LogError(ex, "处理微信支付 V3 回调异常");
// 异常情况也返回成功,避免微信重复通知
return new NotifyResult
{
Success = false,
Message = $"处理异常: {ex.Message}",
JsonResponse = successResponse
};
}
}
///
/// 将 V3 支付结果转换为 V2 格式(复用现有处理逻辑)
///
private static WechatNotifyData ConvertV3ToV2NotifyData(WechatPayV3PaymentResult v3Result)
{
return new WechatNotifyData
{
ReturnCode = "SUCCESS",
ResultCode = v3Result.TradeState == WechatPayV3TradeState.Success ? "SUCCESS" : "FAIL",
OutTradeNo = v3Result.OutTradeNo,
TransactionId = v3Result.TransactionId,
TotalFee = v3Result.Amount.Total,
OpenId = v3Result.Payer.OpenId,
Attach = v3Result.Attach,
NonceStr = Guid.NewGuid().ToString("N")[..32]
};
}
///
/// 根据订单类型路由到对应的处理方法
///
/// 订单号
/// 附加数据(订单类型)
/// 回调数据
/// 是否处理成功
private async Task RouteOrderProcessingAsync(string orderNo, string attach, WechatNotifyData notifyData)
{
try
{
// 获取用户信息
var user = await _dbContext.Users.FirstOrDefaultAsync(u => u.OpenId == notifyData.OpenId);
if (user == null)
{
_logger.LogWarning("未找到用户: OpenId={OpenId}", notifyData.OpenId);
return false;
}
// 记录支付流水
await RecordPaymentAsync(user.Id, orderNo, notifyData.TotalFee / 100m, attach);
// 根据attach类型路由处理
if (attach == OrderAttachType.UserRecharge)
{
// 余额充值
return await ProcessRechargeOrderAsync(orderNo);
}
else if (LotteryOrderTypes.Contains(attach))
{
// 一番赏类订单
return await ProcessLotteryOrderByOrderNoAsync(orderNo);
}
else if (InfiniteOrderTypes.Contains(attach))
{
// 无限赏类订单
return await ProcessInfiniteOrderByOrderNoAsync(orderNo);
}
else if (attach == OrderAttachType.OrderCkj)
{
// 抽卡机订单
return await ProcessCardExtractorOrderByOrderNoAsync(orderNo);
}
else if (attach == OrderAttachType.OrderListSend)
{
// 发货运费订单
return await ProcessShippingFeeOrderAsync(orderNo);
}
else
{
_logger.LogWarning("未知的订单类型: Attach={Attach}, OrderNo={OrderNo}", attach, orderNo);
return false;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "路由订单处理异常: OrderNo={OrderNo}, Attach={Attach}", orderNo, attach);
return false;
}
}
///
/// 记录支付流水(委托给PaymentService)
///
private async Task RecordPaymentAsync(int userId, string orderNo, decimal amount, string content)
{
// 根据content确定支付说明
var paymentContent = string.IsNullOrEmpty(content) ? "微信支付" : content;
// 委托给PaymentService处理
var result = await _paymentService.RecordPaymentAsync(userId, orderNo, amount, PaymentType.WechatPay, paymentContent);
if (!result)
{
_logger.LogWarning("记录支付流水失败: UserId={UserId}, OrderNo={OrderNo}", userId, orderNo);
}
}
///
/// 根据订单号处理一番赏订单
///
private async Task ProcessLotteryOrderByOrderNoAsync(string orderNo)
{
var order = await _dbContext.Orders
.FirstOrDefaultAsync(o => o.OrderNum == orderNo && o.Status == 0);
if (order == null)
{
_logger.LogWarning("未找到待支付的一番赏订单: OrderNo={OrderNo}", orderNo);
return false;
}
return await ProcessLotteryOrderAsync(order.Id, order.UserId, order.GoodsId, order.Num);
}
///
/// 根据订单号处理无限赏订单
///
private async Task ProcessInfiniteOrderByOrderNoAsync(string orderNo)
{
var order = await _dbContext.Orders
.FirstOrDefaultAsync(o => o.OrderNum == orderNo && o.Status == 0);
if (order == null)
{
_logger.LogWarning("未找到待支付的无限赏订单: OrderNo={OrderNo}", orderNo);
return false;
}
return await ProcessInfiniteOrderAsync(order.Id, order.UserId, order.GoodsId);
}
///
/// 根据订单号处理抽卡机订单
///
private async Task ProcessCardExtractorOrderByOrderNoAsync(string orderNo)
{
var order = await _dbContext.Orders
.FirstOrDefaultAsync(o => o.OrderNum == orderNo && o.Status == 0 && o.OrderType == 4);
if (order == null)
{
_logger.LogWarning("未找到待支付的抽卡机订单: OrderNo={OrderNo}", orderNo);
return false;
}
return await ProcessCardExtractorOrderAsync(order.Id, order.UserId, order.GoodsId);
}
///
public async Task ProcessLotteryOrderAsync(int orderId, int userId, int goodsId, int num)
{
using var transaction = await _dbContext.Database.BeginTransactionAsync();
try
{
// 1. 查找订单 - 支持一番赏类订单类型 (1=一番赏, 3=擂台赏, 5=转转赏, 6=福利屋, 11=商城赏, 15=福利屋特殊, 10=商城赏特殊)
var validOrderTypes = new byte[] { 1, 3, 5, 6, 11, 15, 10 };
var order = await _dbContext.Orders
.FirstOrDefaultAsync(o => o.Id == orderId
&& o.UserId == userId
&& o.GoodsId == goodsId
&& o.Num == num
&& o.Status == 0
&& validOrderTypes.Contains(o.OrderType));
if (order == null)
{
_logger.LogWarning("未找到待支付的一番赏订单: OrderId={OrderId}, UserId={UserId}, GoodsId={GoodsId}, Num={Num}",
orderId, userId, goodsId, num);
return false;
}
var goodsTitle = order.GoodsTitle ?? "商品";
var content = $"购买盒子{goodsTitle}";
// 2. 更新订单状态为已支付
order.Status = 1;
order.PayTime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
order.UpdatedAt = DateTime.Now;
// 3. 扣减用户资产(余额、积分、哈尼券)
// 扣减余额
if (order.UseMoney > 0)
{
var balanceResult = await _paymentService.DeductBalanceAsync(order.UserId, order.UseMoney, content, order.OrderNum);
if (!balanceResult.Success)
{
_logger.LogWarning("扣减余额失败: UserId={UserId}, Amount={Amount}, Message={Message}",
order.UserId, order.UseMoney, balanceResult.Message);
// 继续处理,不中断流程(PHP代码也是这样处理的)
}
else
{
_logger.LogDebug("扣减余额成功: UserId={UserId}, Amount={Amount}", order.UserId, order.UseMoney);
}
}
// 扣减积分(吧唧币)
if (order.UseIntegral > 0)
{
var integralResult = await _paymentService.DeductIntegralAsync(order.UserId, order.UseIntegral, content, order.OrderNum);
if (!integralResult.Success)
{
_logger.LogWarning("扣减积分失败: UserId={UserId}, Amount={Amount}, Message={Message}",
order.UserId, order.UseIntegral, integralResult.Message);
}
else
{
_logger.LogDebug("扣减积分成功: UserId={UserId}, Amount={Amount}", order.UserId, order.UseIntegral);
}
}
// 扣减哈尼券
if (order.UseMoney2 > 0)
{
var money2Result = await _paymentService.DeductMoney2Async(order.UserId, order.UseMoney2, content, order.OrderNum);
if (!money2Result.Success)
{
_logger.LogWarning("扣减哈尼券失败: UserId={UserId}, Amount={Amount}, Message={Message}",
order.UserId, order.UseMoney2, money2Result.Message);
}
else
{
_logger.LogDebug("扣减哈尼券成功: UserId={UserId}, Amount={Amount}", order.UserId, order.UseMoney2);
}
}
// 4. 更新优惠券状态为已使用
if (order.CouponId.HasValue && order.CouponId.Value > 0)
{
await UpdateCouponStatusAsync(order.CouponId.Value);
}
// 5. 更新订单通知状态
await UpdateOrderNotifyStatusAsync(order.OrderNum, 1, "处理成功");
await _dbContext.SaveChangesAsync();
await transaction.CommitAsync();
_logger.LogInformation("一番赏订单支付处理成功: OrderId={OrderId}, UserId={UserId}, GoodsId={GoodsId}, Num={Num}, OrderType={OrderType}",
orderId, userId, goodsId, num, order.OrderType);
// 6. 执行普通抽奖逻辑
await ExecuteLotteryAsync(userId, orderId, goodsId, order.OrderType, num, order.PrizeNum, order.OrderNum);
return true;
}
catch (Exception ex)
{
await transaction.RollbackAsync();
_logger.LogError(ex, "处理一番赏订单失败: OrderId={OrderId}", orderId);
// 标记订单为卡单状态
await MarkOrderAsStuckAsync(orderId);
return false;
}
}
///
/// 执行普通抽奖逻辑(一番赏、擂台赏、转转赏等)
///
private async Task ExecuteLotteryAsync(int userId, int orderId, int goodsId, int orderType, int num, int prizeNum, string orderNum)
{
try
{
var drawRequest = new LotteryDrawRequest
{
UserId = userId,
GoodsId = goodsId,
Num = num,
OrderId = orderId,
OrderNum = orderNum,
OrderType = orderType,
Source = 1 // 抽奖获得
};
// 执行多次抽奖
var results = await _lotteryEngine.DrawMultipleAsync(drawRequest, prizeNum);
var successCount = results.Count(r => r.Success);
_logger.LogInformation("普通抽奖完成: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}, Num={Num}, PrizeNum={PrizeNum}, SuccessCount={SuccessCount}",
userId, orderId, goodsId, num, prizeNum, successCount);
if (successCount == 0)
{
_logger.LogWarning("普通抽奖全部失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}",
userId, orderId, goodsId);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "执行普通抽奖失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}",
userId, orderId, goodsId);
// 抽奖失败不影响支付回调处理,但需要记录日志以便后续处理
}
}
///
public async Task ProcessInfiniteOrderAsync(int orderId, int userId, int goodsId)
{
using var transaction = await _dbContext.Database.BeginTransactionAsync();
try
{
// 1. 查找订单 - 支持无限赏类订单类型
// 无限赏订单类型: 2=无限赏, 7=翻倍赏, 8=领主赏, 9=秘宝赏, 10=商城赏, 17=特殊无限赏
var validOrderTypes = new byte[] { 2, 7, 8, 9, 10, 17 };
var order = await _dbContext.Orders
.FirstOrDefaultAsync(o => o.Id == orderId
&& o.UserId == userId
&& o.GoodsId == goodsId
&& o.Status == 0);
// PHP逻辑: 如果num=0找不到订单,尝试num=1(针对order_type=10的商城赏)
if (order == null)
{
_logger.LogWarning("未找到待支付的无限赏订单: OrderId={OrderId}, UserId={UserId}, GoodsId={GoodsId}",
orderId, userId, goodsId);
return false;
}
var goodsTitle = order.GoodsTitle ?? "商品";
var content = $"购买盒子{goodsTitle}";
// 2. 更新订单状态为已支付
order.Status = 1;
order.PayTime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
order.UpdatedAt = DateTime.Now;
// 3. 扣减用户资产(余额、积分、哈尼券)
// 扣减余额
if (order.UseMoney > 0)
{
var balanceResult = await _paymentService.DeductBalanceAsync(order.UserId, order.UseMoney, content, order.OrderNum);
if (!balanceResult.Success)
{
_logger.LogWarning("扣减余额失败: UserId={UserId}, Amount={Amount}, Message={Message}",
order.UserId, order.UseMoney, balanceResult.Message);
}
else
{
_logger.LogDebug("扣减余额成功: UserId={UserId}, Amount={Amount}", order.UserId, order.UseMoney);
}
}
// 扣减积分(吧唧币)
if (order.UseIntegral > 0)
{
var integralResult = await _paymentService.DeductIntegralAsync(order.UserId, order.UseIntegral, content, order.OrderNum);
if (!integralResult.Success)
{
_logger.LogWarning("扣减积分失败: UserId={UserId}, Amount={Amount}, Message={Message}",
order.UserId, order.UseIntegral, integralResult.Message);
}
else
{
_logger.LogDebug("扣减积分成功: UserId={UserId}, Amount={Amount}", order.UserId, order.UseIntegral);
}
}
// 扣减哈尼券
if (order.UseMoney2 > 0)
{
var money2Result = await _paymentService.DeductMoney2Async(order.UserId, order.UseMoney2, content, order.OrderNum);
if (!money2Result.Success)
{
_logger.LogWarning("扣减哈尼券失败: UserId={UserId}, Amount={Amount}, Message={Message}",
order.UserId, order.UseMoney2, money2Result.Message);
}
else
{
_logger.LogDebug("扣减哈尼券成功: UserId={UserId}, Amount={Amount}", order.UserId, order.UseMoney2);
}
}
// 4. 更新优惠券状态为已使用
if (order.CouponId.HasValue && order.CouponId.Value > 0)
{
await UpdateCouponStatusAsync(order.CouponId.Value);
}
// 5. 更新订单通知状态
await UpdateOrderNotifyStatusAsync(order.OrderNum, 1, "处理成功");
await _dbContext.SaveChangesAsync();
await transaction.CommitAsync();
_logger.LogInformation("无限赏订单支付处理成功: OrderId={OrderId}, UserId={UserId}, GoodsId={GoodsId}, OrderType={OrderType}, PrizeNum={PrizeNum}",
orderId, userId, goodsId, order.OrderType, order.PrizeNum);
// 6. 执行无限赏抽奖逻辑
await ExecuteInfiniteLotteryAsync(userId, orderId, goodsId, order.OrderType, order.PrizeNum, order.OrderNum);
return true;
}
catch (Exception ex)
{
await transaction.RollbackAsync();
_logger.LogError(ex, "处理无限赏订单失败: OrderId={OrderId}", orderId);
// 标记订单为卡单状态
await MarkOrderAsStuckAsync(orderId);
return false;
}
}
///
/// 执行无限赏抽奖逻辑
///
private async Task ExecuteInfiniteLotteryAsync(int userId, int orderId, int goodsId, int orderType, int prizeNum, string orderNum)
{
try
{
var drawRequest = new LotteryDrawRequest
{
UserId = userId,
GoodsId = goodsId,
Num = 0, // 无限赏固定为0
OrderId = orderId,
OrderNum = orderNum,
OrderType = orderType,
Source = 1 // 抽奖获得
};
// 执行多次抽奖
var results = await _lotteryEngine.DrawInfiniteMultipleAsync(drawRequest, prizeNum);
var successCount = results.Count(r => r.Success);
_logger.LogInformation("无限赏抽奖完成: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}, PrizeNum={PrizeNum}, SuccessCount={SuccessCount}",
userId, orderId, goodsId, prizeNum, successCount);
if (successCount == 0)
{
_logger.LogWarning("无限赏抽奖全部失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}",
userId, orderId, goodsId);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "执行无限赏抽奖失败: UserId={UserId}, OrderId={OrderId}, GoodsId={GoodsId}",
userId, orderId, goodsId);
// 抽奖失败不影响支付回调处理,但需要记录日志以便后续处理
}
}
///
public async Task ProcessRechargeOrderAsync(string orderNo)
{
using var transaction = await _dbContext.Database.BeginTransactionAsync();
try
{
// 1. 查找充值订单 - 状态为1(待支付)
var rechargeOrder = await _dbContext.UserRecharges
.FirstOrDefaultAsync(r => r.OrderNum == orderNo && r.Status == 1);
if (rechargeOrder == null)
{
_logger.LogWarning("未找到待支付的充值订单: OrderNo={OrderNo}", orderNo);
return false;
}
var userId = rechargeOrder.UserId;
var money = rechargeOrder.Money;
// 2. 更新充值订单状态为已完成
rechargeOrder.Status = 2; // 2=已完成
rechargeOrder.PayTime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
// 3. 增加用户余额
var addBalanceResult = await _paymentService.AddBalanceAsync(userId, money, "在线充值", orderNo);
if (!addBalanceResult)
{
_logger.LogWarning("增加用户余额失败: UserId={UserId}, Amount={Amount}, OrderNo={OrderNo}",
userId, money, orderNo);
await transaction.RollbackAsync();
return false;
}
// 4. 记录微信支付流水
var profitPay = new ProfitPay
{
UserId = userId,
OrderNum = orderNo,
ChangeMoney = money,
Content = "微信支付",
PayType = (byte)PaymentType.WechatPay,
CreatedAt = DateTime.Now
};
_dbContext.ProfitPays.Add(profitPay);
// 5. 更新订单通知状态
await UpdateOrderNotifyStatusAsync(orderNo, 1, "处理成功");
await _dbContext.SaveChangesAsync();
await transaction.CommitAsync();
_logger.LogInformation("充值订单处理成功: OrderNo={OrderNo}, UserId={UserId}, Money={Money}",
orderNo, userId, money);
return true;
}
catch (Exception ex)
{
await transaction.RollbackAsync();
_logger.LogError(ex, "处理充值订单失败: OrderNo={OrderNo}", orderNo);
return false;
}
}
///
public async Task ProcessShippingFeeOrderAsync(string orderNo)
{
using var transaction = await _dbContext.Database.BeginTransactionAsync();
try
{
// 1. 查找发货记录
var sendRecord = await _dbContext.OrderItemsSends
.FirstOrDefaultAsync(s => s.SendNum == orderNo && s.Status == 0);
if (sendRecord == null)
{
_logger.LogWarning("未找到待支付的发货记录: OrderNo={OrderNo}", orderNo);
return false;
}
// 2. 更新发货记录状态为待发货
sendRecord.Status = 1; // 0待支付 -> 1待发货
sendRecord.PayTime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
sendRecord.UpdatedAt = DateTime.Now;
// 3. 更新关联的订单项状态
var orderItems = await _dbContext.OrderItems
.Where(oi => oi.UserId == sendRecord.UserId
&& oi.Status == 0
&& oi.GoodslistType == 1
&& oi.SendNum == sendRecord.SendNum)
.ToListAsync();
foreach (var item in orderItems)
{
item.Status = 2; // 选择发货
item.ChoiceTime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
}
// 4. 更新订单通知状态
await UpdateOrderNotifyStatusAsync(orderNo, 1, "处理成功");
await _dbContext.SaveChangesAsync();
await transaction.CommitAsync();
_logger.LogInformation("发货运费订单处理成功: OrderNo={OrderNo}, UserId={UserId}",
orderNo, sendRecord.UserId);
return true;
}
catch (Exception ex)
{
await transaction.RollbackAsync();
_logger.LogError(ex, "处理发货运费订单失败: OrderNo={OrderNo}", orderNo);
return false;
}
}
///
public async Task ProcessCardExtractorOrderAsync(int orderId, int userId, int goodsId)
{
using var transaction = await _dbContext.Database.BeginTransactionAsync();
try
{
// 1. 查找订单
var order = await _dbContext.Orders
.FirstOrDefaultAsync(o => o.Id == orderId
&& o.UserId == userId
&& o.GoodsId == goodsId
&& o.Status == 0
&& o.OrderType == 4);
if (order == null)
{
_logger.LogWarning("未找到待支付的抽卡机订单: OrderId={OrderId}, UserId={UserId}", orderId, userId);
return false;
}
// 2. 更新订单状态为已支付
order.Status = 1;
order.PayTime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
order.UpdatedAt = DateTime.Now;
// 3. 扣减用户资产
await DeductUserAssetsAsync(order);
// 4. 更新优惠券状态
if (order.CouponId.HasValue && order.CouponId.Value > 0)
{
await UpdateCouponStatusAsync(order.CouponId.Value);
}
// 5. 更新订单通知状态
await UpdateOrderNotifyStatusAsync(order.OrderNum, 1, "处理成功");
await _dbContext.SaveChangesAsync();
await transaction.CommitAsync();
_logger.LogInformation("抽卡机订单处理成功: OrderId={OrderId}, UserId={UserId}", orderId, userId);
// TODO: 触发抽卡机抽奖逻辑
return true;
}
catch (Exception ex)
{
await transaction.RollbackAsync();
_logger.LogError(ex, "处理抽卡机订单失败: OrderId={OrderId}", orderId);
// 标记订单为卡单状态
await MarkOrderAsStuckAsync(orderId);
return false;
}
}
///
public async Task IsOrderProcessedAsync(string orderNo)
{
var notify = await _dbContext.OrderNotifies
.FirstOrDefaultAsync(n => n.OrderNo == orderNo && n.Status == 1);
return notify != null;
}
///
public async Task RecordNotifyAsync(string orderNo, WechatNotifyData notifyData)
{
try
{
// 检查是否已存在记录
var existingNotify = await _dbContext.OrderNotifies
.FirstOrDefaultAsync(n => n.OrderNo == orderNo);
if (existingNotify != null)
{
// 更新现有记录
existingNotify.TransactionId = notifyData.TransactionId;
existingNotify.PayTime = DateTime.Now;
existingNotify.PayAmount = notifyData.TotalFee / 100m;
existingNotify.RawData = null; // 可选:存储原始XML
existingNotify.UpdatedAt = DateTime.Now;
}
else
{
// 创建新记录
var notify = new OrderNotify
{
OrderNo = orderNo,
TransactionId = notifyData.TransactionId,
NonceStr = notifyData.NonceStr,
PayTime = DateTime.Now,
PayAmount = notifyData.TotalFee / 100m,
Status = 0, // 待处理
Attach = notifyData.Attach,
OpenId = notifyData.OpenId,
RawData = null,
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now
};
_dbContext.OrderNotifies.Add(notify);
}
await _dbContext.SaveChangesAsync();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "记录支付回调通知失败: {OrderNo}", orderNo);
return false;
}
}
#region Private Helper Methods
///
/// 扣减用户资产(余额、积分、哈尼券)
///
private async Task DeductUserAssetsAsync(Order order)
{
var user = await _dbContext.Users.FirstOrDefaultAsync(u => u.Id == order.UserId);
if (user == null)
{
_logger.LogWarning("扣减资产时未找到用户: UserId={UserId}", order.UserId);
return;
}
var goodsTitle = order.GoodsTitle ?? "商品";
var content = $"购买盒子{goodsTitle}";
// 扣减余额
if (order.UseMoney > 0)
{
await _paymentService.DeductBalanceAsync(order.UserId, order.UseMoney, content);
_logger.LogDebug("扣减余额: UserId={UserId}, Amount={Amount}", order.UserId, order.UseMoney);
}
// 扣减积分(吧唧币)
if (order.UseIntegral > 0)
{
await _paymentService.DeductIntegralAsync(order.UserId, order.UseIntegral, content);
_logger.LogDebug("扣减积分: UserId={UserId}, Amount={Amount}", order.UserId, order.UseIntegral);
}
// 扣减哈尼券
if (order.UseMoney2 > 0)
{
await _paymentService.DeductMoney2Async(order.UserId, order.UseMoney2, content);
_logger.LogDebug("扣减哈尼券: UserId={UserId}, Amount={Amount}", order.UserId, order.UseMoney2);
}
}
///
/// 更新优惠券状态为已使用
///
private async Task UpdateCouponStatusAsync(int couponId)
{
var coupon = await _dbContext.CouponReceives
.FirstOrDefaultAsync(c => c.Id == couponId && c.Status == 0);
if (coupon != null)
{
coupon.Status = 1; // 已使用
_logger.LogDebug("更新优惠券状态: CouponId={CouponId}", couponId);
}
}
///
/// 更新订单通知状态
///
private async Task UpdateOrderNotifyStatusAsync(string orderNo, byte status, string? message = null)
{
var notify = await _dbContext.OrderNotifies
.FirstOrDefaultAsync(n => n.OrderNo == orderNo);
if (notify != null)
{
notify.Status = status;
notify.ErrorMessage = message;
notify.UpdatedAt = DateTime.Now;
}
}
///
/// 标记订单为卡单状态
///
private async Task MarkOrderAsStuckAsync(int orderId)
{
try
{
var order = await _dbContext.Orders.FirstOrDefaultAsync(o => o.Id == orderId);
if (order != null)
{
order.KdIs = 1; // 标记为卡单
order.UpdatedAt = DateTime.Now;
await _dbContext.SaveChangesAsync();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "标记订单卡单状态失败: OrderId={OrderId}", orderId);
}
}
#endregion
}