import Stripe from "stripe"; let stripeClient: Stripe | null = null; /** * Lazily erzeugter Stripe-Client. Wirft erst beim tatsächlichen Checkout einen * verstaendlichen Fehler, wenn STRIPE_SECRET_KEY fehlt, statt den Server-Start * (z.B. in Docker ohne konfigurierte Zahlungsdaten) zu blockieren. */ export function getStripeClient(): Stripe { if (stripeClient) return stripeClient; const secretKey = process.env.STRIPE_SECRET_KEY; if (!secretKey) { throw new Error( "STRIPE_SECRET_KEY ist nicht gesetzt. Bitte in der .env-Datei konfigurieren." ); } // Ein sk_test_-Schluessel in Produktion faellt sonst nicht auf: Bestellungen // wirken vollstaendig erfolgreich (Stripe-Testmodus quittiert brav), es // fliesst aber nie echtes Geld — ein stiller Umsatzausfall statt eines // Fehlers. if (process.env.NODE_ENV === "production" && secretKey.startsWith("sk_test_")) { console.warn( "STRIPE_SECRET_KEY ist in Produktion ein Test-Schluessel (sk_test_...) — Zahlungen werden im Stripe-Testmodus verarbeitet, es fliesst kein echtes Geld." ); } stripeClient = new Stripe(secretKey); return stripeClient; } /** * Oeffentlicher Schluessel (pk_...) fuer das eingebettete Zahlungsformular. * * Bewusst ohne NEXT_PUBLIC_-Praefix und zur Laufzeit gelesen: Next.js brennt * NEXT_PUBLIC_-Variablen beim Build fest ein, das Docker-Image wird aber * einmal gebaut und erst im Cluster konfiguriert. Die Seite reicht den Wert * deshalb als Prop an den Browser weiter. * * Alles, was nicht wie ein veroeffentlichbarer Schluessel aussieht, gilt als * nicht gesetzt — vor allem ein versehentlich hier eingetragener geheimer * Schluessel (sk_/rk_), der sonst im HTML jeder Kassenseite stuende. */ let missingPublishableKeyLogged = false; export function getStripePublishableKey(): string | undefined { const key = process.env.STRIPE_PUBLISHABLE_KEY?.trim(); if (!key) { // Sonst faellt das Fehlen nur in der Kasse auf ("Zahlung gerade nicht // verfuegbar"), nie im Log. Einmal je Prozess genuegt. if (!missingPublishableKeyLogged) { missingPublishableKeyLogged = true; console.error( "STRIPE_PUBLISHABLE_KEY ist nicht gesetzt — der Checkout nimmt keine Bestellungen an. In k8s/01-configmap.yaml eintragen und den Pod neu starten." ); } return undefined; } if (!/^pk_(test|live)_[A-Za-z0-9]+$/.test(key)) { console.error( "STRIPE_PUBLISHABLE_KEY ist kein veroeffentlichbarer Schluessel (pk_test_/pk_live_) und wird ignoriert." ); return undefined; } return key; }