verify cash paymnt
This commit is contained in:
@@ -16,6 +16,7 @@ import { UpdatePaymentMethodDto } from '../dto/update-payment-method.dto';
|
|||||||
import { VerifyPaymentDto } from '../dto/verify-payment.dto';
|
import { VerifyPaymentDto } from '../dto/verify-payment.dto';
|
||||||
import { RestId, UserId } from 'src/common/decorators';
|
import { RestId, UserId } from 'src/common/decorators';
|
||||||
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
|
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
|
||||||
|
import { API_HEADER_SLUG } from 'src/common/constants';
|
||||||
|
|
||||||
@ApiTags('payments')
|
@ApiTags('payments')
|
||||||
@Controller()
|
@Controller()
|
||||||
@@ -23,20 +24,13 @@ export class PaymentsController {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly paymentsService: PaymentsService,
|
private readonly paymentsService: PaymentsService,
|
||||||
private readonly paymentMethodService: PaymentMethodService,
|
private readonly paymentMethodService: PaymentMethodService,
|
||||||
) { }
|
) {}
|
||||||
|
|
||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Get('public/payments/methods/restaurant')
|
@Get('public/payments/methods/restaurant')
|
||||||
@ApiOperation({ summary: 'Get the restaurant payment methods' })
|
@ApiOperation({ summary: 'Get the restaurant payment methods' })
|
||||||
@ApiHeader({
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
name: 'X-Slug',
|
|
||||||
required: true,
|
|
||||||
schema: {
|
|
||||||
type: 'string',
|
|
||||||
default: 'zhivan',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@ApiNotFoundResponse({ description: 'Restaurant payment methods not found' })
|
@ApiNotFoundResponse({ description: 'Restaurant payment methods not found' })
|
||||||
getTheRestaurantPaymentMethods(@RestId() restId: string) {
|
getTheRestaurantPaymentMethods(@RestId() restId: string) {
|
||||||
return this.paymentMethodService.findByRestaurant(restId);
|
return this.paymentMethodService.findByRestaurant(restId);
|
||||||
@@ -46,14 +40,7 @@ export class PaymentsController {
|
|||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Get('public/payments')
|
@Get('public/payments')
|
||||||
@ApiOperation({ summary: 'Get all the restaurant payments for user' })
|
@ApiOperation({ summary: 'Get all the restaurant payments for user' })
|
||||||
@ApiHeader({
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
name: 'X-Slug',
|
|
||||||
required: true,
|
|
||||||
schema: {
|
|
||||||
type: 'string',
|
|
||||||
default: 'zhivan',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
findAllByRestaurant(@UserId() userId: string, @RestId() restId: string) {
|
findAllByRestaurant(@UserId() userId: string, @RestId() restId: string) {
|
||||||
return this.paymentsService.findAllByRestaurantId(restId, userId);
|
return this.paymentsService.findAllByRestaurantId(restId, userId);
|
||||||
}
|
}
|
||||||
@@ -63,13 +50,19 @@ export class PaymentsController {
|
|||||||
@Get('public/payments/pay-order/:orderId')
|
@Get('public/payments/pay-order/:orderId')
|
||||||
@ApiOperation({ summary: 'Pay for an order' })
|
@ApiOperation({ summary: 'Pay for an order' })
|
||||||
@ApiParam({ name: 'orderId', type: 'string', description: 'Order ID' })
|
@ApiParam({ name: 'orderId', type: 'string', description: 'Order ID' })
|
||||||
@ApiHeader({
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
name: 'X-Slug',
|
|
||||||
required: true,
|
|
||||||
})
|
|
||||||
payAnOrder(@Param('orderId') orderId: string) {
|
payAnOrder(@Param('orderId') orderId: string) {
|
||||||
return this.paymentsService.payOrder(orderId);
|
return this.paymentsService.payOrder(orderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('public/payments/verify')
|
||||||
|
@ApiOperation({ summary: 'Verify a payment' })
|
||||||
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
|
@ApiBody({ type: VerifyPaymentDto })
|
||||||
|
@ApiNotFoundResponse({ description: 'Payment not found' })
|
||||||
|
verifyPayment(@Body() verifyPaymentDto: VerifyPaymentDto) {
|
||||||
|
return this.paymentsService.verifyPayment(verifyPaymentDto.authority, verifyPaymentDto.orderId);
|
||||||
|
}
|
||||||
// @UseGuards(AdminAuthGuard)
|
// @UseGuards(AdminAuthGuard)
|
||||||
// @ApiBearerAuth()
|
// @ApiBearerAuth()
|
||||||
// @Get('admin/payments/:id')
|
// @Get('admin/payments/:id')
|
||||||
@@ -152,19 +145,12 @@ export class PaymentsController {
|
|||||||
return this.paymentMethodService.remove(paymentMethodId);
|
return this.paymentMethodService.remove(paymentMethodId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('public/payments/verify')
|
@UseGuards(AdminAuthGuard)
|
||||||
@ApiOperation({ summary: 'Verify a payment' })
|
@ApiBearerAuth()
|
||||||
@ApiHeader({
|
@Post('admin/payments/verify-cash-method/:paymentId')
|
||||||
name: 'X-Slug',
|
@ApiOperation({ summary: 'Verify cash payment ' })
|
||||||
required: true,
|
@ApiParam({ name: 'paymentId', type: 'string', description: 'Payment ID' })
|
||||||
schema: {
|
verifyCashPayment(@Param('paymentId') paymentId: string) {
|
||||||
type: 'string',
|
return this.paymentMethodService.remove(paymentId);
|
||||||
default: 'zhivan',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@ApiBody({ type: VerifyPaymentDto })
|
|
||||||
@ApiNotFoundResponse({ description: 'Payment not found' })
|
|
||||||
verifyPayment(@Body() verifyPaymentDto: VerifyPaymentDto) {
|
|
||||||
return this.paymentsService.verifyPayment(verifyPaymentDto.authority, verifyPaymentDto.orderId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,4 +57,6 @@ export class PaymentMethodService {
|
|||||||
await this.em.removeAndFlush(paymentMethod);
|
await this.em.removeAndFlush(paymentMethod);
|
||||||
return paymentMethod;
|
return paymentMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { UserWallet } from 'src/modules/users/entities/user-wallet.entity';
|
|||||||
import { OrderPaymentContext } from '../interface/payment';
|
import { OrderPaymentContext } from '../interface/payment';
|
||||||
import { InventoryService } from 'src/modules/inventory/inventory.service';
|
import { InventoryService } from 'src/modules/inventory/inventory.service';
|
||||||
import { OrderStatus } from 'src/modules/orders/interface/order.interface';
|
import { OrderStatus } from 'src/modules/orders/interface/order.interface';
|
||||||
|
import { PaymentMethod } from '../entities/payment-method.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PaymentsService {
|
export class PaymentsService {
|
||||||
@@ -212,6 +213,29 @@ export class PaymentsService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async verifyCashPayment(id: string): Promise<Payment> {
|
||||||
|
const payment = await this.em.transactional(async em => {
|
||||||
|
const payment = await em.findOne(Payment, id, { populate: ['order'] });
|
||||||
|
if (!payment) {
|
||||||
|
throw new NotFoundException('Payment not found');
|
||||||
|
}
|
||||||
|
if (payment.method !== PaymentMethodEnum.Cash) {
|
||||||
|
throw new BadRequestException('Payment method is not cash');
|
||||||
|
}
|
||||||
|
if (payment.status === PaymentStatusEnum.Paid) {
|
||||||
|
throw new BadRequestException('Payment already paid');
|
||||||
|
}
|
||||||
|
payment.order.status = OrderStatus.PAID;
|
||||||
|
payment.status = PaymentStatusEnum.Paid;
|
||||||
|
payment.paidAt = new Date();
|
||||||
|
em.persist(payment);
|
||||||
|
em.persist(payment.order);
|
||||||
|
await em.flush();
|
||||||
|
return payment;
|
||||||
|
});
|
||||||
|
return payment;
|
||||||
|
}
|
||||||
|
|
||||||
private markPaid(payment: Payment, referenceId: string) {
|
private markPaid(payment: Payment, referenceId: string) {
|
||||||
payment.status = PaymentStatusEnum.Paid;
|
payment.status = PaymentStatusEnum.Paid;
|
||||||
payment.paidAt = new Date();
|
payment.paidAt = new Date();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
import { IsString, IsOptional, IsNumber, IsBoolean, IsArray, IsUrl, IsObject } from 'class-validator';
|
import { IsString, IsOptional, IsNumber, IsBoolean, IsArray, IsUrl, IsObject, IsEnum } from 'class-validator';
|
||||||
|
import { PlanEnum } from '../interface/plan.interface';
|
||||||
|
|
||||||
export class CreateRestaurantDto {
|
export class CreateRestaurantDto {
|
||||||
@ApiProperty({ example: 'کافه ژیوان', description: 'نام رستوران' })
|
@ApiProperty({ example: 'کافه ژیوان', description: 'نام رستوران' })
|
||||||
@@ -65,7 +66,6 @@ export class CreateRestaurantDto {
|
|||||||
@IsNumber()
|
@IsNumber()
|
||||||
establishedYear?: number;
|
establishedYear?: number;
|
||||||
|
|
||||||
|
|
||||||
@ApiPropertyOptional({ example: '09123456789', description: 'شماره تلفن' })
|
@ApiPropertyOptional({ example: '09123456789', description: 'شماره تلفن' })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@@ -151,4 +151,8 @@ export class CreateRestaurantDto {
|
|||||||
marriageDateScore: string;
|
marriageDateScore: string;
|
||||||
referrerScore: string;
|
referrerScore: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ApiProperty({ example: true, description: 'PlanEnum.Base', enum: PlanEnum })
|
||||||
|
@IsEnum(PlanEnum)
|
||||||
|
plan: PlanEnum;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Collection, Entity, Index, OneToMany, Property } from '@mikro-orm/core';
|
import { Collection, Entity, Enum, Index, OneToMany, Property } from '@mikro-orm/core';
|
||||||
import { BaseEntity } from '../../../common/entities/base.entity';
|
import { BaseEntity } from '../../../common/entities/base.entity';
|
||||||
import { Delivery } from '../../delivery/entities/delivery.entity';
|
import { Delivery } from '../../delivery/entities/delivery.entity';
|
||||||
|
import { PlanEnum } from '../interface/plan.interface';
|
||||||
|
|
||||||
@Entity({ tableName: 'restaurants' })
|
@Entity({ tableName: 'restaurants' })
|
||||||
@Index({ properties: ['isActive'] })
|
@Index({ properties: ['isActive'] })
|
||||||
@@ -42,7 +43,6 @@ export class Restaurant extends BaseEntity {
|
|||||||
@Property({ nullable: true })
|
@Property({ nullable: true })
|
||||||
establishedYear?: number;
|
establishedYear?: number;
|
||||||
|
|
||||||
|
|
||||||
@Property({ nullable: true })
|
@Property({ nullable: true })
|
||||||
phone?: string;
|
phone?: string;
|
||||||
|
|
||||||
@@ -96,4 +96,7 @@ export class Restaurant extends BaseEntity {
|
|||||||
marriageDateScore: string;
|
marriageDateScore: string;
|
||||||
referrerScore: string;
|
referrerScore: string;
|
||||||
} | null = null;
|
} | null = null;
|
||||||
|
|
||||||
|
@Enum(() => PlanEnum)
|
||||||
|
plan: PlanEnum = PlanEnum.Base;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export enum PlanEnum {
|
||||||
|
Base = 'base',
|
||||||
|
Premium = 'premium',
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
import { CreateRestaurantDto } from '../dto/create-restaurant.dto';
|
import { CreateRestaurantDto } from '../dto/create-restaurant.dto';
|
||||||
import { UpdateRestaurantDto } from '../dto/update-restaurant.dto';
|
import { UpdateRestaurantDto } from '../dto/update-restaurant.dto';
|
||||||
import { Restaurant } from '../entities/restaurant.entity';
|
import { Restaurant } from '../entities/restaurant.entity';
|
||||||
import { EntityManager } from '@mikro-orm/postgresql';
|
import { EntityManager } from '@mikro-orm/postgresql';
|
||||||
import { RestRepository } from '../repositories/rest.repository';
|
import { RestRepository } from '../repositories/rest.repository';
|
||||||
import { RestMessage } from 'src/common/enums/message.enum';
|
import { RestMessage } from 'src/common/enums/message.enum';
|
||||||
@@ -17,6 +17,7 @@ export class RestaurantsService {
|
|||||||
const restaurant = this.em.create(Restaurant, {
|
const restaurant = this.em.create(Restaurant, {
|
||||||
...dto,
|
...dto,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
|
plan: dto.plan,
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.em.persistAndFlush(restaurant);
|
await this.em.persistAndFlush(restaurant);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { PlanEnum } from 'src/modules/restaurants/interface/plan.interface';
|
||||||
|
|
||||||
export interface RestaurantData {
|
export interface RestaurantData {
|
||||||
name: string;
|
name: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
@@ -18,6 +20,7 @@ export interface RestaurantData {
|
|||||||
marriageDateScore: string;
|
marriageDateScore: string;
|
||||||
referrerScore: string;
|
referrerScore: string;
|
||||||
};
|
};
|
||||||
|
plan: PlanEnum.Premium;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const restaurantsData: RestaurantData[] = [
|
export const restaurantsData: RestaurantData[] = [
|
||||||
@@ -49,6 +52,7 @@ export const restaurantsData: RestaurantData[] = [
|
|||||||
marriageDateScore: '10000',
|
marriageDateScore: '10000',
|
||||||
referrerScore: '10000',
|
referrerScore: '10000',
|
||||||
},
|
},
|
||||||
|
plan: PlanEnum.Premium,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'بوته',
|
name: 'بوته',
|
||||||
@@ -78,6 +82,7 @@ export const restaurantsData: RestaurantData[] = [
|
|||||||
marriageDateScore: '10000',
|
marriageDateScore: '10000',
|
||||||
referrerScore: '10000',
|
referrerScore: '10000',
|
||||||
},
|
},
|
||||||
|
plan: PlanEnum.Premium,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'هنر',
|
name: 'هنر',
|
||||||
@@ -107,5 +112,6 @@ export const restaurantsData: RestaurantData[] = [
|
|||||||
marriageDateScore: '10000',
|
marriageDateScore: '10000',
|
||||||
referrerScore: '10000',
|
referrerScore: '10000',
|
||||||
},
|
},
|
||||||
|
plan: PlanEnum.Premium,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user