Files
dlearn-api/src/application/payment/payment.service.ts
T
2025-01-06 00:55:45 +03:30

154 lines
5.3 KiB
TypeScript

import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common";
import { PaymentDataAccess } from "../../dataAccess/payment.dataAccess";
import mongoose, { Mongoose, startSession } from "mongoose";
import { PaymentGateway } from "../IPG/PaymentGateway";
import { UserDataAccess } from "../../dataAccess/user.dataAccess";
import { PurchaseDataAccess } from "../../dataAccess/purchase.dataAccess";
import { CourseDataAccess } from "../../dataAccess/course.dataAccess";
import { PaymentStatus } from "../../common/eNums/paymentStatus.enum";
@Injectable()
export class PaymentService {
private readonly logger = new Logger(PaymentService.name);
constructor(
private readonly paymentDataAccess: PaymentDataAccess,
private readonly paymentGateway: PaymentGateway,
private readonly userDataAccess: UserDataAccess,
private readonly purchaseDataAccess: PurchaseDataAccess,
private readonly courseDataAccess: CourseDataAccess
) { }
async createPayment(userId: string, courseId: string) {
const session = await startSession();
session.startTransaction();
try {
const user = await this.userDataAccess.findOne(userId);
const course = await this.courseDataAccess.getOneCourse(courseId);
if (!course) {
throw new HttpException(
{
status: HttpStatus.BAD_REQUEST,
error: 'دوره مورد نظر یافت نشد',
},
HttpStatus.BAD_REQUEST,
);
}
const courseExists = user.courseIds.find(id => id.equals(courseId));
if (courseExists) {
throw new HttpException(
{
status: HttpStatus.BAD_REQUEST,
error: 'شما قبلا این دوره را خریداری کرده اید',
},
HttpStatus.BAD_REQUEST,
);
}
if (course.price === 0) {
// Handle free course registration
const transactionNumber = `FREE-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
const payment = await this.paymentDataAccess.createPayment(
userId,
0,
courseId,
transactionNumber,
'FREE',
session
);
await session.commitTransaction();
await this.purchaseDataAccess.createPurchase(payment.userId.toString(), payment.courseId.toString(), payment._id.toString());
payment.paymentStatus = PaymentStatus.Completed;
await this.paymentDataAccess.updatePaymentStatus(payment._id.toString(), PaymentStatus.Completed);
const registerCourse = await this.userDataAccess.registerCourse(payment.userId, payment.courseId);
if (!registerCourse.success) {
if (!payment) {
throw new HttpException(
{
status: HttpStatus.BAD_REQUEST,
error: 'درخواست خرید دوره با مشکل مواجه شد',
},
HttpStatus.BAD_REQUEST,
);
}
}
await session.commitTransaction();
await session.endSession();
return { success: true, payment: payment }
}
const paymentData = await this.paymentGateway.requestPayment({ amount: course.price, userId, callbackPath: "cart" });
if (!paymentData) {
throw new HttpException(
{
status: HttpStatus.BAD_REQUEST,
error: 'درخواست خرید دوره با مشکل مواجه شد',
},
HttpStatus.BAD_REQUEST,
);
}
const transactionNumber = `DLR-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
const payment = await this.paymentDataAccess.createPayment(
userId,
course.price, //amount
courseId,
transactionNumber,
paymentData.authority,
session
);
await session.commitTransaction();
await session.endSession();
return { payment: payment, paymentData }
} catch (error) {
await session.abortTransaction();
await session.endSession();
this.logger.warn(error);
return error;
}
}
async verifyPayment(authority: string, status: string) {
const paymentData = await this.paymentDataAccess.getPaymentByAuthority(authority);
if (!paymentData) {
throw new Error("payment not found");
}
const verifyData = await this.paymentGateway.verifyPayment({ authority, amount: paymentData.amount });
console.log({verifyData})
if (verifyData.code === 100 || verifyData.code === 101) {
await this.purchaseDataAccess.createPurchase(paymentData.userId.toString(), paymentData.courseId.toString(), paymentData._id.toString());
paymentData.paymentStatus = PaymentStatus.Completed;
await paymentData.save();
const registerCourse = await this.userDataAccess.registerCourse(paymentData.userId, paymentData.courseId);
if (!registerCourse.success) {
if (!paymentData) {
throw new HttpException(
{
status: HttpStatus.BAD_REQUEST,
error: 'درخواست خرید دوره با مشکل مواجه شد',
},
HttpStatus.BAD_REQUEST,
);
}
}
return { success: true, payment: paymentData, verifyData }
}
}
async getPayments() {
return this.paymentDataAccess.getPayments();
}
async getPaymentsByUser(userId: string) {
return this.paymentDataAccess.getPaymentsByUserId(userId);
}
}