feat: Stripe Embedded Checkout statt Weiterleitung zu checkout.stripe.com
Bezahlt wird jetzt direkt auf /checkout: die Checkout-Session laeuft mit ui_mode "embedded_page", das Zahlungsformular ist ein Stripe-iframe (PCI SAQ A bleibt). PayPal, Karte, SEPA und Klarna kommen weiterhin dynamisch aus dem Dashboard. - Zahlungsschritt ersetzt das Formular; "Zurueck zu deinen Angaben" gibt Sitzung und Bestand sofort frei (POST /api/checkout/cancel) und behaelt alle Eingaben, Turnstile wird neu geladen - Rueckkehrseite prueft serverseitig bei Stripe und gleicht die Sitzung mit der eigenen Bestellung ab; bei abgebrochener PayPal-Zahlung wird dieselbe Sitzung erneut eingebettet - Erneuter Versuch und Abbruch sind per HttpOnly-Cookie an den bestellenden Browser gebunden, die session_id in der URL allein reicht nicht - Alte /checkout/cancel?ref= Links aendern per GET nichts mehr - CSP um die Stripe-Hosts fuer Embedded Checkout und 3-D-Secure erweitert - STRIPE_PUBLISHABLE_KEY zur Laufzeit gelesen (kein NEXT_PUBLIC_), mit Preflight-Pruefung auf pk_live und Schutz gegen versehentliche sk_/rk_ Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
6ac7cc5d1f
commit
4ee5bafe20
28 files changed
+1272
-179
No files matched your search
@@ -30,3 +30,27 @@ export function getStripeClient(): Stripe {
|
||||
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.
|
||||
*/
|
||||
export function getStripePublishableKey(): string | undefined {
|
||||
const key = process.env.STRIPE_PUBLISHABLE_KEY?.trim();
|
||||
if (!key) 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;
|
||||
}
|
||||
Reference in new issue
Block a user