Files
FrontOffice/src/FrontOffice.Main/Utilities/DiscountOrderService.cs
T
masoodafar-web ff3696cda3
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 2m37s
feat: implement payment verification methods for magic wallet and discount wallet
2026-02-28 03:27:58 +03:30

254 lines
7.9 KiB
C#

using CMSMicroservice.Protobuf.Protos.DiscountOrder;
using Google.Protobuf.WellKnownTypes;
using MudBlazor;
namespace FrontOffice.Main.Utilities;
// ── DTOs ──
public record DiscountOrderSummary(
long Id,
string OrderNumber,
long TotalPrice,
long DiscountBalanceUsed,
long GatewayAmount,
bool PaymentCompleted,
int PaymentStatus,
int DeliveryStatus,
string? TrackingCode,
int ItemsCount,
DateTime Created);
public record DiscountOrderDetail(
long Id,
string OrderNumber,
long TotalPrice,
long DiscountBalanceUsed,
long GatewayAmount,
bool PaymentCompleted,
int PaymentStatus,
string? TransactionId,
int DeliveryStatus,
string? TrackingCode,
string? Notes,
string? AdminNotes,
DiscountOrderAddress? Address,
List<DiscountOrderItem> Items,
DateTime Created);
public record DiscountOrderAddress(
long Id, string Title, string Address, string PostalCode, string? Phone);
public record DiscountOrderItem(
long ProductId,
string Title,
long UnitPrice,
int MaxDiscountPercent,
int Count,
long TotalPrice,
long DiscountAmount,
long FinalPrice);
public record PlaceDiscountOrderResult(
bool Success,
string Message,
long OrderId,
long GatewayAmount,
string? PaymentUrl);
public record DiscountOrderListResult(
List<DiscountOrderSummary> Orders,
int TotalCount,
int TotalPages,
int CurrentPage);
// ── Service ──
public class DiscountOrderService
{
private readonly DiscountOrderContract.DiscountOrderContractClient _client;
public DiscountOrderService(DiscountOrderContract.DiscountOrderContractClient client)
{
_client = client;
}
public async Task<PlaceDiscountOrderResult> PlaceOrderAsync(long addressId, long discountBalanceToUse, string? notes = null)
{
try
{
var request = new PlaceOrderRequest
{
UserAddressId = addressId,
DiscountBalanceToUse = discountBalanceToUse
};
if (!string.IsNullOrWhiteSpace(notes))
request.Notes = notes;
var response = await _client.PlaceOrderAsync(request);
return new PlaceDiscountOrderResult(
Success: response.Success,
Message: response.Message ?? string.Empty,
OrderId: response.OrderId,
GatewayAmount: response.GatewayAmount,
PaymentUrl: response.PaymentUrl);
}
catch (Exception ex)
{
return new PlaceDiscountOrderResult(false, ex.Message, 0, 0, null);
}
}
public async Task<bool> CompletePaymentAsync(long orderId, string? transactionId, bool success)
{
try
{
var response = await _client.CompleteOrderPaymentAsync(new CompleteOrderPaymentRequest
{
OrderId = orderId,
TransactionId = transactionId,
PaymentSuccess = success
});
return response.Success;
}
catch { return false; }
}
public async Task<(bool Success, string Message, long OrderId)> VerifyDiscountOrderPaymentAsync(
long orderId, string authority, string status)
{
try
{
var response = await _client.CustomerVerifyDiscountOrderPaymentAsync(
new CustomerVerifyDiscountOrderPaymentRequest
{
OrderId = orderId,
Authority = authority,
Status = status
});
return (response.Success, response.Message, response.OrderId);
}
catch (Grpc.Core.RpcException ex)
{
return (false, ex.Status.Detail ?? "خطا در بررسی وضعیت پرداخت", orderId);
}
}
public async Task<DiscountOrderListResult> GetUserOrdersAsync(int page = 1, int pageSize = 10)
{
try
{
var response = await _client.GetUserOrdersAsync(new GetUserOrdersRequest
{
PageNumber = page,
PageSize = pageSize
});
var orders = response.Models.Select(m => new DiscountOrderSummary(
Id: m.Id,
OrderNumber: m.OrderNumber ?? string.Empty,
TotalPrice: m.TotalPrice,
DiscountBalanceUsed: m.DiscountBalanceUsed,
GatewayAmount: m.GatewayAmount,
PaymentCompleted: m.PaymentCompleted,
PaymentStatus: (int)m.PaymentStatus,
DeliveryStatus: (int)m.DeliveryStatus,
TrackingCode: m.TrackingCode,
ItemsCount: m.ItemsCount,
Created: m.Created?.ToDateTime() ?? DateTime.MinValue
)).ToList();
var totalCount = (int)(response.MetaData?.TotalCount ?? 0);
var totalPages = (int)(response.MetaData?.TotalPage ?? 0);
return new DiscountOrderListResult(orders, totalCount, totalPages, page);
}
catch
{
return new DiscountOrderListResult(new(), 0, 0, page);
}
}
public async Task<DiscountOrderDetail?> GetOrderByIdAsync(long orderId)
{
try
{
var r = await _client.GetOrderByIdAsync(new GetOrderByIdRequest { OrderId = orderId });
var address = r.Address != null
? new DiscountOrderAddress(r.Address.Id, r.Address.Title ?? "", r.Address.Address ?? "", r.Address.PostalCode ?? "", r.Address.Phone)
: null;
var items = r.Items.Select(i => new DiscountOrderItem(
ProductId: i.ProductId,
Title: i.ProductTitle ?? string.Empty,
UnitPrice: i.UnitPrice,
MaxDiscountPercent: i.MaxDiscountPercent,
Count: i.Count,
TotalPrice: i.TotalPrice,
DiscountAmount: i.DiscountAmount,
FinalPrice: i.FinalPrice
)).ToList();
return new DiscountOrderDetail(
Id: r.Id,
OrderNumber: r.OrderNumber ?? string.Empty,
TotalPrice: r.TotalPrice,
DiscountBalanceUsed: r.DiscountBalanceUsed,
GatewayAmount: r.GatewayAmount,
PaymentCompleted: r.PaymentCompleted,
PaymentStatus: (int)r.PaymentStatus,
TransactionId: r.TransactionId,
DeliveryStatus: (int)r.DeliveryStatus,
TrackingCode: r.TrackingCode,
Notes: r.Notes,
AdminNotes: r.AdminNotes,
Address: address,
Items: items,
Created: r.Created?.ToDateTime() ?? DateTime.MinValue);
}
catch
{
return null;
}
}
public static string GetDeliveryStatusText(int status) => status switch
{
0 => "در انتظار",
1 => "در حال پردازش",
2 => "ارسال شده",
3 => "تحویل داده شده",
4 => "لغو شده",
_ => "نامشخص"
};
public static Color GetDeliveryStatusColor(int status) => status switch
{
0 => Color.Warning,
1 => Color.Info,
2 => Color.Primary,
3 => Color.Success,
4 => Color.Error,
_ => Color.Default
};
// PaymentStatus: 0=Pending, 1=Completed, 2=Failed, 3=Refunded
public static string GetPaymentStatusText(int status) => status switch
{
0 => "در انتظار پرداخت",
1 => "پرداخت شده",
2 => "پرداخت ناموفق",
3 => "بازگشت وجه",
_ => "نامشخص"
};
public static Color GetPaymentStatusColor(int status) => status switch
{
0 => Color.Warning,
1 => Color.Success,
2 => Color.Error,
3 => Color.Info,
_ => Color.Default
};
}