Openstatus www.openstatus.dev
at main 61 lines 1.9 kB view raw
1import { TRPCError } from "@trpc/server"; 2import { getHTTPStatusCodeFromError } from "@trpc/server/http"; 3import type { NextRequest } from "next/server"; 4 5import { createTRPCContext } from "@openstatus/api"; 6import { lambdaRouter, stripe } from "@openstatus/api/src/lambda"; 7 8import { env } from "@/env"; 9 10export async function POST(req: NextRequest) { 11 const payload = await req.text(); 12 const signature = req.headers.get("Stripe-Signature"); 13 if (!signature) return new Response("No signature", { status: 400 }); 14 15 try { 16 const event = stripe.webhooks.constructEvent( 17 payload, 18 signature, 19 env.STRIPE_WEBHOOK_SECRET_KEY, 20 ); 21 22 /** 23 * Forward to tRPC API to handle the webhook event 24 */ 25 const ctx = await createTRPCContext({ req }); 26 const caller = lambdaRouter.createCaller(ctx); 27 28 switch (event.type) { 29 case "checkout.session.completed": 30 await caller.stripeRouter.webhooks.sessionCompleted({ event }); 31 break; 32 case "customer.subscription.updated": 33 console.log(event); 34 await caller.stripeRouter.webhooks.customerSubscriptionUpdated({ 35 event, 36 }); 37 break; 38 case "customer.subscription.deleted": 39 await caller.stripeRouter.webhooks.customerSubscriptionDeleted({ 40 event, 41 }); 42 break; 43 44 default: 45 throw new Error(`Unhandled event type ${event.type}`); 46 } 47 } catch (error) { 48 if (error instanceof TRPCError) { 49 const errorCode = getHTTPStatusCodeFromError(error); 50 console.error("Error in tRPC webhook handler", error); 51 return new Response(error.message, { status: errorCode }); 52 } 53 54 const message = error instanceof Error ? error.message : "Unknown error"; 55 return new Response(`Webhook Error: ${message}`, { 56 status: 400, 57 }); 58 } 59 60 return new Response(null, { status: 200 }); 61}