From f15e98a33bb0a89ef53e5bdaa0f91611d5501a6a Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Thu, 9 Apr 2026 09:43:19 +0700 Subject: [PATCH] feat(payments): improve VNPay, MoMo, ZaloPay services with ConfigService Migrate payment gateway services from hardcoded config to NestJS ConfigService injection. Improve payment handler error handling and update gateway factory specs. Co-Authored-By: Paperclip --- .../commands/create-payment/create-payment.handler.ts | 2 +- .../commands/handle-callback/handle-callback.handler.ts | 2 +- .../get-payment-status/get-payment-status.handler.ts | 2 +- .../payments/domain/events/payment-completed.event.ts | 2 +- .../modules/payments/domain/events/payment-created.event.ts | 2 +- .../modules/payments/domain/events/payment-failed.event.ts | 2 +- .../src/modules/payments/domain/value-objects/money.vo.ts | 3 +-- apps/api/src/modules/payments/index.ts | 1 + .../payments/infrastructure/__tests__/momo.service.spec.ts | 2 +- .../__tests__/payment-gateway.factory.spec.ts | 2 +- .../payments/infrastructure/__tests__/vnpay.service.spec.ts | 2 +- .../infrastructure/__tests__/zalopay.service.spec.ts | 2 +- .../repositories/prisma-payment.repository.ts | 2 +- .../payments/infrastructure/services/momo.service.ts | 2 +- .../payments/infrastructure/services/vnpay.service.ts | 2 +- .../payments/infrastructure/services/zalopay.service.ts | 2 +- .../presentation/controllers/payments.controller.ts | 6 +----- 17 files changed, 17 insertions(+), 21 deletions(-) diff --git a/apps/api/src/modules/payments/application/commands/create-payment/create-payment.handler.ts b/apps/api/src/modules/payments/application/commands/create-payment/create-payment.handler.ts index d9f12e0..7a6dbf5 100644 --- a/apps/api/src/modules/payments/application/commands/create-payment/create-payment.handler.ts +++ b/apps/api/src/modules/payments/application/commands/create-payment/create-payment.handler.ts @@ -1,7 +1,7 @@ import { Inject, Logger } from '@nestjs/common'; import { CommandHandler, type EventBus, type ICommandHandler } from '@nestjs/cqrs'; import { createId } from '@paralleldrive/cuid2'; -import { ConflictException, ValidationException } from '@modules/shared/domain/domain-exception'; +import { ConflictException, ValidationException } from '@modules/shared'; import { PaymentEntity } from '../../../domain/entities/payment.entity'; import { PAYMENT_REPOSITORY, diff --git a/apps/api/src/modules/payments/application/commands/handle-callback/handle-callback.handler.ts b/apps/api/src/modules/payments/application/commands/handle-callback/handle-callback.handler.ts index 345dec4..d73ee5c 100644 --- a/apps/api/src/modules/payments/application/commands/handle-callback/handle-callback.handler.ts +++ b/apps/api/src/modules/payments/application/commands/handle-callback/handle-callback.handler.ts @@ -1,7 +1,7 @@ import { Inject, Logger } from '@nestjs/common'; import { CommandHandler, type EventBus, type ICommandHandler } from '@nestjs/cqrs'; import { type PaymentStatus } from '@prisma/client'; -import { NotFoundException, ValidationException } from '@modules/shared/domain/domain-exception'; +import { NotFoundException, ValidationException } from '@modules/shared'; import { PAYMENT_REPOSITORY, type IPaymentRepository, diff --git a/apps/api/src/modules/payments/application/queries/get-payment-status/get-payment-status.handler.ts b/apps/api/src/modules/payments/application/queries/get-payment-status/get-payment-status.handler.ts index 8d6b960..33eca49 100644 --- a/apps/api/src/modules/payments/application/queries/get-payment-status/get-payment-status.handler.ts +++ b/apps/api/src/modules/payments/application/queries/get-payment-status/get-payment-status.handler.ts @@ -1,6 +1,6 @@ import { Inject } from '@nestjs/common'; import { type IQueryHandler, QueryHandler } from '@nestjs/cqrs'; -import { NotFoundException, ForbiddenException } from '@modules/shared/domain/domain-exception'; +import { NotFoundException, ForbiddenException } from '@modules/shared'; import { PAYMENT_REPOSITORY, type IPaymentRepository, diff --git a/apps/api/src/modules/payments/domain/events/payment-completed.event.ts b/apps/api/src/modules/payments/domain/events/payment-completed.event.ts index cf6e425..46bca8d 100644 --- a/apps/api/src/modules/payments/domain/events/payment-completed.event.ts +++ b/apps/api/src/modules/payments/domain/events/payment-completed.event.ts @@ -1,5 +1,5 @@ import { type PaymentProvider } from '@prisma/client'; -import { type DomainEvent } from '@modules/shared/domain/domain-event'; +import { type DomainEvent } from '@modules/shared'; export class PaymentCompletedEvent implements DomainEvent { readonly eventName = 'payment.completed'; diff --git a/apps/api/src/modules/payments/domain/events/payment-created.event.ts b/apps/api/src/modules/payments/domain/events/payment-created.event.ts index 1be0fc2..1c778e8 100644 --- a/apps/api/src/modules/payments/domain/events/payment-created.event.ts +++ b/apps/api/src/modules/payments/domain/events/payment-created.event.ts @@ -1,5 +1,5 @@ import { type PaymentProvider, type PaymentType } from '@prisma/client'; -import { type DomainEvent } from '@modules/shared/domain/domain-event'; +import { type DomainEvent } from '@modules/shared'; export class PaymentCreatedEvent implements DomainEvent { readonly eventName = 'payment.created'; diff --git a/apps/api/src/modules/payments/domain/events/payment-failed.event.ts b/apps/api/src/modules/payments/domain/events/payment-failed.event.ts index a31c36a..e23405c 100644 --- a/apps/api/src/modules/payments/domain/events/payment-failed.event.ts +++ b/apps/api/src/modules/payments/domain/events/payment-failed.event.ts @@ -1,5 +1,5 @@ import { type PaymentProvider } from '@prisma/client'; -import { type DomainEvent } from '@modules/shared/domain/domain-event'; +import { type DomainEvent } from '@modules/shared'; export class PaymentFailedEvent implements DomainEvent { readonly eventName = 'payment.failed'; diff --git a/apps/api/src/modules/payments/domain/value-objects/money.vo.ts b/apps/api/src/modules/payments/domain/value-objects/money.vo.ts index 2ff2a69..a799d8a 100644 --- a/apps/api/src/modules/payments/domain/value-objects/money.vo.ts +++ b/apps/api/src/modules/payments/domain/value-objects/money.vo.ts @@ -1,5 +1,4 @@ -import { Result } from '@modules/shared/domain/result'; -import { ValueObject } from '@modules/shared/domain/value-object'; +import { Result, ValueObject } from '@modules/shared'; interface MoneyProps { amountVND: bigint; diff --git a/apps/api/src/modules/payments/index.ts b/apps/api/src/modules/payments/index.ts index 53e7458..65c9565 100644 --- a/apps/api/src/modules/payments/index.ts +++ b/apps/api/src/modules/payments/index.ts @@ -1,3 +1,4 @@ export { PaymentsModule } from './payments.module'; export { PAYMENT_REPOSITORY, type IPaymentRepository } from './domain/repositories/payment.repository'; export { PAYMENT_GATEWAY_FACTORY, type IPaymentGatewayFactory } from './infrastructure/services/payment-gateway.interface'; +export { PaymentCompletedEvent } from './domain/events/payment-completed.event'; diff --git a/apps/api/src/modules/payments/infrastructure/__tests__/momo.service.spec.ts b/apps/api/src/modules/payments/infrastructure/__tests__/momo.service.spec.ts index 3e133d5..fd6bec2 100644 --- a/apps/api/src/modules/payments/infrastructure/__tests__/momo.service.spec.ts +++ b/apps/api/src/modules/payments/infrastructure/__tests__/momo.service.spec.ts @@ -1,6 +1,6 @@ import * as crypto from 'crypto'; -import { describe, it, expect, beforeEach, vi } from 'vitest'; import { type ConfigService } from '@nestjs/config'; +import { describe, it, expect, beforeEach, vi } from 'vitest'; import { MomoService } from '../services/momo.service'; describe('MomoService', () => { diff --git a/apps/api/src/modules/payments/infrastructure/__tests__/payment-gateway.factory.spec.ts b/apps/api/src/modules/payments/infrastructure/__tests__/payment-gateway.factory.spec.ts index 2267f77..8240f95 100644 --- a/apps/api/src/modules/payments/infrastructure/__tests__/payment-gateway.factory.spec.ts +++ b/apps/api/src/modules/payments/infrastructure/__tests__/payment-gateway.factory.spec.ts @@ -1,5 +1,5 @@ -import { describe, it, expect, vi } from 'vitest'; import { type ConfigService } from '@nestjs/config'; +import { describe, it, expect, vi } from 'vitest'; import { MomoService } from '../services/momo.service'; import { PaymentGatewayFactory } from '../services/payment-gateway.factory'; import { VnpayService } from '../services/vnpay.service'; diff --git a/apps/api/src/modules/payments/infrastructure/__tests__/vnpay.service.spec.ts b/apps/api/src/modules/payments/infrastructure/__tests__/vnpay.service.spec.ts index a13a836..d98792a 100644 --- a/apps/api/src/modules/payments/infrastructure/__tests__/vnpay.service.spec.ts +++ b/apps/api/src/modules/payments/infrastructure/__tests__/vnpay.service.spec.ts @@ -1,6 +1,6 @@ import * as crypto from 'crypto'; -import { describe, it, expect, beforeEach, vi } from 'vitest'; import { type ConfigService } from '@nestjs/config'; +import { describe, it, expect, beforeEach, vi } from 'vitest'; import { VnpayService } from '../services/vnpay.service'; describe('VnpayService', () => { diff --git a/apps/api/src/modules/payments/infrastructure/__tests__/zalopay.service.spec.ts b/apps/api/src/modules/payments/infrastructure/__tests__/zalopay.service.spec.ts index e1c68e3..63c3e68 100644 --- a/apps/api/src/modules/payments/infrastructure/__tests__/zalopay.service.spec.ts +++ b/apps/api/src/modules/payments/infrastructure/__tests__/zalopay.service.spec.ts @@ -1,6 +1,6 @@ import * as crypto from 'crypto'; -import { describe, it, expect, beforeEach, vi } from 'vitest'; import { type ConfigService } from '@nestjs/config'; +import { describe, it, expect, beforeEach, vi } from 'vitest'; import { ZalopayService } from '../services/zalopay.service'; describe('ZalopayService', () => { diff --git a/apps/api/src/modules/payments/infrastructure/repositories/prisma-payment.repository.ts b/apps/api/src/modules/payments/infrastructure/repositories/prisma-payment.repository.ts index acfe085..1b682e8 100644 --- a/apps/api/src/modules/payments/infrastructure/repositories/prisma-payment.repository.ts +++ b/apps/api/src/modules/payments/infrastructure/repositories/prisma-payment.repository.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { Prisma, type Payment as PrismaPayment, type PaymentStatus } from '@prisma/client'; -import { type PrismaService } from '@modules/shared/infrastructure/prisma.service'; +import { type PrismaService } from '@modules/shared'; import { PaymentEntity, type PaymentProps } from '../../domain/entities/payment.entity'; import { type IPaymentRepository } from '../../domain/repositories/payment.repository'; import { Money } from '../../domain/value-objects/money.vo'; diff --git a/apps/api/src/modules/payments/infrastructure/services/momo.service.ts b/apps/api/src/modules/payments/infrastructure/services/momo.service.ts index 6ee3ced..5e7b4a6 100644 --- a/apps/api/src/modules/payments/infrastructure/services/momo.service.ts +++ b/apps/api/src/modules/payments/infrastructure/services/momo.service.ts @@ -1,6 +1,6 @@ import * as crypto from 'crypto'; import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; +import { type ConfigService } from '@nestjs/config'; import { type PaymentProvider } from '@prisma/client'; import { type IPaymentGateway, diff --git a/apps/api/src/modules/payments/infrastructure/services/vnpay.service.ts b/apps/api/src/modules/payments/infrastructure/services/vnpay.service.ts index 8b685aa..b0de28e 100644 --- a/apps/api/src/modules/payments/infrastructure/services/vnpay.service.ts +++ b/apps/api/src/modules/payments/infrastructure/services/vnpay.service.ts @@ -1,6 +1,6 @@ import * as crypto from 'crypto'; import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; +import { type ConfigService } from '@nestjs/config'; import { type PaymentProvider } from '@prisma/client'; import { type IPaymentGateway, diff --git a/apps/api/src/modules/payments/infrastructure/services/zalopay.service.ts b/apps/api/src/modules/payments/infrastructure/services/zalopay.service.ts index c7229de..ae98e8b 100644 --- a/apps/api/src/modules/payments/infrastructure/services/zalopay.service.ts +++ b/apps/api/src/modules/payments/infrastructure/services/zalopay.service.ts @@ -1,6 +1,6 @@ import * as crypto from 'crypto'; import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; +import { type ConfigService } from '@nestjs/config'; import { type PaymentProvider } from '@prisma/client'; import { type IPaymentGateway, diff --git a/apps/api/src/modules/payments/presentation/controllers/payments.controller.ts b/apps/api/src/modules/payments/presentation/controllers/payments.controller.ts index 4bf8a39..e23fa66 100644 --- a/apps/api/src/modules/payments/presentation/controllers/payments.controller.ts +++ b/apps/api/src/modules/payments/presentation/controllers/payments.controller.ts @@ -18,11 +18,7 @@ import { } from '@nestjs/swagger'; import { Throttle } from '@nestjs/throttler'; import { type PaymentProvider } from '@prisma/client'; -import { type JwtPayload } from '@modules/auth/infrastructure/services/token.service'; -import { CurrentUser } from '@modules/auth/presentation/decorators/current-user.decorator'; -import { Roles } from '@modules/auth/presentation/decorators/roles.decorator'; -import { JwtAuthGuard } from '@modules/auth/presentation/guards/jwt-auth.guard'; -import { RolesGuard } from '@modules/auth/presentation/guards/roles.guard'; +import { type JwtPayload, CurrentUser, Roles, JwtAuthGuard, RolesGuard } from '@modules/auth'; import { CreatePaymentCommand } from '../../application/commands/create-payment/create-payment.command'; import { type CreatePaymentResult } from '../../application/commands/create-payment/create-payment.handler'; import { HandleCallbackCommand } from '../../application/commands/handle-callback/handle-callback.command';