Merge branch 'kub-stage' into production
Build and Deploy to Production / build-and-deploy (push) Failing after 17m21s

This commit is contained in:
masoodafar-web
2026-06-26 19:30:51 +03:30
11 changed files with 478 additions and 17 deletions
@@ -0,0 +1,126 @@
@attribute [Route(RouteConstants.Profile.ChargeCreditWallet)]
@attribute [Authorize]
<PageTitle>شارژ کیف‌پول اصلی</PageTitle>
<MudContainer MaxWidth="MaxWidth.Medium" Class="py-6">
<MudStack Spacing="3">
<PageHeader Title="💳 شارژ کیف‌پول اصلی" BackHref="@RouteConstants.Profile.Wallet" />
@if (_paymentResult != null)
{
<MudAlert Severity="@(_paymentResult == "success" ? MudBlazor.Severity.Success : MudBlazor.Severity.Error)"
Class="rounded-lg" Variant="Variant.Filled">
@if (_paymentResult == "success")
{
<MudStack Spacing="2">
<span>شارژ کیف پول اصلی با موفقیت انجام شد! ✅</span>
<MudButton Variant="Variant.Filled"
Color="Color.Primary"
Size="Size.Small"
StartIcon="@Icons.Material.Filled.ShoppingCart"
OnClick="ContinueShoppingAsync">
ادامه خرید
</MudButton>
</MudStack>
}
else if (_paymentResult == "cancelled")
{
<span>پرداخت توسط شما لغو شد.</span>
}
else
{
<span>پرداخت ناموفق بود. لطفاً دوباره تلاش کنید.</span>
}
</MudAlert>
}
<MudPaper Elevation="2" Class="pa-5 rounded-lg">
<MudText Typo="Typo.h6" Class="mb-3">
<MudIcon Icon="@Icons.Material.Filled.AccountBalanceWallet" Class="ml-1" />
شارژ موجودی اصلی
</MudText>
<MudAlert Severity="MudBlazor.Severity.Info" Dense="true" Class="mb-3" Icon="@Icons.Material.Filled.Info">
مبلغ وارد شده (به تومان) از طریق درگاه پرداخت به موجودی اصلی شما اضافه می‌شود.
از موجودی اصلی برای خرید از فروشگاه عادی و پرداخت سفارش استفاده می‌شود.
</MudAlert>
<MudStack Spacing="2">
<MudNumericField @bind-Value="_chargeAmount"
Label="مبلغ (تومان)"
Variant="Variant.Outlined"
Min="10_000"
Max="1_000_000_000"
Format="N0"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Payments"
HelperText="حداقل ۱۰,۰۰۰ و حداکثر ۱,۰۰۰,۰۰۰,۰۰۰ تومان" />
<MudStack Row="true" Spacing="1" Class="flex-wrap">
@foreach (var preset in _presetAmounts)
{
<MudButton Variant="Variant.Outlined" Size="Size.Small"
Color="@(_chargeAmount == preset ? Color.Primary : Color.Default)"
OnClick="() => _chargeAmount = preset"
Class="rounded-pill">
@FormatToman(preset)
</MudButton>
}
</MudStack>
@if (_chargeAmount > 0)
{
<MudPaper Outlined="true" Class="pa-3 rounded-lg" Style="background: #eff6ff;">
<MudStack Row="true" Justify="Justify.SpaceBetween">
<MudText Typo="Typo.body2">مبلغ پرداخت:</MudText>
<MudText Typo="Typo.body2"><strong>@FormatToman(_chargeAmount)</strong></MudText>
</MudStack>
<MudStack Row="true" Justify="Justify.SpaceBetween">
<MudText Typo="Typo.body2">موجودی دریافتی:</MudText>
<MudText Typo="Typo.body2" Color="Color.Primary"><strong>@FormatToman(_chargeAmount)</strong></MudText>
</MudStack>
</MudPaper>
}
<MudButton Variant="Variant.Filled"
Color="Color.Primary"
Size="Size.Large"
FullWidth="true"
Disabled="@(_isProcessing || _chargeAmount < 10_000)"
OnClick="StartCreditCharge"
StartIcon="@Icons.Material.Filled.Payment"
Class="rounded-lg mt-2">
@if (_isProcessing)
{
<MudProgressCircular Size="Size.Small" Indeterminate="true" Class="me-2" />
<span>در حال انتقال به درگاه...</span>
}
else
{
<span>پرداخت با کارت بانکی</span>
}
</MudButton>
</MudStack>
</MudPaper>
<MudExpansionPanels Elevation="1" Class="rounded-lg">
<MudExpansionPanel Text="قوانین شارژ کیف پول اصلی" MaxHeight="500" IsInitiallyExpanded="false">
<MudList T="string" Dense="true">
<MudListItem T="string" Icon="@Icons.Material.Filled.CheckCircle" IconColor="Color.Success">
موجودی اصلی برای خرید از فروشگاه عادی و پرداخت سفارش قابل استفاده است
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.CheckCircle" IconColor="Color.Success">
حداقل مبلغ شارژ: ۱۰,۰۰۰ تومان
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.CheckCircle" IconColor="Color.Success">
مبلغ واریزی بدون ضریب به موجودی اضافه می‌شود (۱:۱)
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.Info" IconColor="Color.Info">
پرداخت از طریق درگاه بانکی انجام می‌شود
</MudListItem>
</MudList>
</MudExpansionPanel>
</MudExpansionPanels>
</MudStack>
</MudContainer>
@@ -0,0 +1,98 @@
using FrontOffice.Main.Utilities;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MudBlazor;
namespace FrontOffice.Main.Pages.Profile;
public partial class ChargeCreditWallet : ComponentBase
{
private bool _isProcessing;
private long _chargeAmount;
private string? _paymentResult;
private string? _pendingReturnUrl;
private readonly long[] _presetAmounts = { 500_000, 1_000_000, 5_000_000, 10_000_000, 20_000_000, 50_000_000 };
[SupplyParameterFromQuery(Name = "payment")]
public string? PaymentQueryParam { get; set; }
[SupplyParameterFromQuery(Name = "amount")]
public long? AmountQueryParam { get; set; }
[SupplyParameterFromQuery(Name = "returnUrl")]
public string? ReturnUrlQueryParam { get; set; }
protected override void OnInitialized()
{
_paymentResult = PaymentQueryParam;
if (AmountQueryParam is > 0)
_chargeAmount = CreditChargeNavigation.NormalizeChargeAmount(AmountQueryParam.Value);
if (CreditChargeNavigation.IsValidReturnUrl(ReturnUrlQueryParam))
_pendingReturnUrl = ReturnUrlQueryParam;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender && !string.IsNullOrEmpty(_pendingReturnUrl))
{
await CreditChargeNavigation.SaveReturnUrlAsync(JSRuntime, _pendingReturnUrl);
}
await base.OnAfterRenderAsync(firstRender);
}
private async Task StartCreditCharge()
{
if (_chargeAmount <= 0 || _isProcessing) return;
_isProcessing = true;
StateHasChanged();
try
{
if (!string.IsNullOrEmpty(_pendingReturnUrl))
await CreditChargeNavigation.SaveReturnUrlAsync(JSRuntime, _pendingReturnUrl);
else
{
var storedReturnUrl = await CreditChargeNavigation.GetReturnUrlAsync(JSRuntime);
if (CreditChargeNavigation.IsValidReturnUrl(storedReturnUrl))
_pendingReturnUrl = storedReturnUrl;
}
var (success, gatewayUrl, error) = await WalletService.InitiateCreditChargeAsync(_chargeAmount);
if (success && !string.IsNullOrEmpty(gatewayUrl))
{
Navigation.NavigateTo(gatewayUrl, forceLoad: true);
}
else
{
Snackbar.Add(error ?? "خطا در ایجاد درخواست پرداخت", Severity.Error);
}
}
catch (Exception ex)
{
Snackbar.Add($"خطا: {ex.Message}", Severity.Error);
}
finally
{
_isProcessing = false;
StateHasChanged();
}
}
private async Task ContinueShoppingAsync()
{
var returnUrl = await CreditChargeNavigation.GetReturnUrlAsync(JSRuntime);
await CreditChargeNavigation.ClearReturnUrlAsync(JSRuntime);
if (CreditChargeNavigation.IsValidReturnUrl(returnUrl))
Navigation.NavigateTo(returnUrl!);
}
private static string FormatToman(long toman)
=> string.Format("{0:N0} تومان", toman);
}
@@ -143,6 +143,9 @@
case "discount-wallet":
await VerifyDiscountWalletCharge();
break;
case "credit-wallet":
await VerifyCreditWalletCharge();
break;
case "discount-order":
await VerifyDiscountOrderPayment();
break;
@@ -254,6 +257,35 @@
await UpdateWalletBalance();
}
}
/// <summary>
/// تأیید شارژ کیف پول اصلی
/// </summary>
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();
}
}
/// <summary>
/// تأیید پرداخت سفارش فروشگاه تخفیفی
@@ -308,6 +340,7 @@
{
"magic-wallet" => "/profile/magic-wallet",
"discount-wallet" => "/profile/charge-discount-wallet",
"credit-wallet" => "/profile/charge-credit-wallet",
"discount-order" => "/discount-store",
_ => "/profile"
};
@@ -38,6 +38,17 @@
درخواست‌های برداشت
</MudButton>
<!-- دکمه شارژ کیف‌پول اصلی -->
<MudButton Variant="Variant.Filled"
Color="Color.Primary"
Size="Size.Large"
FullWidth="true"
StartIcon="@Icons.Material.Filled.AccountBalanceWallet"
Href="@RouteConstants.Profile.ChargeCreditWallet"
Class="rounded-lg">
شارژ کیف‌پول اصلی
</MudButton>
<!-- دکمه شارژ کیف‌پول اعتباری -->
<MudButton Variant="Variant.Filled"
Color="Color.Info"