diff --git a/packages/server/src/main.ts b/packages/server/src/main.ts index 8990a2020..41d5863a5 100644 --- a/packages/server/src/main.ts +++ b/packages/server/src/main.ts @@ -15,7 +15,7 @@ global.__views_dirname = path.join(global.__static_dirname, '/views'); global.__images_dirname = path.join(global.__static_dirname, '/images'); async function bootstrap() { - const app = await NestFactory.create(AppModule); + const app = await NestFactory.create(AppModule, { rawBody: true }); app.setGlobalPrefix('/api'); // create and mount the middleware manually here diff --git a/packages/server/src/modules/SaleInvoices/queries/GetSaleInvoice.service.ts b/packages/server/src/modules/SaleInvoices/queries/GetSaleInvoice.service.ts index d621f2191..4bfcfaa94 100644 --- a/packages/server/src/modules/SaleInvoices/queries/GetSaleInvoice.service.ts +++ b/packages/server/src/modules/SaleInvoices/queries/GetSaleInvoice.service.ts @@ -1,5 +1,6 @@ import { EventEmitter2 } from '@nestjs/event-emitter'; import { Inject, Injectable } from '@nestjs/common'; +import { Knex } from 'knex'; import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service'; import { SaleInvoice } from '../models/SaleInvoice'; import { SaleInvoiceTransformer } from './SaleInvoice.transformer'; @@ -17,7 +18,7 @@ export class GetSaleInvoice { @Inject(SaleInvoice.name) private saleInvoiceModel: TenantModelProxy, - ) {} + ) { } /** * Retrieve sale invoice with associated entries. @@ -27,9 +28,10 @@ export class GetSaleInvoice { */ public async getSaleInvoice( saleInvoiceId: number, + trx?: Knex.Transaction, ): Promise { const saleInvoice = await this.saleInvoiceModel() - .query() + .query(trx) .findById(saleInvoiceId) .withGraphFetched('entries.item') .withGraphFetched('entries.tax') diff --git a/packages/server/src/modules/StripePayment/CreatePaymentReceivedStripePayment.ts b/packages/server/src/modules/StripePayment/CreatePaymentReceivedStripePayment.ts index 9c18d059c..ccab8c45a 100644 --- a/packages/server/src/modules/StripePayment/CreatePaymentReceivedStripePayment.ts +++ b/packages/server/src/modules/StripePayment/CreatePaymentReceivedStripePayment.ts @@ -12,7 +12,7 @@ export class CreatePaymentReceiveStripePayment { private readonly createPaymentReceivedService: CreatePaymentReceivedService, private readonly uow: UnitOfWork, private readonly accountRepository: AccountRepository, - ) {} + ) { } /** * Creates a payment received transaction associated to the given invoice. @@ -28,7 +28,7 @@ export class CreatePaymentReceiveStripePayment { // Retrieves the given invoice to create payment transaction associated to it. const invoice = - await this.getSaleInvoiceService.getSaleInvoice(saleInvoiceId); + await this.getSaleInvoiceService.getSaleInvoice(saleInvoiceId, trx); const paymentReceivedDTO = { customerId: invoice.customerId, @@ -38,6 +38,7 @@ export class CreatePaymentReceiveStripePayment { referenceNo: '', statement: '', depositAccountId: stripeClearingAccount.id, + branchId: invoice.branchId, entries: [{ invoiceId: saleInvoiceId, paymentAmount: paidAmount }], }; // Create a payment received transaction associated to the given invoice. diff --git a/packages/server/src/modules/StripePayment/StripePaymentWebhooks.controller.ts b/packages/server/src/modules/StripePayment/StripePaymentWebhooks.controller.ts index c8d5bb6fd..a8bbde9a5 100644 --- a/packages/server/src/modules/StripePayment/StripePaymentWebhooks.controller.ts +++ b/packages/server/src/modules/StripePayment/StripePaymentWebhooks.controller.ts @@ -5,8 +5,8 @@ import { HttpException, HttpStatus, Post, + RawBodyRequest, Req, - Res, } from '@nestjs/common'; import { Request, Response } from 'express'; import { ApiOperation, ApiTags } from '@nestjs/swagger'; @@ -42,13 +42,10 @@ export class StripePaymentWebhooksController { @HttpCode(200) @ApiOperation({ summary: 'Listen to Stripe webhooks' }) async handleWebhook( - @Req() req: Request, - @Res() res: Response, + @Req() req: RawBodyRequest, @Headers('stripe-signature') signature: string, ) { - console.log(signature, 'signature'); try { - // @ts-ignore - rawBody is set by middleware const rawBody = req.rawBody || req.body; const webhooksSecret = this.configService.get( 'stripePayment.webhooksSecret', @@ -82,7 +79,6 @@ export class StripePaymentWebhooksController { HttpStatus.BAD_REQUEST, ); } - console.log(event.type, 'event.type'); // Handle the event based on its type switch (event.type) { case 'checkout.session.completed': @@ -94,7 +90,6 @@ export class StripePaymentWebhooksController { } as StripeCheckoutSessionCompletedEventPayload, ); break; - case 'account.updated': // Triggers `onStripeAccountUpdated` event. await this.eventEmitter.emitAsync( @@ -109,8 +104,7 @@ export class StripePaymentWebhooksController { default: console.log(`Unhandled event type ${event.type}`); } - - return res.status(200).json({ received: true }); + return { received: true }; } catch (error) { if (error instanceof HttpException) { throw error; diff --git a/packages/server/src/modules/StripePayment/subscribers/StripeWebhooksSubscriber.ts b/packages/server/src/modules/StripePayment/subscribers/StripeWebhooksSubscriber.ts index 1250c7d61..012c7359b 100644 --- a/packages/server/src/modules/StripePayment/subscribers/StripeWebhooksSubscriber.ts +++ b/packages/server/src/modules/StripePayment/subscribers/StripeWebhooksSubscriber.ts @@ -1,21 +1,25 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { OnEvent } from '@nestjs/event-emitter'; +import { ClsService } from 'nestjs-cls'; import { CreatePaymentReceiveStripePayment } from '../CreatePaymentReceivedStripePayment'; import { StripeCheckoutSessionCompletedEventPayload, StripeWebhookEventPayload, } from '../StripePayment.types'; -// import { initalizeTenantServices } from '@/api/middleware/TenantDependencyInjection'; -// import { initializeTenantSettings } from '@/api/middleware/SettingsMiddleware'; -import { OnEvent } from '@nestjs/event-emitter'; -import { Inject, Injectable } from '@nestjs/common'; import { events } from '@/common/events/events'; import { PaymentIntegration } from '../models/PaymentIntegration.model'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; import { TenantModel } from '@/modules/System/models/TenantModel'; +import { SystemUser } from '@/modules/System/models/SystemUser'; @Injectable() export class StripeWebhooksSubscriber { constructor( private readonly createPaymentReceiveStripePayment: CreatePaymentReceiveStripePayment, + private readonly clsService: ClsService, + + @Inject(SystemUser.name) + private readonly systemUserModel: typeof SystemUser, @Inject(PaymentIntegration.name) private readonly paymentIntegrationModel: TenantModelProxy< @@ -23,8 +27,8 @@ export class StripeWebhooksSubscriber { >, @Inject(TenantModel.name) - private readonly tenantModel: typeof TenantModel - ) {} + private readonly tenantModel: typeof TenantModel, + ) { } /** * Handles the checkout session completed webhook event. @@ -38,10 +42,22 @@ export class StripeWebhooksSubscriber { const tenantId = parseInt(metadata.tenantId, 10); const saleInvoiceId = parseInt(metadata.saleInvoiceId, 10); + const tenant = await this.tenantModel + .query() + .findOne({ id: tenantId }) + .throwIfNotFound(); + const user = await this.systemUserModel + .query() + .findOne({ + tenantId: tenant.id, + }) + .modify('active') + .throwIfNotFound(); - // await initalizeTenantServices(tenantId); - // await initializeTenantSettings(tenantId); + this.clsService.set('organizationId', tenant.organizationId); + this.clsService.set('userId', user.id); + this.clsService.set('tenantId', tenant.id); // Get the amount from the event const amount = event.data.object.amount_total;