diff --git a/src/modules/payment/controllers/payment.controller.ts b/src/modules/payment/controllers/payment.controller.ts index a3b816e..f246c27 100644 --- a/src/modules/payment/controllers/payment.controller.ts +++ b/src/modules/payment/controllers/payment.controller.ts @@ -4,7 +4,9 @@ import { UseGuards, Query, Delete, + Res, } from '@nestjs/common'; +import type { Response } from 'express'; import { PaymentService } from '../services/payments.service'; import { ApiTags, @@ -38,8 +40,18 @@ export class PaymentController { @Get('public/payments/online/:token/verify') @ApiOperation({ summary: 'Verify online payment' }) - verifyOnlinePayment(@Param('token') token: string) { - return this.paymentService.verifyOnlinePayment(token); + async verifyOnlinePayment( + @Param('token') token: string, + @Res() res: Response, + ) { + try { + const payment = await this.paymentService.verifyOnlinePayment(token); + const redirectUrl = this.paymentService.getRedirectUrlAfterVerify(payment); + return res.redirect(302, redirectUrl); + } catch { + const redirectUrl = this.paymentService.getRedirectUrlAfterVerifyToFailed(); + return res.redirect(302, redirectUrl); + } } diff --git a/src/modules/payment/services/payments.service.ts b/src/modules/payment/services/payments.service.ts index 36fce9e..b9ee7b9 100644 --- a/src/modules/payment/services/payments.service.ts +++ b/src/modules/payment/services/payments.service.ts @@ -19,12 +19,17 @@ import { Admin } from 'src/modules/admin/entities/admin.entity'; import { AdminRepository } from 'src/modules/admin/repositories/admin.repository'; import { CreditTransaction } from 'src/modules/user/entities/credit-transaction.entity'; import { InvoiceService } from 'src/modules/invoice/invoice.service'; +import { ConfigService } from '@nestjs/config'; @Injectable() export class PaymentService { private readonly logger = new Logger(PaymentService.name); + private readonly frontUrl: string; + + private readonly paymentSuccessPath = 'invoice/payment/success'; + private readonly paymentFailedPath = 'invoice/payment/failed'; constructor( private readonly em: EntityManager, @@ -35,7 +40,10 @@ export class PaymentService { private readonly creditRepository: CreditRepository, private readonly adminRepository: AdminRepository, private readonly invoiceService: InvoiceService, - ) { } + private readonly configService: ConfigService, + ) { + this.frontUrl = this.configService.getOrThrow('FRONT_URL') || 'https://negareh-console.dev.danakcorp.com/' + } async payInvoice(invoiceId: string, dto: PayOrderDto, adminId?: string): Promise<{ paymentUrl: string | null }> { @@ -231,6 +239,27 @@ export class PaymentService { return payment; } + /** + * Returns the frontend URL to redirect the user after online payment verification. + * Success: /payment/success?invoiceId=... + * Failed: /payment/failed?invoiceId=... + */ + getRedirectUrlAfterVerify(payment: Payment): string { + const base = this.frontUrl.replace(/\/$/, ''); + const invoiceId = payment.invoice?.id ?? ''; + const path = + payment.status === PaymentStatusEnum.Paid + ? this.paymentSuccessPath + : this.paymentFailedPath; + return `${base}${path}?invoiceId=${encodeURIComponent(invoiceId)}`; + } + + /** Redirect URL when verification fails without a payment (e.g. invalid token). */ + getRedirectUrlAfterVerifyToFailed(): string { + const base = this.frontUrl.replace(/\/$/, ''); + return `${base}${this.paymentFailedPath}`; + } + findAll(dto: FindPaymentsDto) { return this.paymentRepository.findAllPaginated(dto) }