chore: redirect user after payment gateway

This commit is contained in:
mahyargdz
2025-02-24 15:20:01 +03:30
parent 3b0120d338
commit d563c254e2
5 changed files with 44 additions and 35 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
FROM node:22-alpine AS base
RUN npm install -g corepack@latest
RUN corepack enable && corepack prepare pnpm@latest --activate
RUN corepack enable && corepack prepare pnpm@9 --activate
# Install tzdata to support timezone settings
RUN apk add --no-cache tzdata
+4 -3
View File
@@ -1,5 +1,6 @@
import { Body, Controller, Get, Param, Patch, Post, Query } from "@nestjs/common";
import { Body, Controller, Get, Param, Patch, Post, Query, Res } from "@nestjs/common";
import { ApiOperation, ApiTags } from "@nestjs/swagger";
import { FastifyReply } from "fastify";
import { CreateBankAccountDto } from "./DTO/create-bankaccount.dto";
import { GatewayDepositDto, TransferDepositDto } from "./DTO/deposit-wallet.dto";
@@ -87,8 +88,8 @@ export class PaymentsController {
}
@Get("verify/:gateway")
verifyPayment(@Param() paramDto: VerifyParamDto, @Query() queryDto: VerifyQueryDto) {
return this.paymentsService.verifyPayment(paramDto.gateway, queryDto);
verifyPayment(@Param() paramDto: VerifyParamDto, @Query() queryDto: VerifyQueryDto, @Res({ passthrough: true }) rep: FastifyReply) {
return this.paymentsService.verifyPayment(paramDto.gateway, queryDto, rep);
}
///------------------- bank account -----------------------------
@@ -1,8 +1,10 @@
import { InjectQueue } from "@nestjs/bullmq";
import { BadRequestException, HttpException, Injectable, InternalServerErrorException } from "@nestjs/common";
import { BadRequestException, HttpException, HttpStatus, Injectable, InternalServerErrorException } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { Queue } from "bullmq";
// eslint-disable-next-line import/no-named-as-default
import Decimal from "decimal.js";
import { FastifyReply } from "fastify";
import { DataSource, Not, QueryRunner } from "typeorm";
import { PaginationDto } from "../../../common/DTO/pagination.dto";
@@ -36,6 +38,7 @@ import { GatewayType } from "../types/gateway.type";
export class PaymentsService {
constructor(
@InjectQueue(PAYMENT.PAYMENT_QUEUE_NAME) private readonly paymentQueue: Queue,
private readonly configService: ConfigService,
private readonly gatewayFactory: PaymentGatewayFactory,
private readonly paymentGatewaysRepository: PaymentGatewaysRepository,
private readonly paymentsRepository: PaymentsRepository,
@@ -125,7 +128,10 @@ export class PaymentsService {
//*********************************** */
//*********************************** */
async verifyPayment(gateway: GatewayType, queryDto: VerifyQueryDto) {
async verifyPayment(gateway: GatewayType, queryDto: VerifyQueryDto, rep: FastifyReply) {
const frontUrl = new URL(this.configService.getOrThrow<string>("SITE_URL"));
frontUrl.pathname = "/transactions";
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
@@ -135,7 +141,6 @@ export class PaymentsService {
const payment = await queryRunner.manager.findOne(Payment, {
where: { reference: queryDto.Authority },
relations: ["user"],
// lock: { mode: "pessimistic_write" },
});
if (!payment) throw new BadRequestException(PaymentMessage.PAYMENT_NOT_FOUND_WITH_REF);
@@ -144,37 +149,40 @@ export class PaymentsService {
if (queryDto.Status !== "OK") {
await this.handleFailedPayment(payment.id, queryRunner);
await queryRunner.commitTransaction();
return { message: "nok" };
frontUrl.searchParams.append("status", PaymentStatus.FAILED);
frontUrl.searchParams.append("id", payment.id);
frontUrl.searchParams.append("date", payment.createdAt.toISOString());
frontUrl.searchParams.append("amount", payment.amount.toString());
return rep.status(HttpStatus.FOUND).redirect(frontUrl.toString());
}
const verifyData = await paymentGateway.verifyPayment({ reference: queryDto.Authority, amount: payment.amount });
//
if (verifyData.code === 100) {
const transaction = await this.handleSuccessfulPayment(
payment.id,
payment.user.id,
payment.amount,
`${verifyData.ref_id}`,
queryRunner,
);
await this.handleSuccessfulPayment(payment.id, payment.user.id, payment.amount, `${verifyData.ref_id}`, queryRunner);
await queryRunner.commitTransaction();
return {
message: "success",
transaction,
};
}
if (verifyData.code === 101) {
frontUrl.searchParams.append("status", PaymentStatus.COMPLETED);
frontUrl.searchParams.append("id", payment.id);
frontUrl.searchParams.append("date", payment.createdAt.toISOString());
frontUrl.searchParams.append("amount", payment.amount.toString());
} else if (verifyData.code === 101) {
await queryRunner.commitTransaction();
return {
message: "not valid payment",
};
}
frontUrl.searchParams.append("status", PaymentStatus.PENDING);
frontUrl.searchParams.append("id", payment.id);
frontUrl.searchParams.append("date", payment.createdAt.toISOString());
frontUrl.searchParams.append("amount", payment.amount.toString());
} else {
await this.handleFailedPayment(payment.id, queryRunner);
await queryRunner.commitTransaction();
frontUrl.searchParams.append("status", PaymentStatus.FAILED);
frontUrl.searchParams.append("id", payment.id);
frontUrl.searchParams.append("date", payment.createdAt.toISOString());
frontUrl.searchParams.append("amount", payment.amount.toString());
}
return { message: "nok" };
console.log(frontUrl.toString());
return rep.status(HttpStatus.FOUND).redirect(frontUrl.toString());
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
+3 -2
View File
@@ -1,6 +1,6 @@
import { createHmac } from "node:crypto";
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
import { BadRequestException, HttpStatus, Injectable, Logger } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { FastifyReply } from "fastify";
import slugify from "slugify";
@@ -159,6 +159,7 @@ export class UsersService {
/************************************************************ */
//TODO:fix this later
async verifyEmail(queryDto: EmailVerifyQueryDto, rep: FastifyReply) {
const frontUrl = this.configService.getOrThrow<string>("FRONT_URL");
const { token, userId, ts } = queryDto;
const user = await this.userRepository.findOneBy({ id: userId });
@@ -181,7 +182,7 @@ export class UsersService {
await this.userRepository.save(user);
// return { message: UserMessage.EMAIL_VERIFIED };
return rep.redirect("https://google.com");
return rep.status(HttpStatus.FOUND).redirect(frontUrl);
}
/************************************************************ */
-1
View File
@@ -68,7 +68,6 @@ export class UsersController {
/************************************************************ */
@ApiOperation({ summary: "Verify email" })
@HttpCode(HttpStatus.PERMANENT_REDIRECT)
@Get("verify-email")
verifyEmail(@Query() queryDto: EmailVerifyQueryDto, @Res({ passthrough: true }) rep: FastifyReply) {
return this.usersService.verifyEmail(queryDto, rep);