2022-07-06 19:31:07 +00:00
|
|
|
import type { NextApiRequest, NextApiResponse } from "next";
|
|
|
|
import Stripe from "stripe";
|
|
|
|
|
2022-12-07 19:55:47 +00:00
|
|
|
import { getPremiumMonthlyPlanPriceId } from "@calcom/app-store/stripepayment/lib/utils";
|
2022-07-28 19:58:26 +00:00
|
|
|
import { checkPremiumUsername } from "@calcom/features/ee/common/lib/checkPremiumUsername";
|
2022-12-21 20:31:09 +00:00
|
|
|
import { WEBAPP_URL } from "@calcom/lib/constants";
|
2022-07-06 19:31:07 +00:00
|
|
|
import prisma from "@calcom/prisma";
|
|
|
|
import { Prisma } from "@calcom/prisma/client";
|
2022-07-28 19:58:26 +00:00
|
|
|
|
|
|
|
import { getStripeCustomerIdFromUserId } from "../lib/customer";
|
|
|
|
import stripe from "../lib/server";
|
2022-07-06 19:31:07 +00:00
|
|
|
|
|
|
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
|
|
if (req.method === "GET") {
|
|
|
|
const userId = req.session?.user.id;
|
2022-09-08 00:38:37 +00:00
|
|
|
let { intentUsername = null } = req.query;
|
2022-12-07 19:55:47 +00:00
|
|
|
const { callbackUrl } = req.query;
|
2022-07-06 19:31:07 +00:00
|
|
|
if (!userId || !intentUsername) {
|
|
|
|
res.status(404).end();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (intentUsername && typeof intentUsername === "object") {
|
|
|
|
intentUsername = intentUsername[0];
|
|
|
|
}
|
|
|
|
const customerId = await getStripeCustomerIdFromUserId(userId);
|
|
|
|
if (!customerId) {
|
|
|
|
res.status(404).json({ message: "Missing customer id" });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const userData = await prisma.user.findFirst({
|
|
|
|
where: { id: userId },
|
2022-12-08 23:20:24 +00:00
|
|
|
select: { id: true, metadata: true },
|
2022-07-06 19:31:07 +00:00
|
|
|
});
|
|
|
|
if (!userData) {
|
|
|
|
res.status(404).json({ message: "Missing user data" });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-12-21 20:31:09 +00:00
|
|
|
const return_url = `${WEBAPP_URL}/api/integrations/stripepayment/paymentCallback?checkoutSessionId={CHECKOUT_SESSION_ID}&callbackUrl=${callbackUrl}`;
|
2022-12-07 19:55:47 +00:00
|
|
|
const createSessionParams: Stripe.Checkout.SessionCreateParams = {
|
|
|
|
mode: "subscription",
|
|
|
|
payment_method_types: ["card"],
|
|
|
|
line_items: [
|
|
|
|
{
|
|
|
|
quantity: 1,
|
|
|
|
price: getPremiumMonthlyPlanPriceId(),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
allow_promotion_codes: true,
|
2022-07-06 19:31:07 +00:00
|
|
|
customer: customerId,
|
2022-12-07 19:55:47 +00:00
|
|
|
success_url: return_url,
|
|
|
|
cancel_url: return_url,
|
2022-07-06 19:31:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const checkPremiumResult = await checkPremiumUsername(intentUsername);
|
|
|
|
if (!checkPremiumResult.available) {
|
|
|
|
return res.status(404).json({ message: "Intent username not available" });
|
|
|
|
}
|
2022-09-08 00:38:37 +00:00
|
|
|
const stripeCustomer = await stripe.customers.retrieve(customerId);
|
|
|
|
if (!stripeCustomer || stripeCustomer.deleted) {
|
|
|
|
return res.status(400).json({ message: "Stripe customer not found or deleted" });
|
|
|
|
}
|
|
|
|
await stripe.customers.update(customerId, {
|
|
|
|
metadata: {
|
|
|
|
...stripeCustomer.metadata,
|
|
|
|
username: intentUsername,
|
|
|
|
},
|
|
|
|
});
|
2022-07-06 19:31:07 +00:00
|
|
|
|
2022-12-07 19:55:47 +00:00
|
|
|
if (userData) {
|
2022-09-08 00:38:37 +00:00
|
|
|
await prisma.user.update({
|
|
|
|
where: { id: userId },
|
|
|
|
data: {
|
|
|
|
metadata: {
|
2022-12-07 19:55:47 +00:00
|
|
|
...((userData.metadata as Prisma.JsonObject) || {}),
|
|
|
|
isPremium: false,
|
2022-09-08 00:38:37 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
2022-07-06 19:31:07 +00:00
|
|
|
}
|
2022-12-07 19:55:47 +00:00
|
|
|
const checkoutSession = await stripe.checkout.sessions.create(createSessionParams);
|
|
|
|
if (checkoutSession && checkoutSession.url) {
|
|
|
|
return res.redirect(checkoutSession.url).end();
|
2022-07-06 19:31:07 +00:00
|
|
|
}
|
2022-12-07 19:55:47 +00:00
|
|
|
return res.status(404).json({ message: "Couldn't redirect to stripe checkout session" });
|
2022-07-06 19:31:07 +00:00
|
|
|
}
|
|
|
|
}
|