From 4284ecfca451380d17b4919493e4b0f4f3658b1f Mon Sep 17 00:00:00 2001 From: jos3duardo Date: Sun, 3 Aug 2025 20:58:50 -0400 Subject: [PATCH] Add payment module with DTOs, entity, controller, and service --- .../payments/dto/create-payment.dto.ts | 9 +++++ .../payments/dto/update-payment.dto.ts | 4 ++ .../payments/entities/payment.entity.ts | 24 ++++++++++++ src/modules/payments/payments.controller.ts | 13 +++++++ src/modules/payments/payments.module.ts | 20 ++++++++++ src/modules/payments/payments.service.ts | 39 +++++++++++++++++++ 6 files changed, 109 insertions(+) create mode 100644 src/modules/payments/dto/create-payment.dto.ts create mode 100644 src/modules/payments/dto/update-payment.dto.ts create mode 100644 src/modules/payments/entities/payment.entity.ts create mode 100644 src/modules/payments/payments.controller.ts create mode 100644 src/modules/payments/payments.module.ts create mode 100644 src/modules/payments/payments.service.ts diff --git a/src/modules/payments/dto/create-payment.dto.ts b/src/modules/payments/dto/create-payment.dto.ts new file mode 100644 index 0000000..a29c6be --- /dev/null +++ b/src/modules/payments/dto/create-payment.dto.ts @@ -0,0 +1,9 @@ +import {IsNumber, IsUUID} from "class-validator"; + +export class CreatePaymentDto { + @IsNumber() + amount: number; + + @IsUUID() + correlationId: string; +} diff --git a/src/modules/payments/dto/update-payment.dto.ts b/src/modules/payments/dto/update-payment.dto.ts new file mode 100644 index 0000000..0293332 --- /dev/null +++ b/src/modules/payments/dto/update-payment.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreatePaymentDto } from './create-payment.dto'; + +export class UpdatePaymentDto extends PartialType(CreatePaymentDto) {} diff --git a/src/modules/payments/entities/payment.entity.ts b/src/modules/payments/entities/payment.entity.ts new file mode 100644 index 0000000..0f698f3 --- /dev/null +++ b/src/modules/payments/entities/payment.entity.ts @@ -0,0 +1,24 @@ +import { + Column, + CreateDateColumn, + Entity, + PrimaryGeneratedColumn, +} from 'typeorm'; + +@Entity('payments') +export class Payment { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ type: 'decimal', precision: 10, scale: 2 }) + amount: number; + + @Column({ type: 'varchar', name: 'payment_processor' }) + paymentProcessor: string; + + @Column({ type: 'uuid', name: 'correlation_id', unique: true }) + correlationId: string; + + @CreateDateColumn({ type: 'timestamp', name: 'created_at' }) + createdAt: Date; +} diff --git a/src/modules/payments/payments.controller.ts b/src/modules/payments/payments.controller.ts new file mode 100644 index 0000000..9986172 --- /dev/null +++ b/src/modules/payments/payments.controller.ts @@ -0,0 +1,13 @@ +import { Body, Controller, Post } from '@nestjs/common'; +import { PaymentsService } from './payments.service'; +import { CreatePaymentDto } from './dto/create-payment.dto'; + +@Controller('payments') +export class PaymentsController { + constructor(private readonly paymentsService: PaymentsService) {} + + @Post() + async payment(@Body() createPaymentDto: CreatePaymentDto) { + return this.paymentsService.store(createPaymentDto); + } +} diff --git a/src/modules/payments/payments.module.ts b/src/modules/payments/payments.module.ts new file mode 100644 index 0000000..becdbe2 --- /dev/null +++ b/src/modules/payments/payments.module.ts @@ -0,0 +1,20 @@ +import { Module } from '@nestjs/common'; +import { PaymentsService } from './payments.service'; +import { PaymentsController } from './payments.controller'; +import { HttpModule } from '@nestjs/axios'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Payment } from './entities/payment.entity'; +import { BullModule } from '@nestjs/bullmq'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([Payment]), + BullModule.registerQueue({ + name: 'payments', + }), + HttpModule, + ], + controllers: [PaymentsController], + providers: [PaymentsService], +}) +export class PaymentsModule {} diff --git a/src/modules/payments/payments.service.ts b/src/modules/payments/payments.service.ts new file mode 100644 index 0000000..e0e7b80 --- /dev/null +++ b/src/modules/payments/payments.service.ts @@ -0,0 +1,39 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { CreatePaymentDto } from './dto/create-payment.dto'; +import { HttpService } from '@nestjs/axios'; +import { catchError, firstValueFrom } from 'rxjs'; +import { AxiosError } from 'axios'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Payment } from './entities/payment.entity'; +import { Repository } from 'typeorm'; +import { Queue } from 'bullmq'; +import { InjectQueue } from '@nestjs/bullmq'; + +@Injectable() +export class PaymentsService { + private readonly logger = new Logger(PaymentsService.name); + + constructor( + @InjectQueue('payments') private readonly paymentsQueue: Queue, + private readonly httpService: HttpService, + @InjectRepository(Payment) private readonly repository: Repository, + ) {} + + async store(createPaymentDto: CreatePaymentDto) { + const urlPaymentDefault = 'http://192.168.1.126:8002/payments'; + const { data } = await firstValueFrom( + this.httpService.post(urlPaymentDefault, createPaymentDto).pipe( + catchError((error: AxiosError) => { + this.logger.error(error?.response); + throw 'An error happened!'; + }), + ), + ); + await this.repository.save({ + ...createPaymentDto, + paymentProcessor: 'default', + }); + this.logger.log(data); + return data; + } +}