Files
Wabenhain/src/lib/stripe.ts
T
Nick SzaunigandClaude Opus 5.5 1c5282e84f fix: fehlenden STRIPE_PUBLISHABLE_KEY im Server-Log melden
Bisher fiel der fehlende Schluessel nur in der Kasse auf ("Zahlung gerade
nicht verfuegbar"), nie im Log des Pods.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-25 13:01:00 +02:00

69 lines
2.5 KiB
TypeScript

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;
}