feat: implement payment verification methods for magic wallet and discount wallet
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 2m37s

This commit is contained in:
masoodafar-web
2026-02-28 03:27:58 +03:30
parent 2b1dc47dc7
commit ff3696cda3
4 changed files with 239 additions and 35 deletions
+1 -1
View File
@@ -11,7 +11,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="DateTimeConverterCL" Version="1.0.0" /> <PackageReference Include="DateTimeConverterCL" Version="1.0.0" />
<!-- Replace all FrontOffice.BFF protobuf packages with CMS protobuf --> <!-- Replace all FrontOffice.BFF protobuf packages with CMS protobuf -->
<PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.189" /> <PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.190" />
<!-- <ProjectReference Include="../../../CMS/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj" />--> <!-- <ProjectReference Include="../../../CMS/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj" />-->
<PackageReference Include="MudBlazor" Version="8.14.0" /> <PackageReference Include="MudBlazor" Version="8.14.0" />
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" /> <PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
@@ -35,8 +35,8 @@
</MudText> </MudText>
<MudButton Color="Color.Primary" Variant="Variant.Filled" Class="mt-6" <MudButton Color="Color.Primary" Variant="Variant.Filled" Class="mt-6"
Href="/profile"> Href="@_successReturnUrl">
بازگشت به پروفایل @_successReturnText
</MudButton> </MudButton>
} }
else else
@@ -46,8 +46,8 @@
<MudText Typo="Typo.body1" Class="mt-2">@_message</MudText> <MudText Typo="Typo.body1" Class="mt-2">@_message</MudText>
<MudButton Color="Color.Primary" Variant="Variant.Filled" Class="mt-6" <MudButton Color="Color.Primary" Variant="Variant.Filled" Class="mt-6"
Href="/profile"> Href="@_failReturnUrl">
بازگشت به پروفایل @_failReturnText
</MudButton> </MudButton>
<MudButton Color="Color.Secondary" Variant="Variant.Outlined" Class="mt-3 mr-2" <MudButton Color="Color.Secondary" Variant="Variant.Outlined" Class="mt-3 mr-2"
@@ -61,12 +61,19 @@
@code { @code {
[Inject] private PackageContract.PackageContractClient PackageContractClient { get; set; } = default!; [Inject] private PackageContract.PackageContractClient PackageContractClient { get; set; } = default!;
[Inject] private UserContract.UserContractClient UserContractClient { 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 ILocalStorageService LocalStorage { get; set; } = default!;
[Inject] private AuthService AuthService { get; set; } = default!; [Inject] private AuthService AuthService { get; set; } = default!;
[Inject] private NavigationManager NavManager { get; set; } = default!; [Inject] private NavigationManager NavManager { get; set; } = default!;
private const string TokenStorageKey = "auth:token"; private const string TokenStorageKey = "auth:token";
/// <summary>
/// نوع پرداخت: package (پیش‌فرض) | magic-wallet | discount-wallet | discount-order
/// </summary>
[SupplyParameterFromQuery(Name = "type")]
private string? PaymentType { get; set; }
[SupplyParameterFromQuery(Name = "orderId")] [SupplyParameterFromQuery(Name = "orderId")]
private long OrderId { get; set; } private long OrderId { get; set; }
@@ -84,6 +91,12 @@
private string _message = string.Empty; private string _message = string.Empty;
private long _transactionId; private long _transactionId;
private long _walletBalance; private long _walletBalance;
// دکمه‌های بازگشت بسته به نوع پرداخت
private string _successReturnUrl = "/profile";
private string _successReturnText = "بازگشت به پروفایل";
private string _failReturnUrl = "/profile";
private string _failReturnText = "بازگشت به پروفایل";
protected override async Task OnAfterRenderAsync(bool firstRender) protected override async Task OnAfterRenderAsync(bool firstRender)
{ {
@@ -97,37 +110,23 @@
{ {
try try
{ {
if (OrderId <= 0 || string.IsNullOrEmpty(Authority)) // تعیین نوع پرداخت — اگر type نباشد، پیش‌فرض خرید پکیج
{ var type = PaymentType?.ToLowerInvariant() ?? "package";
_isSuccess = false;
_message = "پارامترهای پرداخت نامعتبر است";
_isLoading = false;
StateHasChanged();
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;
// اگر پرداخت موفق بود، موجودی واقعی کیف پول رو بگیر و توکن رو refresh کن switch (type)
if (_isSuccess)
{ {
try case "magic-wallet":
{ await VerifyMagicWalletCharge();
var balances = await WalletService.GetBalancesAsync(); break;
_walletBalance = balances.CreditBalance; case "discount-wallet":
} await VerifyDiscountWalletCharge();
catch { /* اگر خطا شد، صفر نمایش بده */ } break;
case "discount-order":
await RefreshTokenAsync(); await VerifyDiscountOrderPayment();
break;
default: // "package" or missing
await VerifyPackagePurchase();
break;
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -141,10 +140,156 @@
StateHasChanged(); StateHasChanged();
} }
} }
/// <summary>
/// تأیید خرید پکیج — رفتار فعلی
/// </summary>
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();
}
}
/// <summary>
/// تأیید شارژ کیف‌پول جادویی
/// </summary>
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();
}
}
/// <summary>
/// تأیید شارژ کیف پول تخفیفی
/// </summary>
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();
}
}
/// <summary>
/// تأیید پرداخت سفارش فروشگاه تخفیفی
/// </summary>
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;
}
/// <summary>
/// بروزرسانی موجودی کیف پول
/// </summary>
private async Task UpdateWalletBalance()
{
try
{
var balances = await WalletService.GetBalancesAsync();
_walletBalance = balances.CreditBalance;
}
catch { /* اگر خطا شد، صفر نمایش بده */ }
}
/// <summary>
/// بروزرسانی موجودی + refresh توکن (فقط برای خرید پکیج)
/// </summary>
private async Task UpdateWalletBalanceAndRefreshToken()
{
await UpdateWalletBalance();
await RefreshTokenAsync();
}
private void RetryPayment() private void RetryPayment()
{ {
NavManager.NavigateTo("/profile", forceLoad: true); var type = PaymentType?.ToLowerInvariant() ?? "package";
var url = type switch
{
"magic-wallet" => "/profile/magic-wallet",
"discount-wallet" => "/profile/charge-discount-wallet",
"discount-order" => "/discount-store",
_ => "/profile"
};
NavManager.NavigateTo(url, forceLoad: true);
} }
/// <summary> /// <summary>
@@ -112,6 +112,27 @@ public class DiscountOrderService
catch { return false; } 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) public async Task<DiscountOrderListResult> GetUserOrdersAsync(int page = 1, int pageSize = 10)
{ {
try try
@@ -266,6 +266,44 @@ public class WalletService
} }
} }
// ============= Wallet Verify Methods =============
public async Task<(bool Success, string Message)> VerifyMagicChargeAsync(string authority, string status)
{
try
{
var response = await _client.VerifyMagicChargeAsync(new VerifyWalletChargeRequest
{
Authority = authority,
Status = status
});
return (response.Success, response.Message);
}
catch (Grpc.Core.RpcException ex)
{
return (false, ex.Status.Detail ?? "خطا در بررسی وضعیت پرداخت");
}
}
public async Task<(bool Success, string Message)> VerifyDiscountChargeAsync(string authority, string status)
{
try
{
var response = await _client.VerifyDiscountChargeAsync(new VerifyWalletChargeRequest
{
Authority = authority,
Status = status
});
return (response.Success, response.Message);
}
catch (Grpc.Core.RpcException ex)
{
return (false, ex.Status.Detail ?? "خطا در بررسی وضعیت پرداخت");
}
}
public int GetWalletMode() public int GetWalletMode()
{ {
try try