diff --git a/src/modules/orders/providers/orders.service.ts b/src/modules/orders/providers/orders.service.ts index e8956c0..1df3724 100644 --- a/src/modules/orders/providers/orders.service.ts +++ b/src/modules/orders/providers/orders.service.ts @@ -37,8 +37,7 @@ export class OrdersService { private readonly logger = new Logger(OrdersService.name); private static readonly STATUS_TRANSITIONS: Record = { - [OrderStatus.NEW]: [OrderStatus.PENDING_PAYMENT, OrderStatus.CONFIRMED, OrderStatus.CANCELED], - [OrderStatus.PENDING_PAYMENT]: [OrderStatus.PAID, OrderStatus.FAILED, OrderStatus.CANCELED], + [OrderStatus.PENDING_PAYMENT]: [OrderStatus.PAID, OrderStatus.FAILED, OrderStatus.CANCELED, OrderStatus.CONFIRMED], [OrderStatus.PAID]: [OrderStatus.CONFIRMED, OrderStatus.REFUNDED], [OrderStatus.CONFIRMED]: [OrderStatus.PREPARING, OrderStatus.CANCELED], [OrderStatus.PREPARING]: [OrderStatus.READY, OrderStatus.SHIPPED, OrderStatus.CANCELED], @@ -56,7 +55,7 @@ export class OrdersService { private readonly orderRepository: OrderRepository, private readonly paymentsService: PaymentsService, private readonly inventoryService: InventoryService, - ) { } + ) {} async checkout(userId: string, restaurantId: string) { const cart = await this.cartService.findOneOrFail(userId, restaurantId); @@ -80,8 +79,7 @@ export class OrdersService { totalItems: cart.totalItems || 0, description: cart.description, tableNumber: cart.tableNumber, - status: OrderStatus.NEW, - paymentStatus: PaymentStatusEnum.Pending, + status: OrderStatus.PENDING_PAYMENT, }); em.persist(order); diff --git a/src/modules/orders/repositories/order.repository.ts b/src/modules/orders/repositories/order.repository.ts index d27fcf9..85880d0 100644 --- a/src/modules/orders/repositories/order.repository.ts +++ b/src/modules/orders/repositories/order.repository.ts @@ -35,7 +35,6 @@ export class OrderRepository extends EntityRepository { page = 1, limit = 10, status, - paymentStatus, search, startDate, endDate, @@ -57,11 +56,6 @@ export class OrderRepository extends EntityRepository { where.user = { id: userId }; } - // Filter by payment status - if (paymentStatus) { - where.paymentStatus = paymentStatus; - } - // Filter by date range if (startDate || endDate) { where.createdAt = {}; diff --git a/src/modules/payments/gateways/zarinpal.gateway.ts b/src/modules/payments/gateways/zarinpal.gateway.ts index de354c4..37beae7 100755 --- a/src/modules/payments/gateways/zarinpal.gateway.ts +++ b/src/modules/payments/gateways/zarinpal.gateway.ts @@ -52,7 +52,11 @@ export class ZarinpalGateway implements IPaymentGateway { }; try { - const res = await axios.post(this.zarinpalRequestUrl, zarinpalRequest, this.axiosConfig); + const res = await axios.post( + this.zarinpalRequestUrl, + zarinpalRequest, + this.axiosConfig, + ); const { data, errors } = res.data ?? {}; const code = data?.code; const message = data?.message; @@ -112,7 +116,11 @@ export class ZarinpalGateway implements IPaymentGateway { authority: transactionId, }; - const res = await axios.post(this.zarinpalVerifyUrl, zarinpalVerifyRequest, this.axiosConfig); + const res = await axios.post( + this.zarinpalVerifyUrl, + zarinpalVerifyRequest, + this.axiosConfig, + ); // Check if response data exists if (!res.data || !res.data.data) { @@ -128,7 +136,7 @@ export class ZarinpalGateway implements IPaymentGateway { return { success: code === 100, - referenceId: ref_id ? ref_id.toString() : undefined, + referenceId: ref_id ? ref_id.toString() : '', cardPan: card_pan, raw: res.data, }; @@ -145,5 +153,4 @@ export class ZarinpalGateway implements IPaymentGateway { getPaymentUrl(authority: string): string { return `${this.zarinpalPaymentBaseUrl}/pg/StartPay/${authority}`; } - } diff --git a/src/modules/payments/interface/gateway.ts b/src/modules/payments/interface/gateway.ts index 98e29a8..cb6c786 100644 --- a/src/modules/payments/interface/gateway.ts +++ b/src/modules/payments/interface/gateway.ts @@ -23,7 +23,7 @@ export interface IPaymentVerifyParams { export interface IPaymentVerifyData { success: boolean; - referenceId?: string; + referenceId: string; cardPan?: string; raw: Record; } diff --git a/src/modules/payments/services/payments.service.ts b/src/modules/payments/services/payments.service.ts index e9ac5a4..ddeefa8 100644 --- a/src/modules/payments/services/payments.service.ts +++ b/src/modules/payments/services/payments.service.ts @@ -18,15 +18,13 @@ export class PaymentsService { private readonly em: EntityManager, private readonly gatewayManager: GatewayManager, private readonly inventoryService: InventoryService, - ) { } + ) {} - async payOrder( - orderId: string, - ): Promise<{ paymentUrl: string | null }> { + async payOrder(orderId: string): Promise<{ paymentUrl: string | null }> { const ctx = await this.loadAndValidateOrder(orderId); // Idempotency: avoid creating/charging again for already-paid orders - if (ctx.order.paymentStatus === PaymentStatusEnum.Paid) { + if (ctx.order.status === OrderStatus.PAID) { return { paymentUrl: null }; } @@ -47,9 +45,7 @@ export class PaymentsService { } } - private async loadAndValidateOrder( - orderId: string, - ): Promise { + private async loadAndValidateOrder(orderId: string): Promise { const order = await this.em.findOne( Order, { id: orderId }, @@ -98,7 +94,7 @@ export class PaymentsService { const order = await em.findOne(Order, { id: ctx.order.id }, { populate: ['user', 'restaurant'] }); if (!order) throw new NotFoundException('Order not found'); - if (order.paymentStatus === PaymentStatusEnum.Paid) { + if (order.status === OrderStatus.PAID) { return; } @@ -126,17 +122,14 @@ export class PaymentsService { payment.status = PaymentStatusEnum.Paid; payment.paidAt = new Date(); - order.paymentStatus = PaymentStatusEnum.Paid; + order.status = OrderStatus.PAID; em.persist([wallet, payment, order]); await em.flush(); }); } - - private async handleOnlinePayment( - ctx: OrderPaymentContext, - ): Promise<{ paymentUrl: string }> { + private async handleOnlinePayment(ctx: OrderPaymentContext): Promise<{ paymentUrl: string }> { const gateway = this.gatewayManager.get(ctx.gateway!); const payment = await this.getOrCreateLatestPendingPayment(ctx.order.id, { @@ -168,11 +161,7 @@ export class PaymentsService { }; } - - async verifyPayment( - transactionId: string, - orderId: string, - ): Promise { + async verifyPayment(transactionId: string, orderId: string): Promise { return this.em.transactional(async em => { const payment = await em.findOne( Payment, @@ -207,9 +196,9 @@ export class PaymentsService { this.failPayment(payment); return payment; } - this.markPaid(payment); + this.markPaid(payment, result.referenceId); this.confirmOrder(payment.order); - + await em.flush(); return payment; }); @@ -223,17 +212,16 @@ export class PaymentsService { ); } - private markPaid(payment: Payment) { + private markPaid(payment: Payment, referenceId: string) { payment.status = PaymentStatusEnum.Paid; payment.paidAt = new Date(); - payment.referenceId = payment.referenceId; - payment.order.paymentStatus = PaymentStatusEnum.Paid; + payment.referenceId = referenceId; } private failPayment(payment: Payment) { payment.status = PaymentStatusEnum.Failed; payment.failedAt = new Date(); - payment.order.paymentStatus = PaymentStatusEnum.Failed; + payment.order.status = OrderStatus.FAILED; } private confirmOrder(order: Order) {