refactor : payment
This commit is contained in:
@@ -140,12 +140,11 @@ class PaymentService {
|
||||
// extracted to handle payment creation
|
||||
const { payment, paymentData } = await this.handlePaymentCreation(paymentMethod, price, user, description, session);
|
||||
|
||||
|
||||
// create order and order items
|
||||
const { order, orderItems } = await this.orderService.createOrder(user, payment, cartShipmentItems, session);
|
||||
// clear cart and adjust stock
|
||||
await this.finalizeOrder(user, cartShipmentItems, session);
|
||||
|
||||
// clear cart and adjust stock
|
||||
await this.finalizeOrder(user, cartShipmentItems, session);
|
||||
|
||||
await session.commitTransaction();
|
||||
await session.endSession();
|
||||
return { paymentData, order, orderItems };
|
||||
@@ -161,12 +160,22 @@ class PaymentService {
|
||||
//##################################################################
|
||||
//##################################################################
|
||||
//verify callback of cart payment
|
||||
async verifyCartPayment(gateway: GatewayProvider, verifyCallbackData: { authority: string; status: string }) {
|
||||
const { status, authority } = verifyCallbackData;
|
||||
async verifyCartPayment(gateway: GatewayProvider, verifyCallbackData: { status: string; authority?: string; refNum?: string }) {
|
||||
const { status, authority, refNum } = verifyCallbackData;
|
||||
const session = await startSession();
|
||||
session.startTransaction();
|
||||
try {
|
||||
const paymentData = await this.cartPaymentRepo.model.findOne({ authority }).session(session);
|
||||
// For SEP gateway, refNum is used as authority in database
|
||||
const authorityToFind = gateway === GatewayProvider.SEP ? refNum : authority;
|
||||
if (!authorityToFind) throw new BadRequestError(PaymentMessage.PaymentNotFound);
|
||||
|
||||
// For SEP gateway, check if refNum has already been used as transaction_id
|
||||
if (gateway === GatewayProvider.SEP && refNum) {
|
||||
const existingPayment = await this.cartPaymentRepo.model.findOne({ transaction_id: refNum }).session(session);
|
||||
if (existingPayment) throw new BadRequestError(PaymentMessage.RefNumIsAlreadyUsed);
|
||||
}
|
||||
|
||||
const paymentData = await this.cartPaymentRepo.model.findOne({ authority: authorityToFind }).session(session);
|
||||
|
||||
if (!paymentData) throw new BadRequestError(PaymentMessage.PaymentNotFound);
|
||||
|
||||
@@ -185,10 +194,16 @@ class PaymentService {
|
||||
}
|
||||
|
||||
// Verify payment through gateway
|
||||
const data = await this.paymentGateway.verifyPayment(gateway, { authority, amount: paymentData.totalPrice });
|
||||
const verifyData =
|
||||
gateway === GatewayProvider.SEP
|
||||
? { refNum: authority, amount: paymentData.totalPrice }
|
||||
: { authority, amount: paymentData.totalPrice };
|
||||
const data = await this.paymentGateway.verifyPayment(gateway, verifyData);
|
||||
if (data.code === 100 || data.code === 101) {
|
||||
await this.handleSellerNotify(order._id, user, session);
|
||||
await this.handleSuccessfulPayment(paymentData._id.toString(), order._id, data.ref_id, session);
|
||||
// For SEP gateway, save refNum as transaction_id; for Zarinpal, save ref_id
|
||||
const transactionId = gateway === GatewayProvider.SEP ? refNum : data.ref_id;
|
||||
await this.handleSuccessfulPayment(paymentData._id.toString(), order._id, transactionId, session);
|
||||
return this.buildPaymentResponse(status, PaymentMessage.PaymentSuccessful, paymentData._id.toString(), order._id);
|
||||
}
|
||||
|
||||
@@ -279,8 +294,8 @@ class PaymentService {
|
||||
}
|
||||
//##################################################################
|
||||
//##################################################################
|
||||
private async handleSuccessfulPayment(paymentId: string, orderId: number, refId: number, session: ClientSession) {
|
||||
await this.updatePaymentStatusAndReference(paymentId, refId, PaymentStatus.Completed, session);
|
||||
private async handleSuccessfulPayment(paymentId: string, orderId: number, transactionId: string, session: ClientSession) {
|
||||
await this.updatePaymentStatusAndReference(paymentId, transactionId, PaymentStatus.Completed, session);
|
||||
|
||||
await this.orderService.updateOrderStatus(orderId, OrdersStatus.process_by_seller, session);
|
||||
|
||||
@@ -385,8 +400,8 @@ class PaymentService {
|
||||
}
|
||||
//##################################################################
|
||||
//##################################################################
|
||||
private async updatePaymentStatusAndReference(paymentId: string, refId: number | null, status: PaymentStatus, session: ClientSession) {
|
||||
return await this.cartPaymentRepo.model.findByIdAndUpdate(paymentId, { paymentStatus: status, transaction_id: refId }, { session });
|
||||
private async updatePaymentStatusAndReference(paymentId: string, transactionId: string | null, status: PaymentStatus, session: ClientSession) {
|
||||
return await this.cartPaymentRepo.model.findByIdAndUpdate(paymentId, { paymentStatus: status, transaction_id: transactionId }, { session });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user