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
+9
-4
@@ -23,12 +23,17 @@ const isDev = process.env.NODE_ENV === "development";
|
||||
function buildCsp(nonce: string): string {
|
||||
return [
|
||||
"default-src 'self'",
|
||||
`script-src 'self' 'nonce-${nonce}' 'strict-dynamic' https://challenges.cloudflare.com${isDev ? " 'unsafe-eval'" : ""}`,
|
||||
// Stripe-Hosts laut https://docs.stripe.com/security/guide (Abschnitte
|
||||
// "Checkout" und "Stripe.js") fuer den eingebetteten Checkout. In
|
||||
// script-src greifen sie nur in Browsern ohne 'strict-dynamic'; die
|
||||
// uebrigen laden Stripe.js, weil ein genoncetes Skript es nachlaedt.
|
||||
// hooks.stripe.com: 3-D-Secure und Weiterleitungs-Zahlungsarten.
|
||||
`script-src 'self' 'nonce-${nonce}' 'strict-dynamic' https://challenges.cloudflare.com https://js.stripe.com https://*.js.stripe.com https://checkout.stripe.com${isDev ? " 'unsafe-eval'" : ""}`,
|
||||
"style-src 'self' 'unsafe-inline'",
|
||||
"img-src 'self' data: blob:",
|
||||
"img-src 'self' data: blob: https://*.stripe.com",
|
||||
"font-src 'self' data:",
|
||||
"connect-src 'self' https://api.stripe.com https://challenges.cloudflare.com",
|
||||
"frame-src https://js.stripe.com https://checkout.stripe.com https://challenges.cloudflare.com",
|
||||
"connect-src 'self' https://api.stripe.com https://checkout.stripe.com https://challenges.cloudflare.com",
|
||||
"frame-src https://js.stripe.com https://*.js.stripe.com https://hooks.stripe.com https://checkout.stripe.com https://challenges.cloudflare.com",
|
||||
"form-action 'self'",
|
||||
"base-uri 'self'",
|
||||
"object-src 'none'",
|
||||
|
||||
Reference in new issue
Block a user