fix: Stop throwing 202 for stripe handler (#20397)
* dont throw - log error * invoice paid * update to warn * Update packages/features/ee/billing/api/webhook/_invoice.paid.ts --------- Co-authored-by: Keith Williams <keithwillcode@gmail.com>
This commit is contained in:
co-authored by
Keith Williams
parent
2aa583bb6d
commit
da47168941
@@ -53,7 +53,7 @@ describe("stripeWebhookHandler", () => {
|
||||
await expect(handler(req)).rejects.toThrow(new HttpCode(500, "Missing STRIPE_WEBHOOK_SECRET"));
|
||||
});
|
||||
|
||||
it("should throw an error if event type is unhandled", async () => {
|
||||
it("should return success false if event type is unhandled", async () => {
|
||||
const { req, res } = createMocks<CustomNextApiRequest, CustomNextApiResponse>({
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -65,9 +65,11 @@ describe("stripeWebhookHandler", () => {
|
||||
(stripe.webhooks.constructEvent as any).mockReturnValueOnce({ type: "unhandled_event" });
|
||||
|
||||
const handler = stripeWebhookHandler({});
|
||||
await expect(handler(req)).rejects.toThrow(
|
||||
new HttpCode(202, "Unhandled Stripe Webhook event type unhandled_event")
|
||||
);
|
||||
const response = await handler(req);
|
||||
expect(response).toEqual({
|
||||
success: false,
|
||||
message: "Unhandled Stripe Webhook event type unhandled_event",
|
||||
});
|
||||
});
|
||||
|
||||
it("should call the appropriate handler for a valid event", async () => {
|
||||
|
||||
@@ -54,10 +54,22 @@ export const stripeWebhookHandler = (handlers: SWHandlers) => async (req: NextAp
|
||||
STRIPE_WEBHOOK_SECRET
|
||||
) as Stripe.DiscriminatedEvent;
|
||||
const handlerGetter = handlers[event.type];
|
||||
if (!handlerGetter) throw new HttpCode(202, `Unhandled Stripe Webhook event type ${event.type}`);
|
||||
if (!handlerGetter) {
|
||||
console.log("Unhandled Stripe Webhook event type", event.type);
|
||||
return {
|
||||
success: false,
|
||||
message: `Unhandled Stripe Webhook event type ${event.type}`,
|
||||
};
|
||||
}
|
||||
const handler = (await handlerGetter())?.default;
|
||||
// auto catch unsupported Stripe events.
|
||||
if (!handler) throw new HttpCode(202, `Unhandled Stripe Webhook event type ${event.type}`);
|
||||
if (!handler) {
|
||||
console.log("Unhandled Stripe Webhook event type", event.type);
|
||||
return {
|
||||
success: false,
|
||||
message: `Unhandled Stripe Webhook event type ${event.type}`,
|
||||
};
|
||||
}
|
||||
// @ts-expect-error - we know the handler is defined and accepts the data type
|
||||
return await handler(event.data);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { HttpCode } from "./__handler";
|
||||
import type { LazyModule, SWHMap } from "./__handler";
|
||||
|
||||
type Data = SWHMap["customer.subscription.deleted"]["data"];
|
||||
@@ -28,10 +27,22 @@ const stripeWebhookProductHandler = (handlers: Handlers) => async (data: Data) =
|
||||
throw new Error(`Unable to determine Product ID from subscription: ${subscription.id}`);
|
||||
}
|
||||
const handlerGetter = handlers[productId as any];
|
||||
if (!handlerGetter) throw new HttpCode(202, `No product handler found for product: ${productId}`);
|
||||
if (!handlerGetter) {
|
||||
console.log("No product handler found for product", productId);
|
||||
return {
|
||||
success: false,
|
||||
message: `No product handler found for product: ${productId}`,
|
||||
};
|
||||
}
|
||||
const handler = (await handlerGetter())?.default;
|
||||
// auto catch unsupported Stripe products.
|
||||
if (!handler) throw new HttpCode(202, `No product handler found for product: ${productId}`);
|
||||
if (!handler) {
|
||||
console.log("No product handler found for product", productId);
|
||||
return {
|
||||
success: false,
|
||||
message: `No product handler found for product: ${productId}`,
|
||||
};
|
||||
}
|
||||
return await handler(data);
|
||||
};
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ const stripeWebhookProductHandler = (handlers: Handlers) => async (data: Data) =
|
||||
// Only handle subscription invoices
|
||||
if (!invoice.subscription) {
|
||||
log.warn("Not a subscription invoice, skipping");
|
||||
return { success: true };
|
||||
return { success: false, message: "Not a subscription invoice, skipping" };
|
||||
}
|
||||
|
||||
// Get the product ID from the first subscription item
|
||||
@@ -24,8 +24,8 @@ const stripeWebhookProductHandler = (handlers: Handlers) => async (data: Data) =
|
||||
const productId = firstItem?.price?.product as string; // prod_xxxxx
|
||||
|
||||
if (!productId) {
|
||||
log.error("No product ID found in invoice, skipping");
|
||||
return { success: true };
|
||||
log.warn("No product ID found in invoice, skipping");
|
||||
return { success: false, message: "No product ID found in invoice, skipping" };
|
||||
}
|
||||
|
||||
const handlerGetter = handlers[productId as keyof typeof handlers];
|
||||
@@ -34,14 +34,14 @@ const stripeWebhookProductHandler = (handlers: Handlers) => async (data: Data) =
|
||||
* If no handler is found, we skip the product. A handler could be null if we don't need webhooks to handle the business logic for the product.
|
||||
*/
|
||||
if (!handlerGetter) {
|
||||
log.error(`Skipping product: ${productId} because no handler found`);
|
||||
return { success: true };
|
||||
log.warn(`Skipping product: ${productId} because no handler found`);
|
||||
return { success: false, message: `Skipping product: ${productId} because no handler found` };
|
||||
}
|
||||
const handler = (await handlerGetter())?.default;
|
||||
// auto catch unsupported Stripe products.
|
||||
if (!handler) {
|
||||
log.error(`Skipping product: ${productId} because no handler found`);
|
||||
return { success: true };
|
||||
log.warn(`Skipping product: ${productId} because no handler found`);
|
||||
return { success: false, message: `Skipping product: ${productId} because no handler found` };
|
||||
}
|
||||
return await handler(data);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user