using CMSMicroservice.Application.Common.Exceptions; using CMSMicroservice.Application.Common.Interfaces; using CMSMicroservice.Application.Common.Models; using CMSMicroservice.Domain.Entities; using CMSMicroservice.Domain.Enums; using MediatR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace CMSMicroservice.Application.WalletCQ.Commands.VerifyDiscountWalletCharge; public class VerifyDiscountWalletChargeCommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IPaymentGatewayService _paymentGateway; private readonly ILogger _logger; public VerifyDiscountWalletChargeCommandHandler( IApplicationDbContext context, IPaymentGatewayService paymentGateway, ILogger logger) { _context = context; _paymentGateway = paymentGateway; _logger = logger; } public async Task Handle( VerifyDiscountWalletChargeCommand request, CancellationToken cancellationToken) { try { _logger.LogInformation( "Verifying discount wallet charge. UserId: {UserId}, Amount: {Amount}, Authority: {Authority}", request.UserId, request.Amount, request.Authority ); // 1. بررسی کاربر var user = await _context.Users .FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken); if (user == null) { _logger.LogWarning("User not found: {UserId}", request.UserId); throw new NotFoundException(nameof(User), request.UserId); } // 2. Verify با درگاه var verifyResult = await _paymentGateway.VerifyPaymentAsync( request.Authority, request.Authority // verificationToken - در بعضی درگاه‌ها مثل زرین‌پال همان Authority است ); if (!verifyResult.IsSuccess) { _logger.LogWarning( "Discount wallet charge verification failed for UserId {UserId}: {Message}", request.UserId, verifyResult.Message ); throw new Exception($"تراکنش ناموفق: {verifyResult.Message}"); } // 3. شارژ DiscountBalance var wallet = await _context.UserWallets .FirstOrDefaultAsync(w => w.UserId == user.Id, cancellationToken); if (wallet == null) { _logger.LogError("Wallet not found for UserId: {UserId}", request.UserId); throw new NotFoundException($"کیف پول کاربر با شناسه {request.UserId} یافت نشد"); } var oldBalance = wallet.DiscountBalance; wallet.DiscountBalance += request.Amount; _logger.LogInformation( "Charging discount balance for UserId {UserId}: {OldBalance} -> {NewBalance}", request.UserId, oldBalance, wallet.DiscountBalance ); // 4. ثبت Transaction var transaction = new Transactions { Amount = request.Amount, Description = $"شارژ کیف پول تخفیفی - کاربر {user.Id}", PaymentStatus = PaymentStatus.Success, PaymentDate = DateTime.UtcNow, RefId = verifyResult.RefId, Type = TransactionType.DiscountWalletCharge }; _context.Transactionss.Add(transaction); await _context.SaveChangesAsync(cancellationToken); _logger.LogInformation( "Discount wallet charged successfully. UserId: {UserId}, TransactionId: {TransactionId}, RefId: {RefId}", user.Id, transaction.Id, verifyResult.RefId ); return true; } catch (Exception ex) { _logger.LogError( ex, "Error in VerifyDiscountWalletChargeCommand for UserId: {UserId}", request.UserId ); throw; } } }