feat: add payment callback and referral link features
Build and Deploy / build (push) Failing after 1m21s

This commit is contained in:
masoodafar-web
2025-12-16 02:33:56 +03:30
parent 3c528aba48
commit 3af564be73
7 changed files with 425 additions and 33 deletions
@@ -0,0 +1,174 @@
@page "/profile/payment-callback"
@attribute [Authorize]
@using Blazored.LocalStorage
@using FrontOffice.BFF.Package.Protobuf.Protos.Package
@using FrontOffice.BFF.User.Protobuf.Protos.User
<PageTitle>نتیجه پرداخت | کارا بازار سلامت</PageTitle>
<MudContainer MaxWidth="MaxWidth.Small" Class="py-8">
<MudPaper Class="pa-6 text-center">
@if (_isLoading)
{
<MudProgressCircular Color="Color.Primary" Indeterminate="true" Size="Size.Large" />
<MudText Typo="Typo.h6" Class="mt-4">در حال بررسی وضعیت پرداخت...</MudText>
}
else if (_isSuccess)
{
<MudIcon Icon="@Icons.Material.Filled.CheckCircle" Color="Color.Success" Size="Size.Large" Style="font-size: 80px" />
<MudText Typo="Typo.h5" Color="Color.Success" Class="mt-4">پرداخت موفق</MudText>
<MudText Typo="Typo.body1" Class="mt-2">@_message</MudText>
@if (!string.IsNullOrEmpty(_refId))
{
<MudText Typo="Typo.body2" Class="mt-3">
<strong>کد پیگیری:</strong> @_refId
</MudText>
}
<MudDivider Class="my-4" />
<MudText Typo="Typo.body2" Color="Color.Secondary">
موجودی کیف پول: @FormatPrice(_walletBalance)
</MudText>
<MudText Typo="Typo.body2" Color="Color.Secondary">
موجودی اعتبار تخفیف: @FormatPrice(_discountBalance)
</MudText>
<MudButton Color="Color.Primary" Variant="Variant.Filled" Class="mt-6"
Href="/profile">
بازگشت به پروفایل
</MudButton>
}
else
{
<MudIcon Icon="@Icons.Material.Filled.Error" Color="Color.Error" Size="Size.Large" Style="font-size: 80px" />
<MudText Typo="Typo.h5" Color="Color.Error" Class="mt-4">پرداخت ناموفق</MudText>
<MudText Typo="Typo.body1" Class="mt-2">@_message</MudText>
<MudButton Color="Color.Primary" Variant="Variant.Filled" Class="mt-6"
Href="/profile">
بازگشت به پروفایل
</MudButton>
<MudButton Color="Color.Secondary" Variant="Variant.Outlined" Class="mt-3 mr-2"
OnClick="RetryPayment">
تلاش مجدد
</MudButton>
}
</MudPaper>
</MudContainer>
@code {
[Inject] private PackageContract.PackageContractClient PackageContractClient { get; set; } = default!;
[Inject] private UserContract.UserContractClient UserContractClient { 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";
[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 string? _refId;
private long _walletBalance;
private long _discountBalance;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await VerifyPayment();
}
}
private async Task VerifyPayment()
{
try
{
if (OrderId <= 0 || TransactionId <= 0 || string.IsNullOrEmpty(Authority))
{
_isSuccess = false;
_message = "پارامترهای پرداخت نامعتبر است";
_isLoading = false;
StateHasChanged();
return;
}
var response = await PackageContractClient.VerifyBasePackagePaymentAsync(new VerifyBasePackagePaymentRequest
{
OrderId = OrderId,
TransactionId = TransactionId,
Authority = Authority,
Status = Status ?? "NOK"
});
_isSuccess = response.Success;
_message = response.Message;
_refId = response.RefId;
_walletBalance = response.WalletBalance;
_discountBalance = response.DiscountBalance;
// اگر پرداخت موفق بود، توکن را refresh می‌کنیم
// چون PackagePurchaseMethod تغییر کرده و باید در claims جدید باشد
if (_isSuccess)
{
await RefreshTokenAsync();
}
}
catch (Exception ex)
{
_isSuccess = false;
_message = $"خطا در بررسی وضعیت پرداخت: {ex.Message}";
}
finally
{
_isLoading = false;
StateHasChanged();
}
}
private void RetryPayment()
{
NavManager.NavigateTo("/profile");
}
/// <summary>
/// Refresh token after successful payment to update PackagePurchaseMethod claim
/// </summary>
private async Task RefreshTokenAsync()
{
try
{
var userResponse = await UserContractClient.GetUserAsync(new Google.Protobuf.WellKnownTypes.Empty());
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);
}