Trần Viết Sơn commited on
Commit
463569a
1 Parent(s): 069905f

feat: order

Browse files
backend/src/common/enums/ReceiptType.enum.ts ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ export enum ReceiptType {
2
+ ORDER = 0,
3
+ PAYMENT = 1,
4
+ }
backend/src/modules/order/dto/update-order.dto.ts CHANGED
@@ -1,4 +1,10 @@
1
- import { IsArray, IsNumber, IsOptional, ValidateNested } from 'class-validator';
 
 
 
 
 
 
2
  import { OrderItemsDto } from './order-items.dto.js';
3
  import { Type } from 'class-transformer';
4
 
@@ -11,4 +17,16 @@ export class UpdateOrderDto {
11
  @ValidateNested()
12
  @Type(() => OrderItemsDto)
13
  order_items: OrderItemsDto[];
 
 
 
 
 
 
 
 
 
 
 
 
14
  }
 
1
+ import {
2
+ IsArray,
3
+ IsNumber,
4
+ IsOptional,
5
+ IsString,
6
+ ValidateNested,
7
+ } from 'class-validator';
8
  import { OrderItemsDto } from './order-items.dto.js';
9
  import { Type } from 'class-transformer';
10
 
 
17
  @ValidateNested()
18
  @Type(() => OrderItemsDto)
19
  order_items: OrderItemsDto[];
20
+
21
+ @IsOptional()
22
+ @IsNumber()
23
+ order_status?: number;
24
+
25
+ @IsOptional()
26
+ @IsNumber()
27
+ rating?: number;
28
+
29
+ @IsOptional()
30
+ @IsString()
31
+ note?: string;
32
  }
backend/src/modules/order/order.controller.ts CHANGED
@@ -14,6 +14,7 @@ import { Role } from '../../common/enums/role.enum.js';
14
  import { paginate, Paginate, PaginateQuery } from 'nestjs-paginate';
15
  import { Roles } from '../authentication/authorization/roles.decorator.js';
16
  import { UpdateOrderDto } from './dto/update-order.dto.js';
 
17
 
18
  @Controller('branchs/:branchId/orders')
19
  export class BranchOrderController {
@@ -25,6 +26,7 @@ export class BranchOrderController {
25
  @Req() req: Request,
26
  @Body() createOrderDto: CreateOrderDto,
27
  ) {
 
28
  const userId = req['user'].sub;
29
  const role = req['user'].role;
30
  console.log(req['user']);
@@ -34,6 +36,7 @@ export class BranchOrderController {
34
  branchId,
35
  userId,
36
  createOrderDto,
 
37
  );
38
  } else
39
  return this.orderService.createFromStaff(
 
14
  import { paginate, Paginate, PaginateQuery } from 'nestjs-paginate';
15
  import { Roles } from '../authentication/authorization/roles.decorator.js';
16
  import { UpdateOrderDto } from './dto/update-order.dto.js';
17
+ import { Request } from 'express';
18
 
19
  @Controller('branchs/:branchId/orders')
20
  export class BranchOrderController {
 
26
  @Req() req: Request,
27
  @Body() createOrderDto: CreateOrderDto,
28
  ) {
29
+ const ipAddr = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
30
  const userId = req['user'].sub;
31
  const role = req['user'].role;
32
  console.log(req['user']);
 
36
  branchId,
37
  userId,
38
  createOrderDto,
39
+ ipAddr as string,
40
  );
41
  } else
42
  return this.orderService.createFromStaff(
backend/src/modules/order/order.module.ts CHANGED
@@ -1,13 +1,15 @@
1
- import { Module } from '@nestjs/common';
2
  import { OrderService } from './order.service.js';
3
  import { BranchOrderController, OrderController } from './order.controller.js';
4
  import { BranchModule } from '../branch/branch.module.js';
5
  import { BranchMenusModule } from '../branch-menus/branch-menus.module.js';
 
 
6
 
7
  @Module({
8
  imports: [BranchModule, BranchMenusModule],
9
  controllers: [BranchOrderController, OrderController],
10
- providers: [OrderService],
11
  exports: [OrderService],
12
  })
13
  export class OrderModule {}
 
1
+ import { forwardRef, Module } from '@nestjs/common';
2
  import { OrderService } from './order.service.js';
3
  import { BranchOrderController, OrderController } from './order.controller.js';
4
  import { BranchModule } from '../branch/branch.module.js';
5
  import { BranchMenusModule } from '../branch-menus/branch-menus.module.js';
6
+ import { PaymentModule } from '../../payment/payment.module.js';
7
+ import { PaymentService } from '../../payment/payment.service.js';
8
 
9
  @Module({
10
  imports: [BranchModule, BranchMenusModule],
11
  controllers: [BranchOrderController, OrderController],
12
+ providers: [OrderService, PaymentService],
13
  exports: [OrderService],
14
  })
15
  export class OrderModule {}
backend/src/modules/order/order.service.ts CHANGED
@@ -18,21 +18,99 @@ import {
18
  PaginateConfig,
19
  PaginateQuery,
20
  } from 'nestjs-paginate';
 
 
21
  import { UpdateOrderDto } from './dto/update-order.dto.js';
22
  import { DataSource } from 'typeorm';
 
 
 
 
23
 
24
  @Injectable()
25
  export class OrderService {
26
  constructor(
 
 
27
  private readonly branchService: BranchService,
28
  private readonly datasource: DataSource,
 
29
  ) {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  async createFromCustomer(
31
  branchId: string,
32
  userId: string,
33
  createOrderDto: CreateOrderDto,
 
34
  ) {
35
- // Chưa được update đầy đủ, còn thiếu thông tin thanh toán.
36
  if (createOrderDto.order_type != OrderType.ONLINE) {
37
  throw new BadRequestException('customer cannot create offline order');
38
  }
@@ -93,8 +171,18 @@ export class OrderService {
93
 
94
  await queryRunner.commitTransaction();
95
  await queryRunner.release();
96
- return { ...order, order_items: orderItems };
 
 
 
 
 
 
 
 
 
97
  } catch (err) {
 
98
  await queryRunner.rollbackTransaction();
99
  await queryRunner.release();
100
  throw err;
@@ -197,6 +285,29 @@ export class OrderService {
197
  // Cập nhật trạng thái
198
  // Cập nhật rating
199
  // Cập nhật note
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  }
201
 
202
  async updateOrderPayment(id: number, paymentId: number) {
 
18
  PaginateConfig,
19
  PaginateQuery,
20
  } from 'nestjs-paginate';
21
+ import * as querystring from 'qs';
22
+ import * as crypto from 'crypto';
23
  import { UpdateOrderDto } from './dto/update-order.dto.js';
24
  import { DataSource } from 'typeorm';
25
+ import { PaymentService } from '../../payment/payment.service.js';
26
+ import { ConfigService } from '@nestjs/config';
27
+ import { ReceiptEntity } from '../../entities/receipt.entity.js';
28
+ import { ReceiptType } from '../../common/enums/ReceiptType.enum.js';
29
 
30
  @Injectable()
31
  export class OrderService {
32
  constructor(
33
+ // @Inject(forwardRef(() => PaymentService))
34
+ // private readonly paymentService: PaymentService,
35
  private readonly branchService: BranchService,
36
  private readonly datasource: DataSource,
37
+ private readonly configService: ConfigService,
38
  ) {}
39
+ formatDate(date: Date, format: string): string {
40
+ const yyyymmdd = date.toISOString().slice(0, 10).replace(/-/g, ''); // YYYYMMDD
41
+ const hhmmss = date.toTimeString().slice(0, 8).replace(/:/g, ''); // HHMMSS
42
+ return format === 'yyyymmddHHmmss' ? yyyymmdd + hhmmss : hhmmss;
43
+ }
44
+
45
+ sortObject(obj) {
46
+ let sorted = {};
47
+ let str = [];
48
+ let key;
49
+ for (key in obj) {
50
+ if (obj.hasOwnProperty(key)) {
51
+ str.push(encodeURIComponent(key));
52
+ }
53
+ }
54
+ str.sort();
55
+ for (key = 0; key < str.length; key++) {
56
+ sorted[str[key]] = encodeURIComponent(obj[str[key]]).replace(/%20/g, '+');
57
+ }
58
+ return sorted;
59
+ }
60
+ async createPaymentUrl(
61
+ amount: number,
62
+ orderId: string,
63
+ orderDescription: string,
64
+ orderType: string,
65
+ language: string,
66
+ ipAddr: string,
67
+ ) {
68
+ const tmnCode = this.configService.get<string>('vnp_TmnCode');
69
+ const secretKey = this.configService.get<string>('vnp_HashSecret');
70
+ const vnpUrl = this.configService.get<string>('vnp_Url');
71
+ const returnUrl = this.configService.get<string>('vnp_ReturnUrl');
72
+
73
+ const date = new Date();
74
+ const createDate = this.formatDate(date, 'yyyymmddHHmmss');
75
+ const locale = language || 'vn';
76
+ const currCode = 'VND';
77
+
78
+ const vnp_Params: Record<string, string> = {
79
+ vnp_Version: '2.1.0',
80
+ vnp_Command: 'pay',
81
+ vnp_TmnCode: tmnCode,
82
+ vnp_Locale: locale,
83
+ vnp_CurrCode: currCode,
84
+ vnp_TxnRef: orderId,
85
+ vnp_OrderInfo: orderDescription,
86
+ vnp_OrderType: orderType,
87
+ vnp_Amount: (amount * 100).toString(),
88
+ vnp_ReturnUrl: returnUrl,
89
+ vnp_IpAddr: ipAddr,
90
+ vnp_CreateDate: createDate,
91
+ };
92
+ console.log('3');
93
+
94
+ const sortedParams = this.sortObject(vnp_Params);
95
+
96
+ // Sign the data
97
+ const signData = querystring.stringify(sortedParams, { encode: false });
98
+ const hmac = crypto.createHmac('sha512', secretKey);
99
+ const signed = hmac.update(Buffer.from(signData, 'utf-8')).digest('hex');
100
+ sortedParams['vnp_SecureHash'] = signed;
101
+
102
+ // Create the URL
103
+ const res = `${vnpUrl}?${querystring.stringify(sortedParams, { encode: false })}`;
104
+
105
+ return res;
106
+ }
107
  async createFromCustomer(
108
  branchId: string,
109
  userId: string,
110
  createOrderDto: CreateOrderDto,
111
+ ipAddr: string,
112
  ) {
113
+ // Tạo order đơn.
114
  if (createOrderDto.order_type != OrderType.ONLINE) {
115
  throw new BadRequestException('customer cannot create offline order');
116
  }
 
171
 
172
  await queryRunner.commitTransaction();
173
  await queryRunner.release();
174
+ // hoàn thành tạo order, lấy url thanh toán
175
+ const paymentUrl = await this.createPaymentUrl(
176
+ order.total_value,
177
+ '1731148499',
178
+ order.note || 'what',
179
+ 'other',
180
+ 'vn',
181
+ ipAddr,
182
+ );
183
+ return { ...order, order_items: orderItems, payment_url: paymentUrl };
184
  } catch (err) {
185
+ console.log(err);
186
  await queryRunner.rollbackTransaction();
187
  await queryRunner.release();
188
  throw err;
 
285
  // Cập nhật trạng thái
286
  // Cập nhật rating
287
  // Cập nhật note
288
+ const order = await this.findOrderOrError(id);
289
+ if (updateOrderDto.table_number) {
290
+ order.table_number = updateOrderDto.table_number;
291
+ }
292
+ if (updateOrderDto.note) {
293
+ order.note = updateOrderDto.note;
294
+ }
295
+ if (updateOrderDto.order_status) {
296
+ const st = updateOrderDto.order_status;
297
+ if (st == OrderStatus.DONE) {
298
+ const receipt = await ReceiptEntity.create({
299
+ branch_id: order.branch_id,
300
+ income: order.total_value,
301
+ type: ReceiptType.ORDER,
302
+ sender_id: order.customer_id,
303
+ receiver_id: order.staff_id,
304
+ }).save();
305
+ }
306
+ order.order_status = updateOrderDto.order_status;
307
+ }
308
+ if (updateOrderDto.rating) {
309
+ order.rating = updateOrderDto.rating;
310
+ }
311
  }
312
 
313
  async updateOrderPayment(id: number, paymentId: number) {
backend/src/payment/payment.module.ts CHANGED
@@ -1,11 +1,14 @@
1
- import { Module } from '@nestjs/common';
2
  import { PaymentService } from './payment.service.js';
3
  import { PaymentController } from './payment.controller.js';
 
 
4
  import { OrderService } from '../modules/order/order.service.js';
5
- import { BranchService } from '../modules/branch/branch.service.js';
6
 
7
  @Module({
 
8
  controllers: [PaymentController],
9
- providers: [PaymentService, OrderService, BranchService],
 
10
  })
11
  export class PaymentModule {}
 
1
+ import { forwardRef, Module } from '@nestjs/common';
2
  import { PaymentService } from './payment.service.js';
3
  import { PaymentController } from './payment.controller.js';
4
+ import { OrderModule } from '../modules/order/order.module.js';
5
+ import { BranchModule } from '../modules/branch/branch.module.js';
6
  import { OrderService } from '../modules/order/order.service.js';
 
7
 
8
  @Module({
9
+ imports: [BranchModule],
10
  controllers: [PaymentController],
11
+ providers: [PaymentService, OrderService],
12
+ exports: [PaymentService],
13
  })
14
  export class PaymentModule {}
backend/src/payment/payment.service.ts CHANGED
@@ -1,23 +1,29 @@
1
  // payment.service.ts
2
- import { HttpStatus, Injectable } from '@nestjs/common';
3
  import { ConfigService } from '@nestjs/config';
4
  import * as querystring from 'qs';
5
  import * as crypto from 'crypto';
6
  import { OrderService } from '../modules/order/order.service.js';
7
  import { PaymentEntity } from '../entities/payment.entity.js';
8
- import { CreatePaymentUrlDto } from './dto/create-payment-url.dto.js';
9
  import { CreatePaymentDto } from './dto/create-payment.dto..js';
10
  import { VnpCardType } from '../common/enums/VnpCardType.enum.js';
11
 
12
  @Injectable()
13
  export class PaymentService {
14
  constructor(
 
 
15
  private readonly configService: ConfigService,
16
- private readonly orderService: OrderService
17
- ) { }
18
-
19
- async createPaymentUrl(amount: number, orderId: string, orderDescription: string, orderType: string, language: string, ipAddr: string) {
20
-
 
 
 
 
 
21
  const tmnCode = this.configService.get<string>('vnp_TmnCode');
22
  const secretKey = this.configService.get<string>('vnp_HashSecret');
23
  const vnpUrl = this.configService.get<string>('vnp_Url');
@@ -42,7 +48,7 @@ export class PaymentService {
42
  vnp_IpAddr: ipAddr,
43
  vnp_CreateDate: createDate,
44
  };
45
- console.log("3")
46
 
47
  const sortedParams = this.sortObject(vnp_Params);
48
 
@@ -58,9 +64,8 @@ export class PaymentService {
58
  return res;
59
  }
60
 
61
-
62
  async vnpayIpn(reqQuery) {
63
- console.log("helloooo")
64
  let vnp_Params = reqQuery;
65
  let secureHash = vnp_Params['vnp_SecureHash'];
66
 
@@ -73,8 +78,8 @@ export class PaymentService {
73
  vnp_Params = this.sortObject(vnp_Params);
74
  let secretKey = this.configService.get('vnp_HashSecret');
75
  let signData = querystring.stringify(vnp_Params, { encode: false });
76
- let hmac = crypto.createHmac("sha512", secretKey);
77
- let signed = hmac.update(Buffer.from(signData, 'utf-8')).digest("hex");
78
 
79
  let paymentStatus = '0'; // Giả sử '0' là trạng thái khởi tạo giao dịch, chưa có IPN. Trạng thái này được lưu khi yêu cầu thanh toán chuyển hướng sang Cổng thanh toán VNPAY tại đầu khởi tạo đơn hàng.
80
  //let paymentStatus = '1'; // Giả sử '1' là trạng thái thành công bạn cập nhật sau IPN được gọi và trả kết quả về nó
@@ -83,31 +88,37 @@ export class PaymentService {
83
  let checkOrderId = true;
84
  let order;
85
  try {
86
- order = await this.orderService.findOne(orderId)
87
  } catch (error) {
88
  return {
89
  statusCode: HttpStatus.OK,
90
  message: 'Order not found',
91
  };
92
  }
93
- console.log("order = ", order);
94
- console.log("order total value ", order.total_value);
95
  // Kiểm tra số tiền "giá trị của vnp_Amout/100" trùng khớp với số tiền của đơn hàng trong CSDL của bạn
96
- let checkAmount = order.total_value == parseFloat(vnp_Params["vnp_Amount"])/100;
97
- if (secureHash === signed) { //kiểm tra checksum
 
 
98
  if (checkOrderId) {
99
  if (checkAmount) {
100
- if (paymentStatus == "0") { //kiểm tra tình trạng giao dịch trước khi cập nhật tình trạng thanh toán
101
- if (rspCode == "00") {
 
102
  //thanh cong
103
  //paymentStatus = '1'
104
  // Ở đây cập nhật trạng thái giao dịch thanh toán thành công vào CSDL của bạn
105
  const payment = await this.create({
106
  payment_method: 2,
107
- vnp_amount: parseFloat(vnp_Params["vnp_Amount"])/100,
108
  vnp_bank_code: vnp_Params['vnp_BankCode'],
109
  vnp_bank_tran_no: vnp_Params['vnp_BankTranNo'],
110
- vnp_card_type: VnpCardType[vnp_Params['vnp_CardType'] as keyof typeof VnpCardType],
 
 
 
111
  vnp_order_info: vnp_Params['vnp_BankTranNo'],
112
  vnp_paydate: vnp_Params['vnp_PayDate'],
113
  vnp_response_code: vnp_Params['vnp_ResponseCode'],
@@ -115,13 +126,12 @@ export class PaymentService {
115
  vnp_transaction_status: vnp_Params['vnp_TransactionStatus'],
116
  });
117
  await PaymentEntity.save(payment);
118
- this.orderService.updateOrderPayment(orderId, payment.id)
119
  return {
120
  statusCode: HttpStatus.OK,
121
  message: 'Thành công!',
122
  };
123
- }
124
- else {
125
  //that bai
126
  //paymentStatus = '2'
127
  // Ở đây cập nhật trạng thái giao dịch thanh toán thất bại vào CSDL của bạn
@@ -130,29 +140,25 @@ export class PaymentService {
130
  message: 'Thất bại',
131
  };
132
  }
133
- }
134
- else {
135
  return {
136
  statusCode: HttpStatus.OK,
137
  message: 'This order has been updated to the payment status',
138
  };
139
  }
140
- }
141
- else {
142
  return {
143
  statusCode: HttpStatus.OK,
144
  message: 'Amount invalid',
145
  };
146
  }
147
- }
148
- else {
149
  return {
150
  statusCode: HttpStatus.OK,
151
  message: 'Order not found',
152
  };
153
  }
154
- }
155
- else {
156
  return {
157
  statusCode: HttpStatus.OK,
158
  message: 'Checksum failed!',
@@ -178,12 +184,14 @@ export class PaymentService {
178
  }
179
  str.sort();
180
  for (key = 0; key < str.length; key++) {
181
- sorted[str[key]] = encodeURIComponent(obj[str[key]]).replace(/%20/g, "+");
182
  }
183
  return sorted;
184
  }
185
 
186
- async create(createPaymentDto: CreatePaymentDto): Promise<PaymentEntity | undefined> {
 
 
187
  return PaymentEntity.create({
188
  payment_method: 2,
189
  vnp_amount: createPaymentDto.vnp_amount,
@@ -194,7 +202,7 @@ export class PaymentService {
194
  vnp_paydate: createPaymentDto.vnp_paydate,
195
  vnp_response_code: createPaymentDto.vnp_response_code,
196
  vnp_transaction_no: createPaymentDto.vnp_transaction_no,
197
- vnp_transaction_status: createPaymentDto.vnp_transaction_status
198
- })
199
  }
200
  }
 
1
  // payment.service.ts
2
+ import { forwardRef, HttpStatus, Inject, Injectable } from '@nestjs/common';
3
  import { ConfigService } from '@nestjs/config';
4
  import * as querystring from 'qs';
5
  import * as crypto from 'crypto';
6
  import { OrderService } from '../modules/order/order.service.js';
7
  import { PaymentEntity } from '../entities/payment.entity.js';
 
8
  import { CreatePaymentDto } from './dto/create-payment.dto..js';
9
  import { VnpCardType } from '../common/enums/VnpCardType.enum.js';
10
 
11
  @Injectable()
12
  export class PaymentService {
13
  constructor(
14
+ @Inject(forwardRef(() => OrderService))
15
+ private readonly orderService: OrderService,
16
  private readonly configService: ConfigService,
17
+ ) {}
18
+
19
+ async createPaymentUrl(
20
+ amount: number,
21
+ orderId: string,
22
+ orderDescription: string,
23
+ orderType: string,
24
+ language: string,
25
+ ipAddr: string,
26
+ ) {
27
  const tmnCode = this.configService.get<string>('vnp_TmnCode');
28
  const secretKey = this.configService.get<string>('vnp_HashSecret');
29
  const vnpUrl = this.configService.get<string>('vnp_Url');
 
48
  vnp_IpAddr: ipAddr,
49
  vnp_CreateDate: createDate,
50
  };
51
+ console.log('3');
52
 
53
  const sortedParams = this.sortObject(vnp_Params);
54
 
 
64
  return res;
65
  }
66
 
 
67
  async vnpayIpn(reqQuery) {
68
+ console.log('helloooo');
69
  let vnp_Params = reqQuery;
70
  let secureHash = vnp_Params['vnp_SecureHash'];
71
 
 
78
  vnp_Params = this.sortObject(vnp_Params);
79
  let secretKey = this.configService.get('vnp_HashSecret');
80
  let signData = querystring.stringify(vnp_Params, { encode: false });
81
+ let hmac = crypto.createHmac('sha512', secretKey);
82
+ let signed = hmac.update(Buffer.from(signData, 'utf-8')).digest('hex');
83
 
84
  let paymentStatus = '0'; // Giả sử '0' là trạng thái khởi tạo giao dịch, chưa có IPN. Trạng thái này được lưu khi yêu cầu thanh toán chuyển hướng sang Cổng thanh toán VNPAY tại đầu khởi tạo đơn hàng.
85
  //let paymentStatus = '1'; // Giả sử '1' là trạng thái thành công bạn cập nhật sau IPN được gọi và trả kết quả về nó
 
88
  let checkOrderId = true;
89
  let order;
90
  try {
91
+ order = await this.orderService.findOne(orderId);
92
  } catch (error) {
93
  return {
94
  statusCode: HttpStatus.OK,
95
  message: 'Order not found',
96
  };
97
  }
98
+ console.log('order = ', order);
99
+ console.log('order total value ', order.total_value);
100
  // Kiểm tra số tiền "giá trị của vnp_Amout/100" trùng khớp với số tiền của đơn hàng trong CSDL của bạn
101
+ let checkAmount =
102
+ order.total_value == parseFloat(vnp_Params['vnp_Amount']) / 100;
103
+ if (secureHash === signed) {
104
+ //kiểm tra checksum
105
  if (checkOrderId) {
106
  if (checkAmount) {
107
+ if (paymentStatus == '0') {
108
+ //kiểm tra tình trạng giao dịch trước khi cập nhật tình trạng thanh toán
109
+ if (rspCode == '00') {
110
  //thanh cong
111
  //paymentStatus = '1'
112
  // Ở đây cập nhật trạng thái giao dịch thanh toán thành công vào CSDL của bạn
113
  const payment = await this.create({
114
  payment_method: 2,
115
+ vnp_amount: parseFloat(vnp_Params['vnp_Amount']) / 100,
116
  vnp_bank_code: vnp_Params['vnp_BankCode'],
117
  vnp_bank_tran_no: vnp_Params['vnp_BankTranNo'],
118
+ vnp_card_type:
119
+ VnpCardType[
120
+ vnp_Params['vnp_CardType'] as keyof typeof VnpCardType
121
+ ],
122
  vnp_order_info: vnp_Params['vnp_BankTranNo'],
123
  vnp_paydate: vnp_Params['vnp_PayDate'],
124
  vnp_response_code: vnp_Params['vnp_ResponseCode'],
 
126
  vnp_transaction_status: vnp_Params['vnp_TransactionStatus'],
127
  });
128
  await PaymentEntity.save(payment);
129
+ this.orderService.updateOrderPayment(orderId, payment.id);
130
  return {
131
  statusCode: HttpStatus.OK,
132
  message: 'Thành công!',
133
  };
134
+ } else {
 
135
  //that bai
136
  //paymentStatus = '2'
137
  // Ở đây cập nhật trạng thái giao dịch thanh toán thất bại vào CSDL của bạn
 
140
  message: 'Thất bại',
141
  };
142
  }
143
+ } else {
 
144
  return {
145
  statusCode: HttpStatus.OK,
146
  message: 'This order has been updated to the payment status',
147
  };
148
  }
149
+ } else {
 
150
  return {
151
  statusCode: HttpStatus.OK,
152
  message: 'Amount invalid',
153
  };
154
  }
155
+ } else {
 
156
  return {
157
  statusCode: HttpStatus.OK,
158
  message: 'Order not found',
159
  };
160
  }
161
+ } else {
 
162
  return {
163
  statusCode: HttpStatus.OK,
164
  message: 'Checksum failed!',
 
184
  }
185
  str.sort();
186
  for (key = 0; key < str.length; key++) {
187
+ sorted[str[key]] = encodeURIComponent(obj[str[key]]).replace(/%20/g, '+');
188
  }
189
  return sorted;
190
  }
191
 
192
+ async create(
193
+ createPaymentDto: CreatePaymentDto,
194
+ ): Promise<PaymentEntity | undefined> {
195
  return PaymentEntity.create({
196
  payment_method: 2,
197
  vnp_amount: createPaymentDto.vnp_amount,
 
202
  vnp_paydate: createPaymentDto.vnp_paydate,
203
  vnp_response_code: createPaymentDto.vnp_response_code,
204
  vnp_transaction_no: createPaymentDto.vnp_transaction_no,
205
+ vnp_transaction_status: createPaymentDto.vnp_transaction_status,
206
+ });
207
  }
208
  }