From fd97a76787f0ec0db2baac92cf2681ea8016618c Mon Sep 17 00:00:00 2001 From: JUSN Date: Wed, 16 Sep 2026 13:36:07 +0200 Subject: [PATCH] Webhook abgesichert: fehlendes Secret und kaputtes JSON fuehren nicht mehr zum 500er Ohne gesetztes STRIPE_WEBHOOK_SECRET starb der Handler in hmacHex mit einer Worker-Exception (error 1101 / HTTP 500). Jetzt: sauberes 503 mit Log-Hinweis. JSON.parse ist zusaetzlich abgefangen -> 400 statt Absturz. Co-Authored-By: Claude Opus 5 --- proxy/src/index.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/proxy/src/index.ts b/proxy/src/index.ts index 9874e4c..7fe516d 100644 --- a/proxy/src/index.ts +++ b/proxy/src/index.ts @@ -535,13 +535,25 @@ async function webhookHandler(request: Request, env: Env): Promise { const t = teile['t']; const v1 = teile['v1']; if (!t || !v1) return new Response('Signatur fehlt', { status: 400 }); + // Ohne gesetztes Secret koennen wir nichts pruefen. Sauber ablehnen statt + // im hmacHex mit einem 500er (Worker-Exception) zu sterben. + if (!env.STRIPE_WEBHOOK_SECRET) { + console.log('Webhook ohne STRIPE_WEBHOOK_SECRET aufgerufen — Secret fehlt!'); + return new Response('Webhook nicht konfiguriert', { status: 503 }); + } const erwartet = await hmacHex(env.STRIPE_WEBHOOK_SECRET, `${t}.${payload}`); if (!gleich(v1, erwartet)) return new Response('Signatur ungültig', { status: 400 }); - const event = JSON.parse(payload) as { + let event: { type?: string; data?: { object?: { id?: string; metadata?: Record; customer_details?: { email?: string } } }; }; + try { + event = JSON.parse(payload); + } catch { + return new Response('Kein gültiges JSON', { status: 400 }); + } + if (event.type === 'checkout.session.completed') { const o = event.data?.object; const walletId = o?.metadata?.walletId;