feat: Update payment processing and callback mechanisms
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 8m22s

- Refactor ActivateClubMembershipCommandHandler to use UserPackagePurchases instead of UserOrders for package activation.
- Modify PlaceOrderCommandHandler to redirect payment callbacks to the front office.
- Update ChargeDiscountWalletCommandHandler and ChargeMagicWalletCommandHandler to direct payment callbacks to the front office.
- Remove PaymentCallbackController and integrate payment verification directly into DiscountOrderService and UserWalletService.
- Add CustomerVerifyDiscountOrderPayment RPC to DiscountOrderService for verifying discount order payments.
- Implement VerifyMagicCharge and VerifyDiscountCharge methods in UserWalletService for wallet charge verifications.
- Update appsettings.json to use local URLs for development.
- Remove appsettings.Development.json as it is no longer needed.
- Comment out history tracking methods in ClubMembershipCycle and Package classes.
- Update PackageService to automatically activate club membership after successful payment verification.
- Adjust UserService to generate JWT tokens with user details.
This commit is contained in:
masoodafar-web
2026-02-28 03:27:46 +03:30
parent 01073084ab
commit 1e7c17f090
17 changed files with 363 additions and 334 deletions
@@ -97,43 +97,44 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
);
}
// 4. پیدا کردن UserOrder با PackageId
var packageOrder = await _context.UserOrders
.Include(o => o.Transaction)
.Where(o =>
o.UserId == user.Id &&
o.PackageId != null &&
o.PaymentStatus == PaymentStatus.Success)
.OrderByDescending(o => o.Created)
// 4. پیدا کردن آخرین خرید موفق پکیج
var packagePurchase = await _context.UserPackagePurchases
.Include(p => p.Transaction)
.Where(p =>
p.UserId == user.Id &&
p.Transaction != null &&
p.Transaction.PaymentStatus == PaymentStatus.Success)
.OrderByDescending(p => p.Created)
.FirstOrDefaultAsync(cancellationToken);
if (packageOrder == null)
if (packagePurchase == null)
{
_logger.LogWarning(
"No successful package order found for UserId: {UserId}",
"No successful package purchase found for UserId: {UserId}",
request.UserId
);
throw new NotFoundException("سفارش پکیج یافت نشد");
}
// 5. بررسی Transaction
if (packageOrder.Transaction == null)
if (packagePurchase.Transaction == null)
{
_logger.LogError(
"Transaction not found for OrderId: {OrderId}",
packageOrder.Id
"Transaction not found for PurchaseId: {PurchaseId}",
packagePurchase.Id
);
throw new NotFoundException("تراکنش مربوط به سفارش یافت نشد");
}
var transaction = packageOrder.Transaction;
var transaction = packagePurchase.Transaction;
if (transaction.Type != TransactionType.DepositIpg &&
if (transaction.Type != TransactionType.Buy &&
transaction.Type != TransactionType.DepositIpg &&
transaction.Type != TransactionType.DepositExternal1)
{
_logger.LogWarning(
"Invalid transaction type for OrderId {OrderId}: {Type}",
packageOrder.Id,
"Invalid transaction type for PurchaseId {PurchaseId}: {Type}",
packagePurchase.Id,
transaction.Type
);
throw new BadRequestException(
@@ -141,9 +142,9 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
);
}
// 5.5. بارگذاری پکیج از سفارش
// 5.5. بارگذاری پکیج از خرید
package = await _context.Packages
.FirstOrDefaultAsync(p => p.Id == packageOrder.PackageId && !p.IsDeleted, cancellationToken)
.FirstOrDefaultAsync(p => p.Id == packagePurchase.PackageId && !p.IsDeleted, cancellationToken)
?? throw new NotFoundException("پکیج یافت نشد");
// بررسی موجودی با مبلغ پکیج واقعی
@@ -194,11 +195,11 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
if (isNewMembership)
{
// ایجاد عضویت جدید
// ایجاد عضویت جدید — IsActive = false تا زمان امضای قرارداد باشگاه
entity = new ClubMembership
{
UserId = user.Id,
IsActive = true,
IsActive = false,
ActivatedAt = activationDate,
FirstActivationDate = activationDate,
FirstPackageId = package.Id,
@@ -235,8 +236,8 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
}
// فعال‌سازی مجدد یا خرید مجدد (Q19/Q20) — FirstActivation حفظ میشه (Q21), Last بروزرسانی میشه
// مقدار IsActive قبلی حفظ میشه — اگر قبلاً فعال بوده، فعال بمونه
entity = existingMembership;
entity.IsActive = true;
entity.LastActivationDate = activationDate;
entity.LastPackageId = package.Id;
entity.PurchaseMethod = user.PackagePurchaseMethod;
@@ -195,9 +195,9 @@ public class PlaceOrderCommandHandler : IRequestHandler<PlaceOrderCommand, Place
{
try
{
// آدرس callback — زرین‌پال بعد از پرداخت کاربر را به اینجا هدایت می‌کند
var cmsBaseUrl = _configuration["CmsBaseUrl"] ?? "https://localhost:32846";
var callbackUrl = $"{cmsBaseUrl}/api/payment/discount-order/callback?orderId={order.Id}";
// آدرس callback — زرین‌پال بعد از پرداخت مستقیم به فرانت‌آفیس هدایت می‌کند
var frontOfficeBaseUrl = _configuration["FrontOfficeBaseUrl"] ?? "https://localhost:5268";
var callbackUrl = $"{frontOfficeBaseUrl}/profile/payment-callback?type=discount-order&orderId={order.Id}";
// درخواست به درگاه
var paymentResult = await _paymentGateway.InitiatePaymentAsync(new PaymentRequest
@@ -62,9 +62,9 @@ public class ChargeDiscountWalletCommandHandler
throw new NotFoundException("کیف پول کاربر یافت نشد");
}
// 3. ایجاد درخواست پرداخت
var cmsBaseUrl = _configuration["CmsBaseUrl"] ?? "https://localhost:32846";
var callbackUrl = $"{cmsBaseUrl}/api/wallet/verify-discount-charge";
// 3. ایجاد درخواست پرداخت — callback مستقیم به فرانت‌آفیس
var frontOfficeBaseUrl = _configuration["FrontOfficeBaseUrl"] ?? "https://localhost:5268";
var callbackUrl = $"{frontOfficeBaseUrl}/profile/payment-callback?type=discount-wallet";
var paymentRequest = new PaymentRequest
{
@@ -113,9 +113,9 @@ public class ChargeMagicWalletCommandHandler
);
}
// 5. ایجاد درخواست پرداخت
var cmsBaseUrl = _configuration["CmsBaseUrl"] ?? "https://localhost:32846";
var callbackUrl = $"{cmsBaseUrl}/api/wallet/verify-magic-charge";
// 5. ایجاد درخواست پرداخت — callback مستقیم به فرانت‌آفیس
var frontOfficeBaseUrl = _configuration["FrontOfficeBaseUrl"] ?? "https://localhost:5268";
var callbackUrl = $"{frontOfficeBaseUrl}/profile/payment-callback?type=magic-wallet";
var paymentRequest = new PaymentRequest
{