using System.Text.Json; using Microsoft.EntityFrameworkCore; using Tiku.Application.Commerce; using Tiku.Domain.Tenancy; using Tiku.Infrastructure.Persistence; namespace Tiku.Infrastructure.Commerce; internal sealed class TenantSecretService( ITenancyPersistence dbContext, ITenantSecretProtector tenantSecretProtector) : ITenantSecretService { public async Task GetActiveSecretPayloadAsync( Guid tenantId, string secretRef, CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(secretRef)) throw new PaymentProviderException( "Payment provider secret is not configured.", "payment_secret_not_configured"); var now = DateTimeOffset.UtcNow; var secret = await dbContext.TenantSecrets .AsNoTracking() .Where(item => item.TenantId == tenantId && item.SecretRef == secretRef && item.Status == TenantSecretStatus.Active && (item.ExpiresAt == null || item.ExpiresAt > now)) .SingleOrDefaultAsync(cancellationToken); if (secret is null) throw new PaymentProviderException( "Payment provider secret is not configured.", "payment_secret_not_configured"); if (secret.EncryptedPayload.Length > 0) return tenantSecretProtector.Unprotect( tenantId, secretRef, secret.EncryptionKeyId, secret.EncryptedPayload, secret.EncryptionNonce, secret.EncryptionTag); throw new PaymentProviderException( "Payment provider secret is not configured.", "payment_secret_not_configured"); } }