From 8ab96b829238ec2493896301199920be6d991ccd Mon Sep 17 00:00:00 2001 From: jos3duardo Date: Sun, 17 Aug 2025 04:30:30 -0400 Subject: [PATCH] Handle duplicate payment and log processor errors --- .../services/process-payment.service.ts | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/modules/payments/services/process-payment.service.ts b/src/modules/payments/services/process-payment.service.ts index 857259b..353a3f3 100644 --- a/src/modules/payments/services/process-payment.service.ts +++ b/src/modules/payments/services/process-payment.service.ts @@ -2,18 +2,54 @@ import { Injectable, Logger } from '@nestjs/common'; import { PaymentDefaultProcessor } from '../processor/payment-default.processor'; import { PaymentFallbackProcessor } from '../processor/payment-fallback.processor'; import { CreatePaymentDto } from '../dto/create-payment.dto'; +import { Payment } from '../entities/payment.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { ProcessorTypeEnum } from '../enumns/processor-type.enum'; @Injectable() export class ProcessPaymentService { private readonly logger = new Logger(ProcessPaymentService.name); constructor( + @InjectRepository(Payment) private readonly repository: Repository, + private paymentDefaultProcessor: PaymentDefaultProcessor, private paymentFallbackProcessor: PaymentFallbackProcessor, ) {} async execute(job: CreatePaymentDto): Promise { - const result = await this.paymentDefaultProcessor.execute(job); - if (!result) await this.paymentFallbackProcessor.execute(job); + let result = false; + try { + result = await this.paymentDefaultProcessor.execute(job); + } catch (error) { + if (error.response?.status === 422) { + await this.repository.query( + ` + INSERT INTO payments (correlation_id, amount, payment_processor) + VALUES ($1, $2, $3) + ON CONFLICT (correlation_id) DO NOTHING + `, + [job.correlationId, job.amount, ProcessorTypeEnum.DEFAULT], + ); + this.logger.warn( + `Pagamento já realizado para correlationId: ${job.correlationId}`, + ); + return; // Não lança exceção, job é considerado processado + } + this.logger.warn(`Default processor failed: ${error.message}`); + } + if (!result) { + await this.paymentFallbackProcessor.execute(job); + await this.repository.query( + ` + INSERT INTO payments (correlation_id, amount, payment_processor) + VALUES ($1, $2, $3) + ON CONFLICT (correlation_id) DO NOTHING + `, + [job.correlationId, job.amount, ProcessorTypeEnum.FALLBACK], + ); + } + throw new Error('Payment processing failed'); } }