import { NextRequest } from "next/server"; import type Stripe from "stripe"; import { stripe } from "@/lib/billing/stripe"; import { handleStripeEvent } from "@/lib/billing/webhooks/stripe"; import { alreadyProcessed, logWebhook } from "@/lib/billing/webhook-log"; export const dynamic = "force-dynamic"; export async function POST(req: NextRequest) { const secret = process.env.STRIPE_WEBHOOK_SECRET; const signature = req.headers.get("stripe-signature"); if (!secret || !signature) return new Response("Webhook not configured", { status: 400 }); const body = await req.text(); let event: Stripe.Event; try { event = stripe().webhooks.constructEvent(body, signature, secret); } catch (err) { console.error("[stripe webhook] signature verification failed", err); return new Response("Invalid signature", { status: 400 }); } // Idempotency: skip events we've already processed (Stripe retries deliveries). if (await alreadyProcessed(event.id)) return new Response("ok (duplicate)"); try { await handleStripeEvent(event); await logWebhook("stripe", event.id, event.type, "processed"); } catch (err) { console.error("[stripe webhook] handler error", err); await logWebhook("stripe", event.id, event.type, "failed", err instanceof Error ? err.message : String(err)); return new Response("Handler error", { status: 500 }); } return new Response("ok"); }