From c7f5fdf2416dd2f1e43b4e1ca269a0ecf268249b Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Mon, 19 Jan 2026 12:19:44 +0330 Subject: [PATCH] pay as admin --- .../payment/controllers/payment.controller.ts | 18 ++++++++++--- .../payment/entities/payment.entity.ts | 4 +++ src/modules/payment/interface/payment.ts | 4 ++- .../payment/services/payments.service.ts | 27 +++++++++++++------ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/modules/payment/controllers/payment.controller.ts b/src/modules/payment/controllers/payment.controller.ts index 319f1d8..2ee8ff4 100644 --- a/src/modules/payment/controllers/payment.controller.ts +++ b/src/modules/payment/controllers/payment.controller.ts @@ -15,6 +15,8 @@ import { UserId } from 'src/common/decorators'; import { AuthGuard } from 'src/modules/auth/guards/auth.guard'; import { PayOrderDto } from '../dto/pay-order.dto'; import { FindPaymentsDto } from '../dto/find-payments.dto'; +import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; +import { AdminId } from 'src/common/decorators/admin-id.decorator'; @ApiTags('payment') @Controller() @@ -49,13 +51,21 @@ export class PaymentController { /*=============== Admin =============== */ + @Post('admin/payments/pay-order/:orderId') + @UseGuards(AdminAuthGuard) @ApiBearerAuth() - @Get('public/payments') - @ApiOperation({ summary: 'get all payments as user' }) - findAll(@Query() dto: FindPaymentsDto) { - return this.paymentsService.findAll(dto); + @ApiOperation({ summary: 'Pay for an order as Admin' }) + payOrderAsAdmin(@Param('orderId') orderId: string, @AdminId() adminId: string, @Body() dto: PayOrderDto) { + return this.paymentsService.payOrder(orderId, dto, adminId); } + @Post('public/payments/:token/verify/online') + @UseGuards(AdminAuthGuard) + @ApiBearerAuth() + @ApiOperation({ summary: 'Verify online payment as admin' }) + verifyOnlinePaymentAsAdmin(@Param('paymentId') token: string) { + return this.paymentsService.verifyOnlinePayment(token); + } @Post('admin/payments/:paymentId/verify/cash') @UseGuards(AuthGuard) diff --git a/src/modules/payment/entities/payment.entity.ts b/src/modules/payment/entities/payment.entity.ts index c8f1c7e..69511d7 100644 --- a/src/modules/payment/entities/payment.entity.ts +++ b/src/modules/payment/entities/payment.entity.ts @@ -3,6 +3,7 @@ import { BaseEntity } from '../../../common/entities/base.entity'; import { Order } from '../../order/entities/order.entity'; import { PaymentGatewayEnum, PaymentMethodEnum, PaymentStatusEnum } from '../interface/payment'; import { ulid } from 'ulid'; +import { Admin } from 'src/modules/admin/entities/admin.entity'; @Entity({ tableName: 'payments' }) export class Payment extends BaseEntity { @@ -13,6 +14,9 @@ export class Payment extends BaseEntity { @Index() order!: Order; + @ManyToOne(() => Admin, { nullable: true }) + creator?: Admin + @Property({ type: 'decimal', precision: 10, scale: 0 }) amount!: number; diff --git a/src/modules/payment/interface/payment.ts b/src/modules/payment/interface/payment.ts index d58ef06..d9b59ea 100644 --- a/src/modules/payment/interface/payment.ts +++ b/src/modules/payment/interface/payment.ts @@ -1,3 +1,4 @@ +import { Admin } from 'src/modules/admin/entities/admin.entity'; import type { Order } from 'src/modules/order/entities/order.entity'; import { User } from 'src/modules/user/entities/user.entity'; @@ -25,7 +26,8 @@ export interface ICreatePayment { } export interface OrderPaymentContext { - user:User; + admin: Admin|null + user: User; order: Order; amount: number; method: PaymentMethodEnum diff --git a/src/modules/payment/services/payments.service.ts b/src/modules/payment/services/payments.service.ts index 239c300..060dc6a 100644 --- a/src/modules/payment/services/payments.service.ts +++ b/src/modules/payment/services/payments.service.ts @@ -16,6 +16,8 @@ import { CreditService } from 'src/modules/user/providers/credit.service'; import { CreditTransactionType } from 'src/modules/user/interface/credit'; import { Payment } from '../entities/payment.entity'; import { FindPaymentsDto } from '../dto/find-payments.dto'; +import { Admin } from 'src/modules/admin/entities/admin.entity'; +import { AdminRepository } from 'src/modules/admin/repositories/admin.repository'; @@ -31,11 +33,12 @@ export class PaymentService { private readonly eventEmitter: EventEmitter2, private readonly creditService: CreditService, private readonly creditRepository: CreditRepository, + private readonly adminRepository: AdminRepository, ) { } - async payOrder(orderId: string, dto: PayOrderDto): Promise<{ paymentUrl: string | null }> { + async payOrder(orderId: string, dto: PayOrderDto, adminId?: string): Promise<{ paymentUrl: string | null }> { - const ctx = await this.loadAndValidateOrder(orderId, dto) + const ctx = await this.loadAndValidateOrder(orderId, dto, adminId) switch (dto.method) { case PaymentMethodEnum.Cash: @@ -55,7 +58,7 @@ export class PaymentService { } - private async loadAndValidateOrder(orderId: string, dto: PayOrderDto): Promise { + private async loadAndValidateOrder(orderId: string, dto: PayOrderDto, adminId?: string): Promise { const { amount, method, attachments, description, gateway } = dto const order = await this.orderService.findOneOrFail(orderId) @@ -64,8 +67,12 @@ export class PaymentService { throw new NotFoundException(OrderMessage.NOT_FOUND); } - if (order.balance == 0) { - throw new BadRequestException("you can not pay beause Balance is zero") + let admin: null | Admin = null + if (adminId) { + admin = await this.adminRepository.findOne({ id: adminId }) + if (!admin) { + throw new BadRequestException("Admin not found") + } } if (amount <= 0) { @@ -77,6 +84,7 @@ export class PaymentService { } return { + admin, user: order.user, order, amount, @@ -88,8 +96,9 @@ export class PaymentService { } private async handleCashPayment(ctx: OrderPaymentContext): Promise { - const { order, amount, method, attachments, description } = ctx + const { order, amount, method, attachments, description, admin } = ctx const payment = this.paymentRepository.create({ + creator: admin, order, amount, method, @@ -103,7 +112,7 @@ export class PaymentService { private async handleCreditPayment(ctx: OrderPaymentContext): Promise { - const { order, amount, user } = ctx + const { order, amount, user, admin } = ctx await this.em.transactional(async em => { // 1. get User remained Credit @@ -116,6 +125,7 @@ export class PaymentService { const newBalance = remainedCredit - amount; // 2. Create payment record const payment = this.paymentRepository.create({ + creator: admin, amount: ctx.amount, method: PaymentMethodEnum.Credit, gateway: null, @@ -143,7 +153,7 @@ export class PaymentService { } private async handleOnlinePayment(ctx: OrderPaymentContext): Promise<{ paymentUrl: string }> { - const { amount, order, gateway: requestedGateway } = ctx + const { amount, order, gateway: requestedGateway, admin } = ctx const gateway = this.gatewayManager.get(requestedGateway!); @@ -153,6 +163,7 @@ export class PaymentService { }); const payment = this.paymentRepository.create({ + creator: admin, order, amount, method: PaymentMethodEnum.Online,