using System.Threading.Tasks; using System.Threading; using AIK.Common.Interface; using AIK.Common.SysCommon; using AIK.Models; using AIK.Models.ApiModels; using AIK.Models.ApiModels.Payment; using AIK.Service.IService; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net; namespace AIK.Service.Service { public class PaymentOrderService : IPaymentOrderService { private readonly IHttpClientService _httpClientService; private readonly IConfigurationService _configurationService; private readonly ISettingsService _settingsService; private readonly IRetryPolicyService _retryPolicyService; private readonly ILogger _logger; public PaymentOrderService( IHttpClientService httpClientService, IConfigurationService configurationService, ISettingsService settingsService, IRetryPolicyService retryPolicyService, ILogger logger) { _httpClientService = httpClientService; _configurationService = configurationService; _settingsService = settingsService; _retryPolicyService = retryPolicyService; _logger = logger; } public Task CreateIntegralOrderAsync(string token, CreateIntegralOrderRequest request, CancellationToken cancellationToken = default) { return _retryPolicyService.ExecuteWithRetryAsync(async () => { var url = BuildUrl(WebApiAddress.PayIntegralOrder, new() { ["amount"] =request.Amount.ToString(CultureInfo.InvariantCulture), ["payType"] = request.PayType.ToString(CultureInfo.InvariantCulture), ["channel"] = request.Channel, ["qrcode"] = 1.ToString() }); var response = await _httpClientService.GetStringWithTimeoutAndTokenAsync(url, token, TimeSpan.FromSeconds(15), cancellationToken); var apiResponse = DeserializeResponse(response, nameof(CreateIntegralOrderAsync)); return IsSuccess(apiResponse) ? apiResponse.Data : null; }, nameof(CreateIntegralOrderAsync), cancellationToken); } public Task GetOrderPayStatusAsync(long orderId, int type = 2, CancellationToken cancellationToken = default) { return _retryPolicyService.ExecuteWithRetryAsync(async () => { var url = BuildUrl($"{WebApiAddress.OrderPayStatus}/{orderId}", new() { ["type"] = type.ToString(CultureInfo.InvariantCulture) }); var response = await _httpClientService.GetStringWithTimeoutAsync(url, TimeSpan.FromSeconds(15), cancellationToken); var apiResponse = DeserializeResponse(response, nameof(GetOrderPayStatusAsync)); return IsSuccess(apiResponse) ? apiResponse.Data : null; }, nameof(GetOrderPayStatusAsync), cancellationToken); } public Task RefreshPaypalOrderAsync(long orderId, int type = 2, CancellationToken cancellationToken = default) { return _retryPolicyService.ExecuteWithRetryAsync(async () => { var url = BuildUrl($"{WebApiAddress.OrderPaypal}/{orderId}", new() { ["type"] = type.ToString(CultureInfo.InvariantCulture) }); var response = await _httpClientService.GetStringWithTimeoutAsync(url, TimeSpan.FromSeconds(15), cancellationToken); var apiResponse = DeserializeResponse(response, nameof(RefreshPaypalOrderAsync)); return IsSuccess(apiResponse) ? apiResponse.Data : null; }, nameof(RefreshPaypalOrderAsync), cancellationToken); } private string BuildUrl(string path, Dictionary? query = null) { var url = $"{_configurationService.ApiSettings.BaseUrl}{path}"; if (query == null || query.Count == 0) { return url; } var queryString = string.Join("&", query .Where(item => !string.IsNullOrWhiteSpace(item.Value)) .Select(item => $"{WebUtility.UrlEncode(item.Key)}={WebUtility.UrlEncode(item.Value)}")); return string.IsNullOrEmpty(queryString) ? url : $"{url}?{queryString}"; } private ApiResponse DeserializeResponse(string response, string operationName) { var apiResponse = JsonConvert.DeserializeObject>(response) ?? new ApiResponse(); if (!IsSuccess(apiResponse)) { _logger.LogWarning("{OperationName} failed. Code: {Code}, Message: {Message}, Response: {Response}", operationName, apiResponse.Code, apiResponse.Msg, response); } return apiResponse; } private static bool IsSuccess(ApiResponse response) { return response.Code == 1; } } }