import { NextResponse } from "next/server"; import { stripeClient } from "../../../../../lib/stripeClient"; export const runtime = "nodejs"; export async function POST(req: Request) { const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; if (!webhookSecret) { return NextResponse.json( { error: "Missing STRIPE_WEBHOOK_SECRET for V2 thin events." }, { status: 500 } ); } const signature = req.headers.get("stripe-signature"); if (!signature) { return NextResponse.json({ error: "Missing Stripe signature." }, { status: 400 }); } const rawBody = Buffer.from(await req.arrayBuffer()); try { let event: any = null; const clientAny = stripeClient as any; if (typeof clientAny.parseThinEvent === "function") { const thinEvent = clientAny.parseThinEvent(rawBody, signature, webhookSecret); // Fetch the full event from Stripe for complete data. event = await stripeClient.v2.core.events.retrieve(thinEvent.id); } else { // Fallback: attempt snapshot parsing if thin parsing isn't available. event = stripeClient.webhooks.constructEvent( rawBody, signature, webhookSecret ); } switch (event.type) { case "v2.core.account[requirements].updated": { // TODO: Pull updated requirements and notify the account owner if needed. break; } case "v2.core.account[configuration.merchant].capability_status_updated": case "v2.core.account[configuration.customer].capability_status_updated": case "v2.core.account[.recipient].capability_status_updated": { // TODO: Update capability status in your database. break; } case "setup_intent.created": { console.log( `[webhook] type=${event.type} id=${event.id} object_id=${event?.data?.object?.id || "n/a"} livemode=${event?.livemode}` ); break; } default: { // Unhandled event type break; } } return NextResponse.json({ received: true }); } catch (err: any) { return NextResponse.json( { error: err?.message || "Webhook handler failed." }, { status: 400 } ); } }