using System.Reflection; using GB5Shared.GOP.Qualifier; using GB5Shared.DaprCache; using GB5Shared.DTO.Framework.Login; using GB5Shared.EntityHandler; using GB5Shared.EventLogPublish; using GB5Shared.GB5Library.Qualifier; using GB5Shared.Hosting; using GB5Shared.ListQuery; using GB5Shared.PubSub.OutBox; using GoodBooks.PAY.PAYBLL.Factory; using GoodBooks.PAY.PAYBLL.Vault; using GoodBooks.PAY.PAYSL.Services; using Microsoft.AspNetCore.ResponseCompression; using Newtonsoft.Json; using VaultSharp; using VaultSharp.V1.AuthMethods.Token; namespace PAYSL; public class PAYModule : IModule { public void Register(IServiceCollection services, IConfiguration configuration) { services.AddHttpContextAccessor(); services.AddHttpClient(); // LoginDTO resolved from the Login request header (empty fallback for background scopes) services.AddScoped(sp => { var httpContext = sp.GetRequiredService().HttpContext; if (httpContext != null && httpContext.Request.Headers.TryGetValue("Login", out var loginHeader)) return JsonConvert.DeserializeObject(loginHeader!)!; return new LoginDTO(); }); services.AddScoped(); services.AddScoped(); services.AddScoped(typeof(BaseEntityAppService<>), typeof(BaseEntityAppService<>)); services.AddScoped(); services.AddGB5QualifierEngine(); services.AddScoped(); // Vault — Singleton (thread-safe IVaultClient + in-memory secret cache) services.AddSingleton(sp => { var authMethod = new TokenAuthMethodInfo(configuration["Vault:Token"]!); var settings = new VaultClientSettings(configuration["Vault:Address"]!, authMethod); return new VaultClient(settings); }); services.AddSingleton(); // Payment gateway factory — Singleton (stateless) services.AddSingleton(); // Gateway HTTP clients services.AddHttpClient("Razorpay", c => { c.BaseAddress = new Uri("https://api.razorpay.com/v1/"); c.Timeout = TimeSpan.FromSeconds(30); }); services.AddHttpClient("Stripe", c => { c.BaseAddress = new Uri("https://api.stripe.com/v1/"); c.Timeout = TimeSpan.FromSeconds(30); }); // Cross-module HTTP clients services.AddHttpClient("SalesModule", c => { c.BaseAddress = new Uri(configuration["Integration:SalesModuleBaseUrl"] ?? throw new InvalidOperationException("Integration:SalesModuleBaseUrl not configured in appsettings.json")); c.Timeout = TimeSpan.FromSeconds(10); }); services.AddHttpClient("FinanceModule", c => { c.BaseAddress = new Uri(configuration["Integration:FinanceModuleBaseUrl"] ?? throw new InvalidOperationException("Integration:FinanceModuleBaseUrl not configured in appsettings.json")); c.Timeout = TimeSpan.FromSeconds(15); }); services.AddResponseCompression(o => { o.EnableForHttps = true; o.Providers.Add(); }); var payBllAssembly = Assembly.Load("PAYBLL"); var payDalAssembly = Assembly.Load("PAYDAL"); services.Scan(scan => scan .FromAssemblies(payBllAssembly, payDalAssembly) .AddClasses(c => c.Where(t => !t.IsAbstract && !t.IsInterface && t.Namespace != null && !t.Namespace.Contains(".DTO") && !typeof(Exception).IsAssignableFrom(t) && t.GetMethod("$") == null)) .AsImplementedInterfaces() .WithScopedLifetime()); services.AddListInfrastructure(payDalAssembly); services.AddHostedService(); services.AddHostedService(); } public void MapEndpoints(WebApplication app) { } }