兼容win7版应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
5.2 KiB

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<PaymentOrderService> _logger;
public PaymentOrderService(
IHttpClientService httpClientService,
IConfigurationService configurationService,
ISettingsService settingsService,
IRetryPolicyService retryPolicyService,
ILogger<PaymentOrderService> logger)
{
_httpClientService = httpClientService;
_configurationService = configurationService;
_settingsService = settingsService;
_retryPolicyService = retryPolicyService;
_logger = logger;
}
public Task<PaymentParametersPC?> CreateIntegralOrderAsync(string token, CreateIntegralOrderRequest request, CancellationToken cancellationToken = default)
{
return _retryPolicyService.ExecuteWithRetryAsync<PaymentParametersPC?>(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<PaymentParametersPC>(response, nameof(CreateIntegralOrderAsync));
return IsSuccess(apiResponse) ? apiResponse.Data : null;
}, nameof(CreateIntegralOrderAsync), cancellationToken);
}
public Task<int?> GetOrderPayStatusAsync(long orderId, int type = 2, CancellationToken cancellationToken = default)
{
return _retryPolicyService.ExecuteWithRetryAsync<int?>(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<int?>(response, nameof(GetOrderPayStatusAsync));
return IsSuccess(apiResponse) ? apiResponse.Data : null;
}, nameof(GetOrderPayStatusAsync), cancellationToken);
}
public Task<int?> RefreshPaypalOrderAsync(long orderId, int type = 2, CancellationToken cancellationToken = default)
{
return _retryPolicyService.ExecuteWithRetryAsync<int?>(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<int?>(response, nameof(RefreshPaypalOrderAsync));
return IsSuccess(apiResponse) ? apiResponse.Data : null;
}, nameof(RefreshPaypalOrderAsync), cancellationToken);
}
private string BuildUrl(string path, Dictionary<string, string?>? 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<T> DeserializeResponse<T>(string response, string operationName)
{
var apiResponse = JsonConvert.DeserializeObject<ApiResponse<T>>(response) ?? new ApiResponse<T>();
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<T>(ApiResponse<T> response)
{
return response.Code == 1;
}
}
}