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 }