import { type NextRequest, NextResponse } from "next/server" import Stripe from "stripe" import { updatePaymentStatus } from "@/lib/google-sheets" // Lazy initialization to avoid build-time errors let stripe: Stripe | null = null function getStripe() { if (!stripe) { stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: "2024-12-18.acacia", }) } return stripe } function getWebhookSecret() { return process.env.STRIPE_WEBHOOK_SECRET! } export async function POST(request: NextRequest) { try { const body = await request.text() const signature = request.headers.get("stripe-signature")! let event: Stripe.Event try { event = getStripe().webhooks.constructEvent(body, signature, getWebhookSecret()) } catch (err) { console.error("[Webhook] Signature verification failed:", err) return NextResponse.json({ error: "Invalid signature" }, { status: 400 }) } // Handle the event switch (event.type) { case "checkout.session.completed": { const session = event.data.object as Stripe.Checkout.Session console.log("[Webhook] Payment successful:", session.id) // Extract registration data from metadata const metadata = session.metadata || {} const customerEmail = session.customer_details?.email || "" // Update Google Sheet with payment confirmation const updated = await updatePaymentStatus({ name: metadata.name || "", email: customerEmail, stripeSessionId: session.id, paymentStatus: "Paid", paymentMethod: session.payment_method_types?.[0] || "unknown", amountPaid: session.amount_total ? `€${(session.amount_total / 100).toFixed(2)}` : "", paymentDate: new Date().toISOString(), }) if (updated) { console.log(`[Webhook] Google Sheet updated for ${metadata.name}`) } else { console.error(`[Webhook] Failed to update Google Sheet for ${metadata.name}`) } // TODO: Send confirmation email break } case "payment_intent.succeeded": { const paymentIntent = event.data.object as Stripe.PaymentIntent console.log("[Webhook] PaymentIntent successful:", paymentIntent.id) break } case "payment_intent.payment_failed": { const paymentIntent = event.data.object as Stripe.PaymentIntent console.error("[Webhook] Payment failed:", paymentIntent.id) // Optionally update sheet to mark as failed const failedMetadata = paymentIntent.metadata || {} if (failedMetadata.name) { await updatePaymentStatus({ name: failedMetadata.name, stripeSessionId: paymentIntent.id, paymentStatus: "Failed", paymentDate: new Date().toISOString(), }) } break } default: console.log("[Webhook] Unhandled event type:", event.type) } return NextResponse.json({ received: true }) } catch (err) { console.error("[Webhook] Error:", err) return NextResponse.json({ error: "Webhook error" }, { status: 500 }) } }