diff --git a/packages/features/ee/billing/api/webhook/__handler.test.ts b/packages/features/ee/billing/api/webhook/__handler.test.ts index c2b151f2a6..848b5978e7 100644 --- a/packages/features/ee/billing/api/webhook/__handler.test.ts +++ b/packages/features/ee/billing/api/webhook/__handler.test.ts @@ -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({ 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 () => { diff --git a/packages/features/ee/billing/api/webhook/__handler.ts b/packages/features/ee/billing/api/webhook/__handler.ts index f67be10ea1..266389c4b8 100644 --- a/packages/features/ee/billing/api/webhook/__handler.ts +++ b/packages/features/ee/billing/api/webhook/__handler.ts @@ -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); }; diff --git a/packages/features/ee/billing/api/webhook/_customer.subscription.deleted.ts b/packages/features/ee/billing/api/webhook/_customer.subscription.deleted.ts index 0e3c5bdd2b..ec04137915 100644 --- a/packages/features/ee/billing/api/webhook/_customer.subscription.deleted.ts +++ b/packages/features/ee/billing/api/webhook/_customer.subscription.deleted.ts @@ -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); }; diff --git a/packages/features/ee/billing/api/webhook/_invoice.paid.ts b/packages/features/ee/billing/api/webhook/_invoice.paid.ts index 6d524fb296..d3a7b44ec4 100644 --- a/packages/features/ee/billing/api/webhook/_invoice.paid.ts +++ b/packages/features/ee/billing/api/webhook/_invoice.paid.ts @@ -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); };