forked from gongxuegit/tiku-backend.net
feat(saas): implement marketplace and tenant onboarding
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Tiku.Application.Commerce;
|
||||
using Tiku.Application.PlatformBilling;
|
||||
using Tiku.Application.Security;
|
||||
using Tiku.Domain.Tenancy;
|
||||
using Tiku.Infrastructure.Persistence;
|
||||
|
||||
namespace Tiku.Infrastructure.PlatformBilling;
|
||||
|
||||
internal sealed class PlatformBillingPaymentGateway(
|
||||
ITenantExecutionScope tenantExecutionScope) : IPlatformBillingPaymentGateway
|
||||
{
|
||||
public Task<CreatePaymentProviderResult> CreatePaymentAsync(
|
||||
string provider,
|
||||
CreatePaymentProviderRequest request,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
ExecuteAsync(provider, request.OrderNo, async (resolvedProvider, account, token) =>
|
||||
await resolvedProvider.CreatePaymentAsync(account, request, token), cancellationToken);
|
||||
|
||||
public Task<PaymentNotificationResult> ParseNotificationAsync(
|
||||
string provider,
|
||||
PaymentNotificationRequest request,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
ExecuteAsync(provider, "payment-notification", async (resolvedProvider, account, token) =>
|
||||
await resolvedProvider.ParsePaymentNotificationAsync(account, request, token), cancellationToken);
|
||||
|
||||
private Task<TResult> ExecuteAsync<TResult>(
|
||||
string provider,
|
||||
string correlationId,
|
||||
Func<IPaymentProvider, PaymentProviderAccount, CancellationToken, Task<TResult>> operation,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return tenantExecutionScope.ExecuteAsync(
|
||||
new SystemScopeRequest(
|
||||
null,
|
||||
SystemScopeCallerType.Platform,
|
||||
nameof(PlatformBillingPaymentGateway),
|
||||
"Resolve the platform-owned SaaS billing payment account",
|
||||
correlationId,
|
||||
IsGlobal: true),
|
||||
async (services, token) =>
|
||||
{
|
||||
var dbContext = services.GetRequiredService<TikuDbContext>();
|
||||
var platformTenantId = await dbContext.Tenants.AsNoTracking()
|
||||
.Where(value => value.Mode == TenantMode.PlatformOwned)
|
||||
.Select(value => value.Id)
|
||||
.SingleOrDefaultAsync(token);
|
||||
if (platformTenantId == Guid.Empty)
|
||||
{
|
||||
throw new PaymentProviderException("Platform-owned tenant is missing.", "platform_payment_owner_missing");
|
||||
}
|
||||
|
||||
var normalized = NormalizeProvider(provider);
|
||||
var resolvedProvider = services.GetServices<IPaymentProvider>()
|
||||
.SingleOrDefault(value => value.Provider == normalized)
|
||||
?? throw new PaymentProviderException("Payment provider is not supported.", "payment_provider_not_supported");
|
||||
PaymentProviderAccount account;
|
||||
if (normalized == PaymentProviders.Manual)
|
||||
{
|
||||
account = new PaymentProviderAccount(
|
||||
platformTenantId,
|
||||
PaymentProviders.Manual,
|
||||
"PlatformCollect",
|
||||
JsonDocument.Parse("{}").RootElement.Clone(),
|
||||
JsonDocument.Parse("{}").RootElement.Clone());
|
||||
}
|
||||
else
|
||||
{
|
||||
account = await services.GetRequiredService<IPaymentProviderConfigService>()
|
||||
.GetActiveAccountAsync(platformTenantId, normalized, token);
|
||||
}
|
||||
|
||||
return await operation(resolvedProvider, account, token);
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
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,
|
||||
PaymentProviders.WechatPay or PaymentProviders.Alipay or PaymentProviders.Manual => normalized,
|
||||
_ => throw new PaymentProviderException("Payment provider is not supported.", "payment_provider_not_supported")
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user