Files
CMS/src/CMSMicroservice.Application/DiscountShopCQ/Commands/CompleteOrderPayment/CompleteOrderPaymentCommandHandler.cs
T
masoodafar-web f3ac5ad7df fix: add missing UserWalletChangeLog for discount shop purchases and discount wallet charge
Bug: when buying from discount shop, DiscountBalance was deducted from DB
but no UserWalletChangeLog was created — making it invisible in wallet history.
Same issue existed for discount wallet top-up (charge).

Fixed in 3 handlers:
- PlaceOrderCommandHandler (fully paid by discount balance path)
- CompleteOrderPaymentCommandHandler (gateway + discount balance path)
- VerifyDiscountWalletChargeCommandHandler (discount wallet charge)
2026-02-23 22:59:00 +03:30

135 lines
4.8 KiB
C#

using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Enums;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace CMSMicroservice.Application.DiscountShopCQ.Commands.CompleteOrderPayment;
public class CompleteOrderPaymentCommandHandler : IRequestHandler<CompleteOrderPaymentCommand, CompleteOrderPaymentResponseDto>
{
private readonly IApplicationDbContext _context;
private readonly IInventoryService _inventoryService;
public CompleteOrderPaymentCommandHandler(
IApplicationDbContext context,
IInventoryService inventoryService)
{
_context = context;
_inventoryService = inventoryService;
}
public async Task<CompleteOrderPaymentResponseDto> Handle(CompleteOrderPaymentCommand request, CancellationToken cancellationToken)
{
var order = await _context.DiscountOrders
.Include(o => o.OrderDetails)
.ThenInclude(od => od.Product)
.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
if (order == null)
{
return new CompleteOrderPaymentResponseDto
{
Success = false,
Message = "سفارش یافت نشد"
};
}
var transaction = await _context.Transactions
.FirstOrDefaultAsync(t => t.Id == request.TransactionId, cancellationToken);
if (transaction == null)
{
return new CompleteOrderPaymentResponseDto
{
Success = false,
Message = "تراکنش یافت نشد"
};
}
if (request.PaymentSuccess)
{
// Update transaction
transaction.PaymentStatus = PaymentStatus.Success;
transaction.PaymentDate = DateTime.Now;
transaction.RefId = request.RefId;
// Update order
order.PaymentStatus = PaymentStatus.Success;
order.PaymentDate = DateTime.Now;
order.DeliveryStatus = DeliveryStatus.Pending;
// Deduct discount balance from user wallet
var userWallet = await _context.UserWallets
.FirstOrDefaultAsync(w => w.UserId == order.UserId, cancellationToken);
if (userWallet != null && order.DiscountBalanceUsed > 0)
{
userWallet.DiscountBalance -= order.DiscountBalanceUsed;
// ثبت لاگ تغییرات کیف پول
_context.UserWalletChangeLogs.Add(new Domain.Entities.UserWalletChangeLog
{
WalletId = userWallet.Id,
CurrentBalance = userWallet.Balance,
ChangeValue = 0,
CurrentNetworkBalance = userWallet.NetworkBalance,
ChangeNerworkValue = 0,
CurrentDiscountBalance = userWallet.DiscountBalance,
ChangeDiscountValue = -order.DiscountBalanceUsed,
IsIncrease = false,
RefrenceId = transaction.Id
});
}
// تایید فروش و کسر موجودی از طریق InventoryService
foreach (var orderDetail in order.OrderDetails)
{
await _inventoryService.ConfirmSaleAsync(
orderDetail.ProductId,
ProductType.DiscountProduct,
orderDetail.Count,
order.Id,
cancellationToken);
// افزایش تعداد فروش
orderDetail.Product.SaleCount += orderDetail.Count;
}
await _context.SaveChangesAsync(cancellationToken);
return new CompleteOrderPaymentResponseDto
{
Success = true,
Message = "پرداخت با موفقیت انجام شد",
OrderId = order.Id
};
}
else
{
// Payment failed - آزادسازی رزرو
foreach (var orderDetail in order.OrderDetails)
{
await _inventoryService.ReleaseReservationAsync(
orderDetail.ProductId,
ProductType.DiscountProduct,
orderDetail.Count,
order.Id,
cancellationToken);
}
transaction.PaymentStatus = PaymentStatus.Reject;
order.PaymentStatus = PaymentStatus.Reject;
order.DeliveryStatus = DeliveryStatus.Cancelled;
await _context.SaveChangesAsync(cancellationToken);
return new CompleteOrderPaymentResponseDto
{
Success = false,
Message = "پرداخت ناموفق بود",
OrderId = order.Id
};
}
}
}