import "server-only"; import type { ServerEnvironment } from "@salixcommerce/config/server"; import type { PaymentProvider } from "@salixcommerce/core"; import { createStripePaymentProvider } from "@salixcommerce/stripe"; import { serverEnvironment } from "@/config/server"; import { commerceRepository } from "../commerce/commerce"; import type { CommerceRepository } from "../commerce/repository"; import { emptyPaymentRepository } from "./empty-payment-repository"; import { createFakePaymentProvider, type FakePaymentProvider } from "./fake-payment-provider"; import { createPaymentService } from "./payment-service"; import type { PaymentRepository } from "./repository"; import { createSupabasePaymentRepository } from "./supabase-payment-repository"; export interface PaymentRuntime { readonly enabled: boolean; readonly fakeProvider?: FakePaymentProvider; readonly provider: PaymentProvider | null; readonly repository: PaymentRepository; readonly service: ReturnType; } export function createPaymentRuntime( environment: ServerEnvironment, commerce: CommerceRepository, ): PaymentRuntime { const repository = createRepository(environment); let fakeProvider: FakePaymentProvider | undefined; let provider: PaymentProvider | null = null; if (environment.SALIX_PAYMENT_PROVIDER === "fake") { if (environment.SALIX_FAKE_PAYMENT_SECRET === undefined) { throw new Error("Fake payment configuration passed validation without a signing secret."); } fakeProvider = createFakePaymentProvider({ secret: environment.SALIX_FAKE_PAYMENT_SECRET }); provider = fakeProvider; } else if (environment.SALIX_PAYMENT_PROVIDER === "stripe") { if ( environment.SALIX_CHECKOUT_BASE_URL === undefined || environment.SALIX_STRIPE_SECRET_KEY === undefined || environment.SALIX_STRIPE_WEBHOOK_SECRET === undefined ) { throw new Error("Stripe payment configuration passed validation while incomplete."); } provider = createStripePaymentProvider({ checkoutBaseUrl: environment.SALIX_CHECKOUT_BASE_URL, secretKey: environment.SALIX_STRIPE_SECRET_KEY, webhookSecret: environment.SALIX_STRIPE_WEBHOOK_SECRET, }); } const service = createPaymentService({ commerceRepository: commerce, ...(fakeProvider === undefined ? {} : { fakeProvider }), provider, repository, }); return Object.freeze({ enabled: provider !== null && repository !== emptyPaymentRepository, ...(fakeProvider === undefined ? {} : { fakeProvider }), provider, repository, service, }); } function createRepository(environment: ServerEnvironment): PaymentRepository { if ( environment.SALIX_SUPABASE_URL === undefined || environment.SALIX_SUPABASE_SERVICE_ROLE_KEY === undefined ) { return emptyPaymentRepository; } return createSupabasePaymentRepository({ serviceRoleKey: environment.SALIX_SUPABASE_SERVICE_ROLE_KEY, url: environment.SALIX_SUPABASE_URL, }); } export const paymentRuntime = createPaymentRuntime(serverEnvironment, commerceRepository); export const paymentEnabled = paymentRuntime.enabled; export const paymentRepository = paymentRuntime.repository; export const paymentService = paymentRuntime.service;