Files
CMS/src/CMSMicroservice.Application/DiscountShopCQ/Commands/CompleteOrderPayment/CompleteOrderPaymentCommandHandler.cs
T
masoodafar-web ef1716e243
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 8m22s
fix: proper DeliveryStatus mapping + cancel delivery on failed payment
- Added MapDeliveryStatus() to correctly map Domain→Proto enum values
- Domain Pending(1) was incorrectly cast to Proto PROCESSING(1) instead of PROCESSING
- Set DeliveryStatus=Cancelled when payment fails (CompleteOrderPaymentCommandHandler)
- Set DeliveryStatus=Cancelled when order expires (ExpirePendingOrdersService)
2026-02-17 00:41:48 +03:30

121 lines
4.1 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)
{
userWallet.DiscountBalance -= order.DiscountBalanceUsed;
}
// تایید فروش و کسر موجودی از طریق 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
};
}
}
}