using CMSMicroservice.Application.Common.Interfaces; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using System.Net.Http; using System.Net.Http.Json; using System.Text.Json; namespace CMSMicroservice.Infrastructure.Services.Payment; /// /// Real Implementation برای درگاه پرداخت دایا /// برای فعال‌سازی: باید URL و API Key را در appsettings.json تنظیم کنید /// public class DayaPaymentService : IPaymentGatewayService { private readonly HttpClient _httpClient; private readonly IConfiguration _configuration; private readonly ILogger _logger; private readonly string _apiKey; private readonly string _baseUrl; public DayaPaymentService( HttpClient httpClient, IConfiguration configuration, ILogger logger) { _httpClient = httpClient; _configuration = configuration; _logger = logger; // خواندن تنظیمات از appsettings.json _baseUrl = _configuration["DayaPayment:BaseUrl"] ?? "https://api.daya.ir"; _apiKey = _configuration["DayaPayment:ApiKey"] ?? throw new InvalidOperationException( "DayaPayment:ApiKey is not configured in appsettings.json"); _httpClient.BaseAddress = new Uri(_baseUrl); _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}"); _httpClient.Timeout = TimeSpan.FromSeconds(30); } public async Task InitiatePaymentAsync( PaymentRequest request, CancellationToken cancellationToken = default) { try { _logger.LogInformation( "Initiating Daya payment: UserId={UserId}, Amount={Amount}", request.UserId, request.Amount); // ساختار Request برای API دایا var apiRequest = new { amount = request.Amount, mobile = request.Mobile, description = request.Description, callback_url = request.CallbackUrl, user_id = request.UserId }; var response = await _httpClient.PostAsJsonAsync( "/api/v1/payment/initiate", apiRequest, cancellationToken); if (!response.IsSuccessStatusCode) { var errorContent = await response.Content.ReadAsStringAsync(cancellationToken); _logger.LogError( "Daya API error: StatusCode={StatusCode}, Error={Error}", response.StatusCode, errorContent); return new PaymentInitiateResult { IsSuccess = false, ErrorMessage = $"خطا در ارتباط با درگاه: {response.StatusCode}" }; } var result = await response.Content.ReadFromJsonAsync(cancellationToken); if (result == null || string.IsNullOrEmpty(result.RefId)) { _logger.LogError("Invalid response from Daya API"); return new PaymentInitiateResult { IsSuccess = false, ErrorMessage = "پاسخ نامعتبر از درگاه" }; } _logger.LogInformation( "Daya payment initiated successfully: RefId={RefId}", result.RefId); return new PaymentInitiateResult { IsSuccess = true, RefId = result.RefId, GatewayUrl = result.GatewayUrl, ErrorMessage = null }; } catch (HttpRequestException ex) { _logger.LogError(ex, "Network error while calling Daya API"); return new PaymentInitiateResult { IsSuccess = false, ErrorMessage = "خطا در ارتباط با سرور درگاه" }; } catch (Exception ex) { _logger.LogError(ex, "Unexpected error in InitiatePaymentAsync"); return new PaymentInitiateResult { IsSuccess = false, ErrorMessage = "خطای غیرمنتظره" }; } } public async Task VerifyPaymentAsync( string refId, string verificationToken, CancellationToken cancellationToken = default) { try { _logger.LogInformation("Verifying Daya payment: RefId={RefId}", refId); var apiRequest = new { ref_id = refId, token = verificationToken }; var response = await _httpClient.PostAsJsonAsync( "/api/v1/payment/verify", apiRequest, cancellationToken); if (!response.IsSuccessStatusCode) { var errorContent = await response.Content.ReadAsStringAsync(cancellationToken); _logger.LogError( "Daya verification error: StatusCode={StatusCode}, Error={Error}", response.StatusCode, errorContent); return new PaymentVerificationResult { IsSuccess = false, RefId = refId, Message = $"خطا در تأیید پرداخت: {response.StatusCode}" }; } var result = await response.Content.ReadFromJsonAsync(cancellationToken); if (result == null) { return new PaymentVerificationResult { IsSuccess = false, RefId = refId, Message = "پاسخ نامعتبر از درگاه" }; } _logger.LogInformation( "Daya payment verified: RefId={RefId}, IsSuccess={IsSuccess}, TrackingCode={TrackingCode}", refId, result.IsSuccess, result.TrackingCode); return new PaymentVerificationResult { IsSuccess = result.IsSuccess, RefId = refId, TrackingCode = result.TrackingCode, Amount = result.Amount, Message = result.Message }; } catch (Exception ex) { _logger.LogError(ex, "Error in VerifyPaymentAsync"); return new PaymentVerificationResult { IsSuccess = false, RefId = refId, Message = "خطا در تأیید پرداخت" }; } } public async Task ProcessPayoutAsync( PayoutRequest request, CancellationToken cancellationToken = default) { try { _logger.LogInformation( "Processing Daya payout: UserId={UserId}, Amount={Amount}, IBAN={Iban}", request.UserId, request.Amount, request.Iban); // Validation if (!request.Iban.StartsWith("IR") || request.Iban.Length != 26) { _logger.LogWarning("Invalid IBAN format: {Iban}", request.Iban); return new PayoutResult { IsSuccess = false, Message = "فرمت شماره شبا نامعتبر است", ProcessedAt = DateTime.Now }; } if (request.Amount < 10_000) { _logger.LogWarning("Amount too low: {Amount}", request.Amount); return new PayoutResult { IsSuccess = false, Message = "حداقل مبلغ برداشت 10,000 تومان است", ProcessedAt = DateTime.Now }; } var apiRequest = new { amount = request.Amount, iban = request.Iban, account_holder_name = request.AccountHolderName, description = request.Description, internal_ref_id = request.InternalRefId, user_id = request.UserId }; var response = await _httpClient.PostAsJsonAsync( "/api/v1/payout/process", apiRequest, cancellationToken); if (!response.IsSuccessStatusCode) { var errorContent = await response.Content.ReadAsStringAsync(cancellationToken); _logger.LogError( "Daya payout error: StatusCode={StatusCode}, Error={Error}", response.StatusCode, errorContent); return new PayoutResult { IsSuccess = false, Message = $"خطا در واریز: {response.StatusCode}", ProcessedAt = DateTime.Now }; } var result = await response.Content.ReadFromJsonAsync(cancellationToken); if (result == null) { return new PayoutResult { IsSuccess = false, Message = "پاسخ نامعتبر از درگاه", ProcessedAt = DateTime.Now }; } _logger.LogInformation( "Daya payout processed: IsSuccess={IsSuccess}, BankRefId={BankRefId}", result.IsSuccess, result.BankRefId); return new PayoutResult { IsSuccess = result.IsSuccess, BankRefId = result.BankRefId, TrackingCode = result.TrackingCode, Message = result.Message, ProcessedAt = DateTime.Now }; } catch (Exception ex) { _logger.LogError(ex, "Error in ProcessPayoutAsync"); return new PayoutResult { IsSuccess = false, Message = "خطا در پردازش واریز", ProcessedAt = DateTime.Now }; } } // DTO classes for Daya API private class DayaInitiateResponse { public string RefId { get; set; } = string.Empty; public string GatewayUrl { get; set; } = string.Empty; } private class DayaVerifyResponse { public bool IsSuccess { get; set; } public string TrackingCode { get; set; } = string.Empty; public decimal Amount { get; set; } public string Message { get; set; } = string.Empty; } private class DayaPayoutResponse { public bool IsSuccess { get; set; } public string BankRefId { get; set; } = string.Empty; public string TrackingCode { get; set; } = string.Empty; public string Message { get; set; } = string.Empty; } }