import { NextRequest, NextResponse } from "next/server"; import Razorpay from "razorpay"; import { createClient } from "@supabase/supabase-js"; const supabase = createClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.SUPABASE_SERVICE_ROLE_KEY! ); let resend: any = null; if (process.env.RESEND_API_KEY) { import("resend").then(({ Resend }) => { resend = new Resend(process.env.RESEND_API_KEY); }); } export async function POST(req: NextRequest) { const rawBody = await req.text(); const signature = req.headers.get("x-razorpay-signature") || ""; const webhookSecret = process.env.RAZORPAY_WEBHOOK_SECRET!; // Verify signature const isValid = Razorpay.validateWebhookSignature(rawBody, signature, webhookSecret); if (!isValid) { return NextResponse.json({ error: "Invalid signature" }, { status: 400 }); } const event = JSON.parse(rawBody); const eventType: string = event.event; switch (eventType) { case "subscription.activated": { const sub = event.payload.subscription.entity; const plan = sub.notes?.plan || "pro"; const userId = sub.notes?.user_id; if (userId) { const { data } = await supabase .from("profiles") .update({ plan, razorpay_subscription_id: sub.id, updated_at: new Date().toISOString(), }) .eq("id", userId) .select("email") .single(); // Send welcome email if (data?.email && resend) { await resend.emails.send({ from: "ClauseGuard ", to: [data.email], subject: `Welcome to ClauseGuard ${plan.charAt(0).toUpperCase() + plan.slice(1)}`, html: `

Your ${plan} subscription is active. You now have unlimited scans.

Go to dashboard

`, }); } } break; } case "subscription.charged": { // Recurring payment succeeded — nothing to update, plan already active break; } case "subscription.cancelled": case "subscription.completed": { const sub = event.payload.subscription.entity; const userId = sub.notes?.user_id; if (userId) { await supabase .from("profiles") .update({ plan: "free", razorpay_subscription_id: null, updated_at: new Date().toISOString(), }) .eq("id", userId); } break; } case "subscription.halted": { const sub = event.payload.subscription.entity; const userId = sub.notes?.user_id; if (userId) { const { data } = await supabase .from("profiles") .select("email") .eq("id", userId) .single(); if (data?.email && resend) { await resend.emails.send({ from: "ClauseGuard ", to: [data.email], subject: "Payment failed — subscription paused", html: "

Your payment failed and your subscription has been paused. Please update your payment method to continue.

", }); } } break; } case "payment.failed": { // Razorpay auto-retries for subscriptions — log for monitoring const payment = event.payload.payment.entity; console.warn("Payment failed:", payment.id, payment.error_description); break; } } return NextResponse.json({ status: "ok" }); }