Files
comfyui-deploy/web/src/app/(app)/api/stripe/callback/route.tsx
T

176 lines
5.6 KiB
TypeScript

import { auth, clerkClient } from "@clerk/nextjs";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
import { stripe } from "../../../../../server/stripe";
import { NextResponse } from "next/server";
import { db } from "@/db/db";
import { subscriptionStatusTable } from "@/db/schema";
import { eq } from "drizzle-orm";
const secret = process.env.STRIPE_WEBHOOK_SECRET || "";
export async function POST(req: Request) {
try {
const body = await req.text();
const signature = headers().get("stripe-signature");
if (!signature)
return new NextResponse("Signature not found.", {
status: 500,
});
const event = stripe.webhooks.constructEvent(body, signature, secret);
console.log(event);
if (event.type === "checkout.session.completed") {
if (!event.data.object.customer_details?.email) {
throw new Error(`missing user email, ${event.id}`);
}
const userId = event.data.object.metadata?.userId;
const plan = event.data.object.metadata?.plan;
if (!userId) {
throw new Error(`missing itinerary_id on metadata, ${event.id}`);
}
if (!plan) {
throw new Error(`missing plan on metadata, ${event.id}`);
}
const orgId = event.data.object.metadata?.orgId;
const customerId =
typeof event.data.object.customer == "string"
? event.data.object.customer
: event.data.object.customer?.id;
const subscriptionId =
typeof event.data.object.subscription == "string"
? event.data.object.subscription
: event.data.object.subscription?.id;
if (!customerId) {
throw new Error(`missing customerId, ${event.id}`);
}
if (!subscriptionId) {
throw new Error(`missing subscriptionId, ${event.id}`);
}
const items = await stripe.subscriptionItems.list({
subscription: subscriptionId,
limit: 5,
});
// getting the subscription item id for the api plan
const subscription_item_api_id = items.data.find(
(x) => x.price.id === process.env.STRIPE_PR_API,
)?.id;
// the plan could be either pro or enterprise
const subscription_item_plan_id =
items.data.find((x) => x.price.id === process.env.STRIPE_PR_PRO)?.id ??
items.data.find((x) => x.price.id === process.env.STRIPE_PR_ENTERPRISE)
?.id;
if (!subscription_item_api_id) {
throw new Error(
`missing plan on subscription_item_api_id, ${event.id}`,
);
}
if (!subscription_item_plan_id) {
throw new Error(
`missing plan on subscription_item_plan_id, ${event.id}`,
);
}
console.log(items);
await db
.insert(subscriptionStatusTable)
.values({
stripe_customer_id: customerId,
org_id: orgId && orgId.length > 0 && orgId != "null" ? orgId : null,
user_id: userId,
subscription_id: subscriptionId,
plan: plan as "pro" | "enterprise" | "basic",
status: "active",
subscription_item_api_id: subscription_item_api_id,
subscription_item_plan_id: subscription_item_plan_id,
})
.onConflictDoNothing();
// updateDatabase(event.data.object.metadata.itinerary_id);
// sendEmail(event.data.object.customer_details.email);
} else if (event.type === "customer.subscription.paused") {
const customerId =
typeof event.data.object.customer == "string"
? event.data.object.customer
: event.data.object.customer?.id;
if (!customerId) {
throw new Error(`missing customerId, ${event.id}`);
}
await db
.update(subscriptionStatusTable)
.set({ status: "paused" })
.where(eq(subscriptionStatusTable.stripe_customer_id, customerId));
} else if (event.type === "customer.subscription.resumed") {
const customerId =
typeof event.data.object.customer == "string"
? event.data.object.customer
: event.data.object.customer?.id;
if (!customerId) {
throw new Error(`missing customerId, ${event.id}`);
}
await db
.update(subscriptionStatusTable)
.set({ status: "active" })
.where(eq(subscriptionStatusTable.stripe_customer_id, customerId));
} else if (event.type === "customer.subscription.deleted") {
const customerId =
typeof event.data.object.customer == "string"
? event.data.object.customer
: event.data.object.customer?.id;
if (!customerId) {
throw new Error(`missing customerId, ${event.id}`);
}
await db
.update(subscriptionStatusTable)
.set({ status: "deleted" })
.where(eq(subscriptionStatusTable.stripe_customer_id, customerId));
} else if (event.type === "customer.subscription.updated") {
const customerId =
typeof event.data.object.customer == "string"
? event.data.object.customer
: event.data.object.customer?.id;
if (!customerId) {
throw new Error(`missing customerId, ${event.id}`);
}
const cancel_at_period_end = event.data.object.cancel_at_period_end;
await db
.update(subscriptionStatusTable)
.set({ cancel_at_period_end: cancel_at_period_end })
.where(eq(subscriptionStatusTable.stripe_customer_id, customerId));
}
return NextResponse.json({ result: event, ok: true });
} catch (error) {
console.error(error);
return NextResponse.json(
{
message: `Something went wrong: ${error}`,
ok: false,
},
{ status: 500 },
);
}
}