Files
tiku-backend.net/Tiku.Infrastructure/PlatformBilling/PlatformBillingNotificationService.cs
xiong 33375a38d7
Some checks failed
ci / release-gate (push) Has been cancelled
refactor(architecture): harden module boundaries
2026-08-04 12:10:36 +08:00

62 lines
3.1 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Tiku.Application.Commerce;
using Tiku.Application.PlatformBilling;
using Tiku.Application.Security;
using Tiku.Infrastructure.Persistence;
namespace Tiku.Infrastructure.PlatformBilling;
internal sealed class PlatformBillingNotificationService(
ITenantExecutionScope tenantExecutionScope,
IPlatformBillingPaymentGateway paymentGateway) : IPlatformBillingNotificationService
{
public async Task ProcessAsync(PlatformBillingNotification notification,
CancellationToken cancellationToken = default)
{
var parsed = await paymentGateway.ParseNotificationAsync(
notification.Provider,
new PaymentNotificationRequest(Guid.Empty, notification.Provider, notification.Headers,
notification.RawBody, notification.Body),
cancellationToken);
if (!parsed.SignatureValid || !parsed.Paid)
throw Error("Payment notification was not a valid paid event.", "platform_billing_notification_invalid");
await tenantExecutionScope.ExecuteAsync(
new SystemScopeRequest(null, SystemScopeCallerType.Platform, nameof(PlatformBillingNotificationService),
"Settle platform billing notification", parsed.EventId, true),
async (services, token) =>
{
var db = services.GetRequiredService<IPlatformBillingPersistence>();
var order = await db.PlatformBillingOrders.AsNoTracking()
.SingleOrDefaultAsync(value => value.OrderNo == parsed.OrderNo, token)
?? throw Error("Platform billing order was not found.", "platform_billing_order_not_found");
if (order.TotalAmountCents != parsed.AmountCents)
throw Error("Payment notification amount does not match the order.",
"platform_billing_payment_amount_mismatch");
var payment = await db.PlatformBillingPayments.AsNoTracking()
.Where(value =>
value.TenantId == order.TenantId && value.OrderId == order.Id &&
value.Provider == parsed.Provider)
.OrderByDescending(value => value.CreatedAt)
.FirstOrDefaultAsync(token)
?? throw Error("Platform billing payment was not found.",
"platform_billing_payment_not_found");
await services.GetRequiredService<IPlatformBillingSettlementService>().MarkPaidAsync(
payment.Id,
parsed.EventId,
parsed.EventType,
parsed.ProviderTradeNo,
parsed.PaidAt ?? DateTimeOffset.UtcNow,
parsed.RawPayload,
null,
token);
},
cancellationToken);
}
private static PlatformBillingException Error(string message, string code)
{
return new PlatformBillingException(message, code);
}
}