From bb6f26f240777a28cd02a87d0a3df7e026e91df9 Mon Sep 17 00:00:00 2001 From: gbuomprisco Date: Tue, 11 Jun 2024 23:35:32 +0800 Subject: [PATCH] Update and refactor billing services and types Several updates and refactorings have been made to the billing services and types. The "onInvoicePaid" method and some types related to line items have been removed. The comments and arguments for the "verifyWebhookSignature" and "handleWebhookEvent" methods in service classes have been updated for clarity. The "onEvent" method's arguments have also been adjusted in multiple places to improve consistency. --- .../billing-webhook-handler.service.ts | 19 +++++++++------ packages/billing/core/src/types/index.ts | 21 ++--------------- .../billing-event-handler.service.ts | 23 ++----------------- .../lemon-squeezy-webhook-handler.service.ts | 7 ++++-- .../stripe-webhook-handler.service.ts | 11 ++++++--- 5 files changed, 29 insertions(+), 52 deletions(-) diff --git a/packages/billing/core/src/services/billing-webhook-handler.service.ts b/packages/billing/core/src/services/billing-webhook-handler.service.ts index 2a0084a97..7a3ec3172 100644 --- a/packages/billing/core/src/services/billing-webhook-handler.service.ts +++ b/packages/billing/core/src/services/billing-webhook-handler.service.ts @@ -5,22 +5,30 @@ import { UpsertOrderParams, UpsertSubscriptionParams } from '../types'; * @description Represents an abstract class for handling billing webhook events. */ export abstract class BillingWebhookHandlerService { - // Verifies the webhook signature - should throw an error if the signature is invalid + /** + * @name verifyWebhookSignature + * @description Verify the webhook signature + * @param request + */ abstract verifyWebhookSignature(request: Request): Promise; + /** + * @name handleWebhookEvent + * @description Handle the webhook event from the billing provider + * @param event + * @param params + */ abstract handleWebhookEvent( event: unknown, params: { // this method is called when a checkout session is completed onCheckoutSessionCompleted: ( subscription: UpsertSubscriptionParams | UpsertOrderParams, - customerId: string, ) => Promise; // this method is called when a subscription is updated onSubscriptionUpdated: ( subscription: UpsertSubscriptionParams, - customerId: string, ) => Promise; // this method is called when a subscription is deleted @@ -30,15 +38,12 @@ export abstract class BillingWebhookHandlerService { // one-time payments onPaymentSucceeded: (sessionId: string) => Promise; - // this method is called when an invoice is paid. This is used for recurring payments - onInvoicePaid: (data: UpsertSubscriptionParams) => Promise; - // this method is called when a payment is failed. This is used for // one-time payments onPaymentFailed: (sessionId: string) => Promise; // generic handler for any event - onEvent?: (event: string, data: Data) => Promise; + onEvent?: (data: Data) => Promise; }, ): Promise; } diff --git a/packages/billing/core/src/types/index.ts b/packages/billing/core/src/types/index.ts index a77634d90..cb67f1a80 100644 --- a/packages/billing/core/src/types/index.ts +++ b/packages/billing/core/src/types/index.ts @@ -1,24 +1,7 @@ import { Database } from '@kit/supabase/database'; -type LineItems = Array<{ - id: string; - quantity: number; - product_id: string; - variant_id: string; - price_amount: number; -}>; - export type UpsertSubscriptionParams = - Database['public']['Functions']['upsert_subscription']['Args'] & { - line_items: LineItems & { - interval: string; - subscription_id: string; - interval_count: number; - type: 'per_seat' | 'flat' | 'metered'; - }; - }; + Database['public']['Functions']['upsert_subscription']['Args']; export type UpsertOrderParams = - Database['public']['Functions']['upsert_order']['Args'] & { - line_items: LineItems; - }; + Database['public']['Functions']['upsert_order']['Args']; \ No newline at end of file diff --git a/packages/billing/gateway/src/server/services/billing-event-handler/billing-event-handler.service.ts b/packages/billing/gateway/src/server/services/billing-event-handler/billing-event-handler.service.ts index 1de40765a..4e4a99aaa 100644 --- a/packages/billing/gateway/src/server/services/billing-event-handler/billing-event-handler.service.ts +++ b/packages/billing/gateway/src/server/services/billing-event-handler/billing-event-handler.service.ts @@ -26,8 +26,7 @@ interface CustomHandlersParams { ) => Promise; onPaymentSucceeded: (sessionId: string) => Promise; onPaymentFailed: (sessionId: string) => Promise; - onInvoicePaid: (data: UpsertSubscriptionParams) => Promise; - onEvent?: (event: string, data: unknown) => Promise; + onEvent?: (data: Data) => Promise; } /** @@ -63,7 +62,7 @@ class BillingEventHandlerService { */ async handleWebhookEvent( request: Request, - params: Partial = {}, + params: Partial = {} ) { const event = await this.strategy.verifyWebhookSignature(request); @@ -274,24 +273,6 @@ class BillingEventHandlerService { logger.info(ctx, 'Successfully updated payment status'); }, - onInvoicePaid: async (data) => { - const logger = await getLogger(); - - const ctx = { - namespace: this.namespace, - subscriptionId: data.target_subscription_id, - }; - - logger.info(ctx, 'Processing invoice paid event...'); - - // by default we don't need to do anything here - // but we allow consumers to provide custom handlers for the event - if (params.onInvoicePaid) { - await params.onInvoicePaid(data); - } - - logger.info(ctx, 'Invoice paid event processed successfully'); - }, onEvent: params.onEvent, }); } diff --git a/packages/billing/lemon-squeezy/src/services/lemon-squeezy-webhook-handler.service.ts b/packages/billing/lemon-squeezy/src/services/lemon-squeezy-webhook-handler.service.ts index 8b9aa16e8..472768109 100644 --- a/packages/billing/lemon-squeezy/src/services/lemon-squeezy-webhook-handler.service.ts +++ b/packages/billing/lemon-squeezy/src/services/lemon-squeezy-webhook-handler.service.ts @@ -97,8 +97,7 @@ export class LemonSqueezyWebhookHandlerService onSubscriptionDeleted: (subscriptionId: string) => Promise; onPaymentSucceeded: (sessionId: string) => Promise; onPaymentFailed: (sessionId: string) => Promise; - onInvoicePaid: (data: UpsertSubscriptionParams) => Promise; - onEvent?: (event: string) => Promise; + onEvent?: (event: OrderWebhook | SubscriptionWebhook) => Promise; }, ) { const eventName = event.meta.event_name; @@ -133,6 +132,10 @@ export class LemonSqueezyWebhookHandlerService } default: { + if (params.onEvent) { + return params.onEvent(event); + } + const logger = await getLogger(); logger.info( diff --git a/packages/billing/stripe/src/services/stripe-webhook-handler.service.ts b/packages/billing/stripe/src/services/stripe-webhook-handler.service.ts index c90568e97..4690b46e4 100644 --- a/packages/billing/stripe/src/services/stripe-webhook-handler.service.ts +++ b/packages/billing/stripe/src/services/stripe-webhook-handler.service.ts @@ -58,6 +58,12 @@ export class StripeWebhookHandlerService return event; } + /** + * @name handleWebhookEvent + * @description Handle the webhook event from the billing provider + * @param event + * @param params + */ async handleWebhookEvent( event: Stripe.Event, params: { @@ -70,8 +76,7 @@ export class StripeWebhookHandlerService onSubscriptionDeleted: (subscriptionId: string) => Promise; onPaymentSucceeded: (sessionId: string) => Promise; onPaymentFailed: (sessionId: string) => Promise; - onInvoicePaid: (data: UpsertSubscriptionParams) => Promise; - onEvent: (eventType: string) => Promise; + onEvent?: (event: Stripe.Event) => Promise; }, ) { switch (event.type) { @@ -109,7 +114,7 @@ export class StripeWebhookHandlerService default: { if (params.onEvent) { - return params.onEvent(event.type); + return params.onEvent(event); } const Logger = await getLogger();