Files
sign/apps/marketing/src/pages/api/claim-plan/index.ts

99 lines
2.5 KiB
TypeScript
Raw Normal View History

2023-06-09 18:21:18 +10:00
import { NextApiRequest, NextApiResponse } from 'next';
import { randomUUID } from 'crypto';
2023-10-25 22:29:51 +11:00
import { TEarlyAdopterCheckoutMetadataSchema } from '@documenso/ee/server-only/stripe/webhook/early-adopter-checkout-metadata';
2023-06-09 18:21:18 +10:00
import { redis } from '@documenso/lib/server-only/redis';
import { stripe } from '@documenso/lib/server-only/stripe';
import { prisma } from '@documenso/prisma';
import { TClaimPlanResponseSchema, ZClaimPlanRequestSchema } from '~/api/claim-plan/types';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<TClaimPlanResponseSchema>,
) {
try {
const { method } = req;
if (method?.toUpperCase() !== 'POST') {
return res.status(405).json({
error: 'Method not allowed',
});
}
const safeBody = ZClaimPlanRequestSchema.safeParse(req.body);
if (!safeBody.success) {
return res.status(400).json({
error: 'Bad request',
});
}
const { email, name, planId, signatureDataUrl, signatureText } = safeBody.data;
const user = await prisma.user.findFirst({
where: {
email: email.toLowerCase(),
},
});
2023-10-25 22:29:51 +11:00
if (user) {
2023-06-09 18:21:18 +10:00
return res.status(200).json({
2023-10-26 16:40:25 +11:00
redirectUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL}/signin`,
2023-06-09 18:21:18 +10:00
});
}
2023-10-25 22:29:51 +11:00
const clientReferenceId = randomUUID();
2023-06-09 18:21:18 +10:00
if (signatureDataUrl) {
2023-10-25 22:29:51 +11:00
await redis.set(`signature:${clientReferenceId}`, signatureDataUrl, {
2023-06-09 18:21:18 +10:00
// expire in 7 days
ex: 60 * 60 * 24 * 7,
});
}
2023-10-25 22:29:51 +11:00
const metadata: TEarlyAdopterCheckoutMetadataSchema = {
2023-06-09 18:21:18 +10:00
name,
email,
signatureText: signatureText || name,
2023-10-25 22:29:51 +11:00
source: 'marketing',
2023-06-09 18:21:18 +10:00
};
if (signatureDataUrl) {
2023-10-25 22:29:51 +11:00
metadata.signatureDataUrl = clientReferenceId;
2023-06-09 18:21:18 +10:00
}
const checkout = await stripe.checkout.sessions.create({
customer_email: email,
2023-10-25 22:29:51 +11:00
// Using the UUID here means our webhook will not try to use it as a user ID.
client_reference_id: clientReferenceId,
2023-06-09 18:21:18 +10:00
line_items: [
{
price: planId,
quantity: 1,
},
],
mode: 'subscription',
metadata,
allow_promotion_codes: true,
2023-09-14 15:00:14 +10:00
success_url: `${process.env.NEXT_PUBLIC_MARKETING_URL}/claimed?sessionId={CHECKOUT_SESSION_ID}`,
2023-10-25 22:29:51 +11:00
cancel_url: `${process.env.NEXT_PUBLIC_MARKETING_URL}`,
2023-06-09 18:21:18 +10:00
});
if (!checkout.url) {
throw new Error('Checkout URL not found');
}
return res.json({
redirectUrl: checkout.url,
});
} catch (error) {
console.error(error);
return res.status(500).json({
error: 'Internal server error',
});
}
}