forked from xiongyuxing/tiku-backend.net
feat: add payment sdk and tenant secret foundation
This commit is contained in:
80
Tiku.Infrastructure/Commerce/PaymentProviderConfigService.cs
Normal file
80
Tiku.Infrastructure/Commerce/PaymentProviderConfigService.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Tiku.Application.Commerce;
|
||||
using Tiku.Domain.Commerce;
|
||||
using Tiku.Infrastructure.Persistence;
|
||||
|
||||
namespace Tiku.Infrastructure.Commerce;
|
||||
|
||||
internal sealed class PaymentProviderConfigService(
|
||||
TikuDbContext dbContext,
|
||||
ITenantSecretService tenantSecretService) : IPaymentProviderConfigService
|
||||
{
|
||||
public async Task<PaymentProviderAccount> GetActiveAccountAsync(
|
||||
Guid tenantId,
|
||||
string provider,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var normalizedProvider = NormalizeProvider(provider);
|
||||
var account = await dbContext.TenantPaymentAccounts
|
||||
.AsNoTracking()
|
||||
.Where(item =>
|
||||
item.TenantId == tenantId &&
|
||||
item.Provider == normalizedProvider &&
|
||||
item.Status == TenantPaymentAccountStatus.Active)
|
||||
.SingleOrDefaultAsync(cancellationToken);
|
||||
|
||||
if (account is null)
|
||||
{
|
||||
throw new PaymentProviderException(
|
||||
"Payment provider account is not configured.",
|
||||
"payment_provider_not_configured");
|
||||
}
|
||||
|
||||
var secretPayload = normalizedProvider == PaymentProviders.Manual
|
||||
? JsonDocument.Parse("{}").RootElement.Clone()
|
||||
: await tenantSecretService.GetActiveSecretPayloadAsync(
|
||||
tenantId,
|
||||
GetString(account.ConfigPublic, "secretRef", "secret_ref") ?? string.Empty,
|
||||
cancellationToken);
|
||||
|
||||
return new PaymentProviderAccount(
|
||||
account.TenantId,
|
||||
normalizedProvider,
|
||||
account.Mode.ToString(),
|
||||
account.ConfigPublic,
|
||||
secretPayload);
|
||||
}
|
||||
|
||||
private static string NormalizeProvider(string provider)
|
||||
{
|
||||
var normalized = provider.Trim().ToLowerInvariant().Replace("-", "_", StringComparison.Ordinal);
|
||||
|
||||
return normalized switch
|
||||
{
|
||||
"wechat" or "wechatpay" or "wxpay" or "wx_pay" => PaymentProviders.WechatPay,
|
||||
"ali_pay" => PaymentProviders.Alipay,
|
||||
"" => throw new PaymentProviderException("Payment provider is required.", "payment_provider_required"),
|
||||
_ => normalized
|
||||
};
|
||||
}
|
||||
|
||||
private static string? GetString(JsonElement element, params string[] keys)
|
||||
{
|
||||
if (element.ValueKind != JsonValueKind.Object)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var key in keys)
|
||||
{
|
||||
if (element.TryGetProperty(key, out var property) &&
|
||||
property.ValueKind == JsonValueKind.String)
|
||||
{
|
||||
return property.GetString();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user