diff --git a/docs/CUSTOMER-SERVICES.md b/docs/CUSTOMER-SERVICES.md index a7031de..05ff8bd 100644 --- a/docs/CUSTOMER-SERVICES.md +++ b/docs/CUSTOMER-SERVICES.md @@ -67,10 +67,12 @@ | 4.5 | `WalletService.VerifyMagicChargeAsync` | `UserWalletContract.VerifyMagicCharge` | `/profile/payment-callback?type=magic-wallet` | تأیید شارژ Magic پس از درگاه | | 4.6 | `WalletService.InitiateDiscountChargeAsync` | `UserWalletContract.InitiateDiscountCharge` | `/profile/charge-discount-wallet` | شروع شارژ کیف پول تخفیفی → درگاه | | 4.7 | `WalletService.VerifyDiscountChargeAsync` | `UserWalletContract.VerifyDiscountCharge` | `/profile/payment-callback?type=discount-wallet` | تأیید شارژ کیف تخفیفی | -| 4.8 | `WalletService.GetWithdrawalsAsync` | `UserWalletContract.GetCustomerWithdrawals` | `/profile/withdrawal-requests` | لیست درخواست‌های برداشت | -| 4.9 | `WalletService.GetWithdrawalSettingsAsync` | `UserWalletContract.GetCustomerWithdrawalSettings` | `/profile/withdrawal-requests` | حداقل مبلغ برداشت | -| 4.10 | `WalletService.RequestWithdrawalAsync` | `UserWalletContract.CustomerWithdrawBalance` | `/profile/withdrawal-requests` | ثبت درخواست برداشت پاداش (با payoutId کمیسیون) | -| 4.11 | `CommissionService.GetWithdrawablePayoutsAsync` | `CommissionContract.GetMyCommissionPayouts` | `/profile/withdrawal-requests` | پاداش‌های قابل برداشت برای انتخاب | +| 4.8 | `WalletService.InitiateCreditChargeAsync` | `UserWalletContract.InitiateCreditCharge` | `/profile/charge-credit-wallet` | شروع شارژ کیف پول اصلی → درگاه | +| 4.9 | `WalletService.VerifyCreditChargeAsync` | `UserWalletContract.VerifyCreditCharge` | `/profile/payment-callback?type=credit-wallet` | تأیید شارژ کیف اصلی | +| 4.10 | `WalletService.GetWithdrawalsAsync` | `UserWalletContract.GetCustomerWithdrawals` | `/profile/withdrawal-requests` | لیست درخواست‌های برداشت | +| 4.11 | `WalletService.GetWithdrawalSettingsAsync` | `UserWalletContract.GetCustomerWithdrawalSettings` | `/profile/withdrawal-requests` | حداقل مبلغ برداشت | +| 4.12 | `WalletService.RequestWithdrawalAsync` | `UserWalletContract.CustomerWithdrawBalance` | `/profile/withdrawal-requests` | ثبت درخواست برداشت پاداش (با payoutId کمیسیون) | +| 4.13 | `CommissionService.GetWithdrawablePayoutsAsync` | `CommissionContract.GetMyCommissionPayouts` | `/profile/withdrawal-requests` | پاداش‌های قابل برداشت برای انتخاب | --- @@ -81,8 +83,9 @@ | 5.1 | `PackageContract.CustomerVerifyPackagePurchase` | `PackageContract` | `/profile/payment-callback` (type=package) | تأیید خرید پکیج | | 5.2 | `WalletService.VerifyMagicChargeAsync` | `UserWalletContract` | `/profile/payment-callback` (type=magic-wallet) | تأیید شارژ Magic | | 5.3 | `WalletService.VerifyDiscountChargeAsync` | `UserWalletContract` | `/profile/payment-callback` (type=discount-wallet) | تأیید شارژ تخفیفی | -| 5.4 | `DiscountOrderService.VerifyDiscountOrderPaymentAsync` | `DiscountOrderContract.CustomerVerifyDiscountOrderPayment` | `/profile/payment-callback` (type=discount-order) | تأیید پرداخت سفارش فروشگاه تخفیفی | -| 5.5 | `UserContract.GetUserForCustomer` + `AuthService.InitUserAuthInfo` | `UserContract` | `/profile/payment-callback` | به‌روزرسانی claims کاربر پس از پرداخت موفق | +| 5.4 | `WalletService.VerifyCreditChargeAsync` | `UserWalletContract` | `/profile/payment-callback` (type=credit-wallet) | تأیید شارژ کیف اصلی | +| 5.5 | `DiscountOrderService.VerifyDiscountOrderPaymentAsync` | `DiscountOrderContract.CustomerVerifyDiscountOrderPayment` | `/profile/payment-callback` (type=discount-order) | تأیید پرداخت سفارش فروشگاه تخفیفی | +| 5.6 | `UserContract.GetUserForCustomer` + `AuthService.InitUserAuthInfo` | `UserContract` | `/profile/payment-callback` | به‌روزرسانی claims کاربر پس از پرداخت موفق | --- diff --git a/src/FrontOffice.Main/FrontOffice.Main.csproj b/src/FrontOffice.Main/FrontOffice.Main.csproj index a2e702d..ca06319 100644 --- a/src/FrontOffice.Main/FrontOffice.Main.csproj +++ b/src/FrontOffice.Main/FrontOffice.Main.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor b/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor new file mode 100644 index 0000000..6d30f81 --- /dev/null +++ b/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor @@ -0,0 +1,117 @@ +@attribute [Route(RouteConstants.Profile.ChargeCreditWallet)] +@attribute [Authorize] + +شارژ کیف‌پول اصلی + + + + + + @if (_paymentResult != null) + { + + @if (_paymentResult == "success") + { + شارژ کیف پول اصلی با موفقیت انجام شد! ✅ + } + else if (_paymentResult == "cancelled") + { + پرداخت توسط شما لغو شد. + } + else + { + پرداخت ناموفق بود. لطفاً دوباره تلاش کنید. + } + + } + + + + + شارژ موجودی اصلی + + + + مبلغ وارد شده (به تومان) از طریق درگاه پرداخت به موجودی اصلی شما اضافه می‌شود. + از موجودی اصلی برای خرید از فروشگاه عادی و پرداخت سفارش استفاده می‌شود. + + + + + + + @foreach (var preset in _presetAmounts) + { + + @FormatToman(preset) + + } + + + @if (_chargeAmount > 0) + { + + + مبلغ پرداخت: + @FormatToman(_chargeAmount) + + + موجودی دریافتی: + @FormatToman(_chargeAmount) + + + } + + + @if (_isProcessing) + { + + در حال انتقال به درگاه... + } + else + { + پرداخت با کارت بانکی + } + + + + + + + + + موجودی اصلی برای خرید از فروشگاه عادی و پرداخت سفارش قابل استفاده است + + + حداقل مبلغ شارژ: ۱۰,۰۰۰ تومان + + + مبلغ واریزی بدون ضریب به موجودی اضافه می‌شود (۱:۱) + + + پرداخت از طریق درگاه بانکی انجام می‌شود + + + + + + diff --git a/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor.cs b/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor.cs new file mode 100644 index 0000000..7ab98cb --- /dev/null +++ b/src/FrontOffice.Main/Pages/Profile/ChargeCreditWallet.razor.cs @@ -0,0 +1,56 @@ +using FrontOffice.Main.Utilities; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace FrontOffice.Main.Pages.Profile; + +public partial class ChargeCreditWallet : ComponentBase +{ + private bool _isProcessing; + private long _chargeAmount; + private string? _paymentResult; + + 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; } + + protected override void OnInitialized() + { + _paymentResult = PaymentQueryParam; + } + + private async Task StartCreditCharge() + { + if (_chargeAmount <= 0 || _isProcessing) return; + + _isProcessing = true; + StateHasChanged(); + + try + { + 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 static string FormatToman(long toman) + => string.Format("{0:N0} تومان", toman); +} diff --git a/src/FrontOffice.Main/Pages/Profile/PaymentCallback.razor b/src/FrontOffice.Main/Pages/Profile/PaymentCallback.razor index 25cf450..c70178f 100644 --- a/src/FrontOffice.Main/Pages/Profile/PaymentCallback.razor +++ b/src/FrontOffice.Main/Pages/Profile/PaymentCallback.razor @@ -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(); } } + + /// + /// تأیید شارژ کیف پول اصلی + /// + 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(); + } + } /// /// تأیید پرداخت سفارش فروشگاه تخفیفی @@ -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" }; diff --git a/src/FrontOffice.Main/Pages/Profile/Wallet.razor b/src/FrontOffice.Main/Pages/Profile/Wallet.razor index 219c273..6670c39 100644 --- a/src/FrontOffice.Main/Pages/Profile/Wallet.razor +++ b/src/FrontOffice.Main/Pages/Profile/Wallet.razor @@ -38,6 +38,17 @@ درخواست‌های برداشت + + + شارژ کیف‌پول اصلی + + InitiateCreditChargeAsync(long amount) + { + try + { + var response = await _client.InitiateCreditChargeAsync(new InitiateCreditChargeRequest + { + Amount = amount + }); + + if (response.IsSuccess) + return (true, response.GatewayUrl, null); + + return (false, null, response.ErrorMessage); + } + catch (Grpc.Core.RpcException ex) + { + return (false, null, ex.Status.Detail ?? "خطا در ارتباط با سرور"); + } + } + // ============= Wallet Verify Methods ============= public async Task<(bool Success, string Message)> VerifyMagicChargeAsync(string authority, string status) @@ -304,6 +324,24 @@ public class WalletService } } + public async Task<(bool Success, string Message)> VerifyCreditChargeAsync(string authority, string status) + { + try + { + var response = await _client.VerifyCreditChargeAsync(new VerifyWalletChargeRequest + { + Authority = authority, + Status = status + }); + + return (response.Success, response.Message); + } + catch (Grpc.Core.RpcException ex) + { + return (false, ex.Status.Detail ?? "خطا در بررسی وضعیت پرداخت"); + } + } + public int GetWalletMode() { try