88 lines
2.3 KiB
TypeScript
88 lines
2.3 KiB
TypeScript
import type { NextApiRequest, NextApiResponse } from "next";
|
|
import z from "zod";
|
|
|
|
import { findPaymentCredentials } from "@calcom/app-store/paypal/api/webhook";
|
|
import Paypal from "@calcom/app-store/paypal/lib/Paypal";
|
|
import { IS_PRODUCTION } from "@calcom/lib/constants";
|
|
import prisma from "@calcom/prisma";
|
|
|
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
try {
|
|
// Look if it's get
|
|
if (req.method !== "GET") {
|
|
throw new Error("Invalid method");
|
|
}
|
|
|
|
// Look if bookingUid it's provided in query params using zod
|
|
const parseRequest = captureRequestSchema.safeParse(req.query);
|
|
if (!parseRequest.success) {
|
|
throw new Error("Request is malformed");
|
|
}
|
|
|
|
// Get bookingUid and token from query params
|
|
const { bookingUid, token } = parseRequest.data;
|
|
|
|
// Get booking credentials
|
|
const booking = await prisma.booking.findUnique({
|
|
where: {
|
|
uid: bookingUid,
|
|
},
|
|
select: {
|
|
id: true,
|
|
userId: true,
|
|
},
|
|
});
|
|
|
|
if (!booking) {
|
|
throw new Error("Booking not found");
|
|
}
|
|
|
|
const credentials = await findPaymentCredentials(booking?.id);
|
|
|
|
if (!credentials) {
|
|
throw new Error("Credentials not found");
|
|
}
|
|
|
|
// Get paypal instance
|
|
const paypalClient = new Paypal(credentials);
|
|
|
|
// capture payment
|
|
const capture = await paypalClient.captureOrder(token);
|
|
|
|
if (!capture) {
|
|
res.redirect(`/booking/${bookingUid}?paypalPaymentStatus=failed`);
|
|
}
|
|
if (IS_PRODUCTION) {
|
|
res.redirect(`/booking/${bookingUid}?paypalPaymentStatus=success`);
|
|
} else {
|
|
// For cal.dev, paypal sandbox doesn't send webhooks
|
|
const updateBooking = prisma.booking.update({
|
|
where: {
|
|
uid: bookingUid,
|
|
},
|
|
data: {
|
|
paid: true,
|
|
},
|
|
});
|
|
const updatePayment = prisma.payment.update({
|
|
where: {
|
|
id: booking?.id,
|
|
},
|
|
data: {
|
|
success: true,
|
|
},
|
|
});
|
|
await Promise.all([updateBooking, updatePayment]);
|
|
res.redirect(`/booking/${bookingUid}?paypalPaymentStatus=success`);
|
|
}
|
|
return;
|
|
} catch (_err) {
|
|
res.redirect(`/booking/${req.query.bookingUid}?paypalPaymentStatus=failed`);
|
|
}
|
|
}
|
|
|
|
const captureRequestSchema = z.object({
|
|
bookingUid: z.string(),
|
|
token: z.string(),
|
|
});
|