pay as admin
This commit is contained in:
@@ -15,6 +15,8 @@ import { UserId } from 'src/common/decorators';
|
|||||||
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
|
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
|
||||||
import { PayOrderDto } from '../dto/pay-order.dto';
|
import { PayOrderDto } from '../dto/pay-order.dto';
|
||||||
import { FindPaymentsDto } from '../dto/find-payments.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')
|
@ApiTags('payment')
|
||||||
@Controller()
|
@Controller()
|
||||||
@@ -49,13 +51,21 @@ export class PaymentController {
|
|||||||
|
|
||||||
/*=============== Admin =============== */
|
/*=============== Admin =============== */
|
||||||
|
|
||||||
|
@Post('admin/payments/pay-order/:orderId')
|
||||||
|
@UseGuards(AdminAuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Get('public/payments')
|
@ApiOperation({ summary: 'Pay for an order as Admin' })
|
||||||
@ApiOperation({ summary: 'get all payments as user' })
|
payOrderAsAdmin(@Param('orderId') orderId: string, @AdminId() adminId: string, @Body() dto: PayOrderDto) {
|
||||||
findAll(@Query() dto: FindPaymentsDto) {
|
return this.paymentsService.payOrder(orderId, dto, adminId);
|
||||||
return this.paymentsService.findAll(dto);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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')
|
@Post('admin/payments/:paymentId/verify/cash')
|
||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { BaseEntity } from '../../../common/entities/base.entity';
|
|||||||
import { Order } from '../../order/entities/order.entity';
|
import { Order } from '../../order/entities/order.entity';
|
||||||
import { PaymentGatewayEnum, PaymentMethodEnum, PaymentStatusEnum } from '../interface/payment';
|
import { PaymentGatewayEnum, PaymentMethodEnum, PaymentStatusEnum } from '../interface/payment';
|
||||||
import { ulid } from 'ulid';
|
import { ulid } from 'ulid';
|
||||||
|
import { Admin } from 'src/modules/admin/entities/admin.entity';
|
||||||
|
|
||||||
@Entity({ tableName: 'payments' })
|
@Entity({ tableName: 'payments' })
|
||||||
export class Payment extends BaseEntity {
|
export class Payment extends BaseEntity {
|
||||||
@@ -13,6 +14,9 @@ export class Payment extends BaseEntity {
|
|||||||
@Index()
|
@Index()
|
||||||
order!: Order;
|
order!: Order;
|
||||||
|
|
||||||
|
@ManyToOne(() => Admin, { nullable: true })
|
||||||
|
creator?: Admin
|
||||||
|
|
||||||
@Property({ type: 'decimal', precision: 10, scale: 0 })
|
@Property({ type: 'decimal', precision: 10, scale: 0 })
|
||||||
amount!: number;
|
amount!: number;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { Admin } from 'src/modules/admin/entities/admin.entity';
|
||||||
import type { Order } from 'src/modules/order/entities/order.entity';
|
import type { Order } from 'src/modules/order/entities/order.entity';
|
||||||
import { User } from 'src/modules/user/entities/user.entity';
|
import { User } from 'src/modules/user/entities/user.entity';
|
||||||
|
|
||||||
@@ -25,7 +26,8 @@ export interface ICreatePayment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderPaymentContext {
|
export interface OrderPaymentContext {
|
||||||
user:User;
|
admin: Admin|null
|
||||||
|
user: User;
|
||||||
order: Order;
|
order: Order;
|
||||||
amount: number;
|
amount: number;
|
||||||
method: PaymentMethodEnum
|
method: PaymentMethodEnum
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import { CreditService } from 'src/modules/user/providers/credit.service';
|
|||||||
import { CreditTransactionType } from 'src/modules/user/interface/credit';
|
import { CreditTransactionType } from 'src/modules/user/interface/credit';
|
||||||
import { Payment } from '../entities/payment.entity';
|
import { Payment } from '../entities/payment.entity';
|
||||||
import { FindPaymentsDto } from '../dto/find-payments.dto';
|
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 eventEmitter: EventEmitter2,
|
||||||
private readonly creditService: CreditService,
|
private readonly creditService: CreditService,
|
||||||
private readonly creditRepository: CreditRepository,
|
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) {
|
switch (dto.method) {
|
||||||
case PaymentMethodEnum.Cash:
|
case PaymentMethodEnum.Cash:
|
||||||
@@ -55,7 +58,7 @@ export class PaymentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async loadAndValidateOrder(orderId: string, dto: PayOrderDto): Promise<OrderPaymentContext> {
|
private async loadAndValidateOrder(orderId: string, dto: PayOrderDto, adminId?: string): Promise<OrderPaymentContext> {
|
||||||
const { amount, method, attachments, description, gateway } = dto
|
const { amount, method, attachments, description, gateway } = dto
|
||||||
|
|
||||||
const order = await this.orderService.findOneOrFail(orderId)
|
const order = await this.orderService.findOneOrFail(orderId)
|
||||||
@@ -64,8 +67,12 @@ export class PaymentService {
|
|||||||
throw new NotFoundException(OrderMessage.NOT_FOUND);
|
throw new NotFoundException(OrderMessage.NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order.balance == 0) {
|
let admin: null | Admin = null
|
||||||
throw new BadRequestException("you can not pay beause Balance is zero")
|
if (adminId) {
|
||||||
|
admin = await this.adminRepository.findOne({ id: adminId })
|
||||||
|
if (!admin) {
|
||||||
|
throw new BadRequestException("Admin not found")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amount <= 0) {
|
if (amount <= 0) {
|
||||||
@@ -77,6 +84,7 @@ export class PaymentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
admin,
|
||||||
user: order.user,
|
user: order.user,
|
||||||
order,
|
order,
|
||||||
amount,
|
amount,
|
||||||
@@ -88,8 +96,9 @@ export class PaymentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async handleCashPayment(ctx: OrderPaymentContext): Promise<void> {
|
private async handleCashPayment(ctx: OrderPaymentContext): Promise<void> {
|
||||||
const { order, amount, method, attachments, description } = ctx
|
const { order, amount, method, attachments, description, admin } = ctx
|
||||||
const payment = this.paymentRepository.create({
|
const payment = this.paymentRepository.create({
|
||||||
|
creator: admin,
|
||||||
order,
|
order,
|
||||||
amount,
|
amount,
|
||||||
method,
|
method,
|
||||||
@@ -103,7 +112,7 @@ export class PaymentService {
|
|||||||
|
|
||||||
|
|
||||||
private async handleCreditPayment(ctx: OrderPaymentContext): Promise<void> {
|
private async handleCreditPayment(ctx: OrderPaymentContext): Promise<void> {
|
||||||
const { order, amount, user } = ctx
|
const { order, amount, user, admin } = ctx
|
||||||
|
|
||||||
await this.em.transactional(async em => {
|
await this.em.transactional(async em => {
|
||||||
// 1. get User remained Credit
|
// 1. get User remained Credit
|
||||||
@@ -116,6 +125,7 @@ export class PaymentService {
|
|||||||
const newBalance = remainedCredit - amount;
|
const newBalance = remainedCredit - amount;
|
||||||
// 2. Create payment record
|
// 2. Create payment record
|
||||||
const payment = this.paymentRepository.create({
|
const payment = this.paymentRepository.create({
|
||||||
|
creator: admin,
|
||||||
amount: ctx.amount,
|
amount: ctx.amount,
|
||||||
method: PaymentMethodEnum.Credit,
|
method: PaymentMethodEnum.Credit,
|
||||||
gateway: null,
|
gateway: null,
|
||||||
@@ -143,7 +153,7 @@ export class PaymentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async handleOnlinePayment(ctx: OrderPaymentContext): Promise<{ paymentUrl: string }> {
|
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!);
|
const gateway = this.gatewayManager.get(requestedGateway!);
|
||||||
|
|
||||||
@@ -153,6 +163,7 @@ export class PaymentService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const payment = this.paymentRepository.create({
|
const payment = this.paymentRepository.create({
|
||||||
|
creator: admin,
|
||||||
order,
|
order,
|
||||||
amount,
|
amount,
|
||||||
method: PaymentMethodEnum.Online,
|
method: PaymentMethodEnum.Online,
|
||||||
|
|||||||
Reference in New Issue
Block a user