@page "/profile/payment-callback"
@attribute [Authorize]
@using Blazored.LocalStorage
@using CMSMicroservice.Protobuf.Protos.Package
@using CMSMicroservice.Protobuf.Protos.User
@using FrontOffice.Main.Utilities
نتیجه پرداخت | کارا بازار سلامت
@if (_isLoading)
{
در حال بررسی وضعیت پرداخت...
}
else if (_isSuccess)
{
پرداخت موفق
@_message
@if (_transactionId > 0)
{
کد ارجاعی: @_transactionId
}
موجودی کیف پول اصلی: @FormatPrice(_walletBalance)
@_successReturnText
}
else
{
پرداخت ناموفق
@_message
@_failReturnText
تلاش مجدد
}
@code {
[Inject] private PackageContract.PackageContractClient PackageContractClient { get; set; } = default!;
[Inject] private UserContract.UserContractClient UserContractClient { get; set; } = default!;
[Inject] private DiscountOrderService DiscountOrderService { get; set; } = default!;
[Inject] private ILocalStorageService LocalStorage { get; set; } = default!;
[Inject] private AuthService AuthService { get; set; } = default!;
[Inject] private NavigationManager NavManager { get; set; } = default!;
private const string TokenStorageKey = "auth:token";
///
/// نوع پرداخت: package (پیشفرض) | magic-wallet | discount-wallet | discount-order
///
[SupplyParameterFromQuery(Name = "type")]
private string? PaymentType { get; set; }
[SupplyParameterFromQuery(Name = "orderId")]
private long OrderId { get; set; }
[SupplyParameterFromQuery(Name = "transactionId")]
private long TransactionId { get; set; }
[SupplyParameterFromQuery(Name = "Authority")]
private string? Authority { get; set; }
[SupplyParameterFromQuery(Name = "Status")]
private string? Status { get; set; }
private bool _isLoading = true;
private bool _isSuccess;
private string _message = string.Empty;
private long _transactionId;
private long _walletBalance;
private bool _verifyCompleted;
private readonly SemaphoreSlim _verifyGate = new(1, 1);
// دکمههای بازگشت بسته به نوع پرداخت
private string _successReturnUrl = "/profile";
private string _successReturnText = "بازگشت به پروفایل";
private string _failReturnUrl = "/profile";
private string _failReturnText = "بازگشت به پروفایل";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender && !_verifyCompleted)
{
await VerifyPaymentOnceAsync();
}
}
///
/// Blazor Server may invoke render/verify twice in quick succession — gate with semaphore.
///
private async Task VerifyPaymentOnceAsync()
{
if (_verifyCompleted) return;
await _verifyGate.WaitAsync();
try
{
if (_verifyCompleted) return;
await VerifyPayment();
_verifyCompleted = true;
}
finally
{
_verifyGate.Release();
}
}
private async Task VerifyPayment()
{
try
{
// تعیین نوع پرداخت — اگر type نباشد، پیشفرض خرید پکیج
var type = PaymentType?.ToLowerInvariant() ?? "package";
switch (type)
{
case "magic-wallet":
await VerifyMagicWalletCharge();
break;
case "discount-wallet":
await VerifyDiscountWalletCharge();
break;
case "credit-wallet":
await VerifyCreditWalletCharge();
break;
case "discount-order":
await VerifyDiscountOrderPayment();
break;
default: // "package" or missing
await VerifyPackagePurchase();
break;
}
}
catch (Exception ex)
{
_isSuccess = false;
_message = $"خطا در بررسی وضعیت پرداخت: {ex.Message}";
}
finally
{
_isLoading = false;
StateHasChanged();
}
}
///
/// تأیید خرید پکیج — رفتار فعلی
///
private async Task VerifyPackagePurchase()
{
_successReturnUrl = "/profile";
_successReturnText = "بازگشت به پروفایل";
_failReturnUrl = "/profile";
_failReturnText = "بازگشت به پروفایل";
if (OrderId <= 0 || string.IsNullOrEmpty(Authority))
{
_isSuccess = false;
_message = "پارامترهای پرداخت نامعتبر است";
return;
}
var response = await PackageContractClient.CustomerVerifyPackagePurchaseAsync(new CustomerVerifyPackagePurchaseRequest
{
OrderId = OrderId,
Authority = Authority ?? string.Empty,
Status = Status ?? string.Empty
});
_isSuccess = response.Success;
_message = response.Message;
_transactionId = response.TransactionId;
if (_isSuccess)
{
await UpdateWalletBalanceAndRefreshToken();
}
}
///
/// تأیید شارژ کیفپول جادویی
///
private async Task VerifyMagicWalletCharge()
{
_successReturnUrl = "/profile/magic-wallet";
_successReturnText = "بازگشت به کیف پول جادویی";
_failReturnUrl = "/profile/magic-wallet";
_failReturnText = "بازگشت به کیف پول جادویی";
if (string.IsNullOrEmpty(Authority))
{
_isSuccess = false;
_message = "کد Authority نامعتبر است";
return;
}
var (success, message) = await WalletService.VerifyMagicChargeAsync(
Authority, Status ?? "NOK");
_isSuccess = success;
_message = message;
if (_isSuccess)
{
await UpdateWalletBalance();
}
}
///
/// تأیید شارژ کیف پول تخفیفی
///
private async Task VerifyDiscountWalletCharge()
{
_successReturnUrl = "/profile/charge-discount-wallet";
_successReturnText = "بازگشت به کیف پول تخفیفی";
_failReturnUrl = "/profile/charge-discount-wallet";
_failReturnText = "بازگشت به کیف پول تخفیفی";
if (string.IsNullOrEmpty(Authority))
{
_isSuccess = false;
_message = "کد Authority نامعتبر است";
return;
}
var (success, message) = await WalletService.VerifyDiscountChargeAsync(
Authority, Status ?? "NOK");
_isSuccess = success;
_message = message;
if (_isSuccess)
{
await UpdateWalletBalance();
}
}
///
/// تأیید شارژ کیف پول اصلی
///
private async Task VerifyCreditWalletCharge()
{
_successReturnUrl = "/profile/charge-credit-wallet?payment=success";
_successReturnText = "بازگشت به شارژ کیف پول اصلی";
_failReturnUrl = "/profile/charge-credit-wallet?payment=failed";
_failReturnText = "بازگشت به شارژ کیف پول اصلی";
if (string.IsNullOrEmpty(Authority))
{
_isSuccess = false;
_message = "کد Authority نامعتبر است";
return;
}
var (success, message) = await WalletService.VerifyCreditChargeAsync(
Authority, Status ?? "NOK");
_isSuccess = success;
_message = message;
if (_isSuccess)
{
await UpdateWalletBalance();
}
}
///
/// تأیید پرداخت سفارش فروشگاه تخفیفی
///
private async Task VerifyDiscountOrderPayment()
{
_successReturnUrl = $"/discount-store/order/{OrderId}";
_successReturnText = "مشاهده سفارش";
_failReturnUrl = $"/discount-store/order/{OrderId}";
_failReturnText = "مشاهده سفارش";
if (OrderId <= 0 || string.IsNullOrEmpty(Authority))
{
_isSuccess = false;
_message = "پارامترهای پرداخت نامعتبر است";
return;
}
var (success, message, _) = await DiscountOrderService.VerifyDiscountOrderPaymentAsync(
OrderId, Authority, Status ?? "NOK");
_isSuccess = success;
_message = message;
}
///
/// بروزرسانی موجودی کیف پول
///
private async Task UpdateWalletBalance()
{
try
{
var balances = await WalletService.GetBalancesAsync();
_walletBalance = balances.CreditBalance;
}
catch { /* اگر خطا شد، صفر نمایش بده */ }
}
///
/// بروزرسانی موجودی + refresh توکن (فقط برای خرید پکیج)
///
private async Task UpdateWalletBalanceAndRefreshToken()
{
await UpdateWalletBalance();
await RefreshTokenAsync();
}
private void RetryPayment()
{
var type = PaymentType?.ToLowerInvariant() ?? "package";
var url = type switch
{
"magic-wallet" => "/profile/magic-wallet",
"discount-wallet" => "/profile/charge-discount-wallet",
"credit-wallet" => "/profile/charge-credit-wallet",
"discount-order" => "/discount-store",
_ => "/profile"
};
NavManager.NavigateTo(url, forceLoad: true);
}
///
/// Refresh token after successful payment to update PackagePurchaseMethod claim
///
private async Task RefreshTokenAsync()
{
try
{
var userResponse = await UserContractClient.GetUserForCustomerAsync(new CMSMicroservice.Protobuf.Protos.User.GetUserForCustomerRequest());
if (!string.IsNullOrWhiteSpace(userResponse.Token))
{
// ذخیره توکن جدید در localStorage
await LocalStorage.SetItemAsync(TokenStorageKey, userResponse.Token);
// بهروزرسانی UserAuthInfo با claims جدید
await AuthService.InitUserAuthInfo();
}
}
catch
{
// اگر refresh ناموفق بود، پرداخت همچنان موفق است
// کاربر میتواند با logout/login دوباره token جدید بگیرد
}
}
private static string FormatPrice(long price) => string.Format("{0:N0} تومان", price);
}