Merge pull request #179 from documenso/fix/improve-stripe-webhook-endpoint

fix: improve stripe webhook endpoint
This commit is contained in:
Lucas Smith
2023-06-17 11:46:37 +10:00
committed by GitHub

View File

@@ -25,9 +25,7 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
}); });
} }
log("constructing body...")
const body = await buffer(req); const body = await buffer(req);
log("constructed body")
const event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!); const event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!);
log("event-type:", event.type); log("event-type:", event.type);
@@ -70,11 +68,25 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
if (event.type === "invoice.payment_succeeded") { if (event.type === "invoice.payment_succeeded") {
const invoice = event.data.object as Stripe.Invoice; const invoice = event.data.object as Stripe.Invoice;
if (invoice.billing_reason !== "subscription_cycle") {
return res.status(200).json({
success: true,
message: "Webhook received",
});
}
const customerId = const customerId =
typeof invoice.customer === "string" ? invoice.customer : invoice.customer?.id; typeof invoice.customer === "string" ? invoice.customer : invoice.customer?.id;
const subscription = await stripe.subscriptions.retrieve(invoice.subscription as string); const subscription = await stripe.subscriptions.retrieve(invoice.subscription as string);
const hasSubscription = await prisma.subscription.findFirst({
where: {
customerId,
},
});
if (hasSubscription) {
await prisma.subscription.update({ await prisma.subscription.update({
where: { where: {
customerId, customerId,
@@ -86,6 +98,7 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
periodEnd: new Date(subscription.current_period_end * 1000), periodEnd: new Date(subscription.current_period_end * 1000),
}, },
}); });
}
return res.status(200).json({ return res.status(200).json({
success: true, success: true,
@@ -98,6 +111,13 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
const customerId = failedInvoice.customer as string; const customerId = failedInvoice.customer as string;
const hasSubscription = await prisma.subscription.findFirst({
where: {
customerId,
},
});
if (hasSubscription) {
await prisma.subscription.update({ await prisma.subscription.update({
where: { where: {
customerId, customerId,
@@ -106,6 +126,7 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
status: SubscriptionStatus.PAST_DUE, status: SubscriptionStatus.PAST_DUE,
}, },
}); });
}
return res.status(200).json({ return res.status(200).json({
success: true, success: true,
@@ -118,6 +139,13 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
const customerId = updatedSubscription.customer as string; const customerId = updatedSubscription.customer as string;
const hasSubscription = await prisma.subscription.findFirst({
where: {
customerId,
},
});
if (hasSubscription) {
await prisma.subscription.update({ await prisma.subscription.update({
where: { where: {
customerId, customerId,
@@ -129,6 +157,7 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
periodEnd: new Date(updatedSubscription.current_period_end * 1000), periodEnd: new Date(updatedSubscription.current_period_end * 1000),
}, },
}); });
}
return res.status(200).json({ return res.status(200).json({
success: true, success: true,
@@ -141,6 +170,13 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
const customerId = deletedSubscription.customer as string; const customerId = deletedSubscription.customer as string;
const hasSubscription = await prisma.subscription.findFirst({
where: {
customerId,
},
});
if (hasSubscription) {
await prisma.subscription.update({ await prisma.subscription.update({
where: { where: {
customerId, customerId,
@@ -149,6 +185,7 @@ export const webhookHandler = async (req: NextApiRequest, res: NextApiResponse)
status: SubscriptionStatus.INACTIVE, status: SubscriptionStatus.INACTIVE,
}, },
}); });
}
return res.status(200).json({ return res.status(200).json({
success: true, success: true,