a tool for shared writing and social publishing
1import { NextRequest, NextResponse } from "next/server";
2import { getStripe } from "stripe/client";
3import { inngest } from "app/api/inngest/client";
4
5export async function POST(req: NextRequest) {
6 const body = await req.text();
7 const signature = req.headers.get("stripe-signature");
8 if (!signature) {
9 return NextResponse.json({ error: "Missing signature" }, { status: 400 });
10 }
11
12 let event;
13 try {
14 event = getStripe().webhooks.constructEvent(
15 body,
16 signature,
17 process.env.STRIPE_WEBHOOK_SECRET as string,
18 );
19 } catch (err) {
20 console.error("Stripe webhook signature verification failed:", err);
21 return NextResponse.json({ error: "Invalid signature" }, { status: 400 });
22 }
23
24 switch (event.type) {
25 case "checkout.session.completed":
26 await inngest.send({
27 name: "stripe/checkout.session.completed",
28 data: { sessionId: event.data.object.id },
29 });
30 break;
31
32 case "customer.subscription.created":
33 case "customer.subscription.updated":
34 await inngest.send({
35 name: "stripe/customer.subscription.updated",
36 data: { subscriptionId: event.data.object.id },
37 });
38 break;
39
40 case "customer.subscription.deleted":
41 await inngest.send({
42 name: "stripe/customer.subscription.deleted",
43 data: { subscriptionId: event.data.object.id },
44 });
45 break;
46
47 case "invoice.payment_failed": {
48 const invoice = event.data.object;
49 const sub = invoice.parent?.subscription_details?.subscription;
50 const subId =
51 typeof sub === "string"
52 ? sub
53 : typeof sub === "object" && sub
54 ? sub.id
55 : "";
56 await inngest.send({
57 name: "stripe/invoice.payment.failed",
58 data: {
59 invoiceId: invoice.id,
60 subscriptionId: subId,
61 customerId: invoice.customer as string,
62 },
63 });
64 break;
65 }
66 }
67
68 return NextResponse.json({ received: true });
69}