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_SUBSCRIPTION_WEBHOOK_SECRET; if (!webhookSecret) { return NextResponse.json( { error: "Missing STRIPE_SUBSCRIPTION_WEBHOOK_SECRET." }, { 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 { const event = stripeClient.webhooks.constructEvent( rawBody, signature, webhookSecret ); switch (event.type) { case "customer.subscription.updated": { const subscription = event.data.object as any; const accountId = subscription.customer_account; const priceId = subscription.items?.data?.[0]?.price?.id; const quantity = subscription.items?.data?.[0]?.quantity; const cancelAtPeriodEnd = subscription.cancel_at_period_end; const pauseCollection = subscription.pause_collection; // TODO: Store subscription status in your DB for accountId. // Suggested fields: status, priceId, quantity, cancelAtPeriodEnd, pauseCollection. break; } case "customer.subscription.deleted": { const subscription = event.data.object as any; const accountId = subscription.customer_account; // TODO: Revoke access for accountId in your DB. break; } case "payment_method.attached": case "payment_method.detached": case "customer.updated": case "customer.tax_id.created": case "customer.tax_id.deleted": case "customer.tax_id.updated": case "billing_portal.configuration.created": case "billing_portal.configuration.updated": case "billing_portal.session.created": { // TODO: Update billing info in your DB if needed. break; } default: { break; } } return NextResponse.json({ received: true }); } catch (err: any) { return NextResponse.json( { error: err?.message || "Webhook handler failed." }, { status: 400 } ); } }