Compare commits
No commits in common. 'ee10b49cf8a36a34bd0c44b722b9406f5b65f1d1' and '9e665f8710599849458beb738c56a4ff30d404d0' have entirely different histories.
ee10b49cf8
...
9e665f8710
22 changed files with 176 additions and 443 deletions
@ -1,54 +0,0 @@ |
|||||||
"use strict"; |
|
||||||
|
|
||||||
module.exports = { |
|
||||||
up: async (queryInterface, Sequelize) => { |
|
||||||
const tableExists = await queryInterface |
|
||||||
.describeTable("Invoices") |
|
||||||
.then(() => true) |
|
||||||
.catch(() => false); |
|
||||||
|
|
||||||
if (tableExists) { |
|
||||||
await queryInterface.dropTable("Invoices", { cascade: true }); |
|
||||||
} |
|
||||||
await queryInterface.createTable("Invoices", { |
|
||||||
id: { |
|
||||||
type: Sequelize.INTEGER, |
|
||||||
autoIncrement: true, |
|
||||||
primaryKey: true, |
|
||||||
allowNull: false, |
|
||||||
}, |
|
||||||
userId: { |
|
||||||
type: Sequelize.INTEGER, |
|
||||||
allowNull: false, |
|
||||||
references: { |
|
||||||
model: "Users", |
|
||||||
key: "id", |
|
||||||
}, |
|
||||||
onDelete: "CASCADE", |
|
||||||
}, |
|
||||||
totalPaymentAmount: { |
|
||||||
type: Sequelize.FLOAT, |
|
||||||
allowNull: false, |
|
||||||
}, |
|
||||||
status: { |
|
||||||
type: Sequelize.ENUM("pending", "paid"), |
|
||||||
allowNull: false, |
|
||||||
defaultValue: "pending", |
|
||||||
}, |
|
||||||
createdAt: { |
|
||||||
type: Sequelize.DATE, |
|
||||||
allowNull: false, |
|
||||||
defaultValue: Sequelize.fn("NOW"), |
|
||||||
}, |
|
||||||
updatedAt: { |
|
||||||
type: Sequelize.DATE, |
|
||||||
allowNull: false, |
|
||||||
defaultValue: Sequelize.fn("NOW"), |
|
||||||
}, |
|
||||||
}); |
|
||||||
}, |
|
||||||
|
|
||||||
down: async (queryInterface, Sequelize) => { |
|
||||||
await queryInterface.dropTable("Invoices", { cascade: true }); |
|
||||||
}, |
|
||||||
}; |
|
@ -1,11 +1,17 @@ |
|||||||
import { Controller, Get, Post, Body, Patch, Param, Delete } from "@nestjs/common"; |
import { Controller, Get, Post, Body, Patch, Param, Delete } from "@nestjs/common"; |
||||||
import { InvoiceService } from "./invoice.service"; |
import { InvoiceService } from "./invoice.service"; |
||||||
|
import { Invoice } from "./entities/invoice.entity"; |
||||||
|
|
||||||
@Controller("invoice") |
@Controller("invoice") |
||||||
export class InvoiceController { |
export class InvoiceController { |
||||||
constructor(private readonly invoiceService: InvoiceService) {} |
constructor(private readonly invoiceService: InvoiceService) {} |
||||||
// @Get(":userId")
|
@Post("create") |
||||||
// async getInvoices(@Param("userId") userId: number): Promise<any> {
|
async createInvoice(@Body() body: { userId: number; totalAmount: number }): Promise<Invoice> { |
||||||
// return this.invoiceService.getInvoicesByUser(userId);
|
const { userId, totalAmount } = body; |
||||||
// }
|
return this.invoiceService.createInvoice(userId, totalAmount); |
||||||
|
} |
||||||
|
@Get(":userId") |
||||||
|
async getInvoices(@Param("userId") userId: number): Promise<any> { |
||||||
|
return this.invoiceService.getInvoicesByUser(userId); |
||||||
|
} |
||||||
} |
} |
||||||
|
@ -1,14 +1,12 @@ |
|||||||
import { Module, forwardRef } from "@nestjs/common"; |
import { Module } from '@nestjs/common'; |
||||||
import { SequelizeModule } from "@nestjs/sequelize"; |
import { InvoiceService } from './invoice.service'; |
||||||
import { InvoiceController } from "./invoice.controller"; |
import { InvoiceController } from './invoice.controller'; |
||||||
import { InvoiceService } from "./invoice.service"; |
import { SequelizeModule } from '@nestjs/sequelize'; |
||||||
import { Invoice } from "./entities/invoice.entity"; |
import { Invoice } from './entities/invoice.entity'; |
||||||
import { CartModule } from "src/cart/cart.module"; |
|
||||||
|
|
||||||
@Module({ |
@Module({ |
||||||
imports: [SequelizeModule.forFeature([Invoice]), forwardRef(()=>CartModule)], |
imports : [SequelizeModule.forFeature([Invoice])], |
||||||
controllers: [InvoiceController], |
controllers: [InvoiceController], |
||||||
providers: [InvoiceService], |
providers: [InvoiceService], |
||||||
exports: [InvoiceService], |
|
||||||
}) |
}) |
||||||
export class InvoiceModule {} |
export class InvoiceModule {} |
||||||
|
@ -1,71 +1,52 @@ |
|||||||
import { forwardRef, HttpException, HttpStatus, Inject, Injectable } from "@nestjs/common"; |
import { HttpException, HttpStatus, Injectable } from "@nestjs/common"; |
||||||
import { InjectModel } from "@nestjs/sequelize"; |
import { InjectModel } from "@nestjs/sequelize"; |
||||||
import { Invoice } from "./entities/invoice.entity"; |
import { Invoice } from "./entities/invoice.entity"; |
||||||
import { CartService } from "src/cart/cart.service"; |
|
||||||
import { User } from "src/users/entities/user.entity"; |
|
||||||
import { where } from "sequelize"; |
import { where } from "sequelize"; |
||||||
|
|
||||||
@Injectable() |
@Injectable() |
||||||
export class InvoiceService { |
export class InvoiceService { |
||||||
constructor( |
constructor(@InjectModel(Invoice) private readonly invoiceModel: typeof Invoice) {} |
||||||
@InjectModel(Invoice) private readonly invoiceModel: typeof Invoice, |
|
||||||
@Inject(forwardRef(() => CartService)) |
|
||||||
private cartService: CartService, |
|
||||||
) {} |
|
||||||
|
|
||||||
async createInvoiceFromCart(userId: number): Promise<Invoice> { |
async createInvoice(userId: number, totalAmount: number): Promise<Invoice> { |
||||||
const user = await User.findByPk(userId); |
try { |
||||||
if (!user) { |
if (!userId) { |
||||||
throw new HttpException("User not found", HttpStatus.NOT_FOUND); |
throw new HttpException("User id not found!", HttpStatus.BAD_REQUEST); |
||||||
} |
} |
||||||
const invoice = await this.invoiceModel.create({ |
|
||||||
userId, |
const newInvoice = await this.invoiceModel.create({ userId, totalAmount }); |
||||||
totalPaymentAmount: 0, |
return newInvoice; |
||||||
}); |
} catch (error) { |
||||||
return invoice; |
|
||||||
} |
if (error instanceof HttpException) { |
||||||
async updateTotalPayment(userId: number) { |
throw error; |
||||||
const user = await User.findByPk(userId); |
} |
||||||
if (!user) { |
|
||||||
throw new HttpException("User not found", HttpStatus.NOT_FOUND); |
throw new HttpException("An error occurred while creating the invoice.", HttpStatus.INTERNAL_SERVER_ERROR); |
||||||
} |
|
||||||
|
|
||||||
const userCartItems = await this.cartService.getUserCart(userId); |
|
||||||
if (!userCartItems || !userCartItems.cartItems || userCartItems.cartItems.length === 0) { |
|
||||||
throw new HttpException("Cart is empty", HttpStatus.BAD_REQUEST); |
|
||||||
} |
|
||||||
|
|
||||||
let invoice = await this.invoiceModel.findOne({ where: { userId, status: "pending" } }); |
|
||||||
if (!invoice) { |
|
||||||
throw new HttpException("Invoice not found", HttpStatus.NOT_FOUND); |
|
||||||
} |
} |
||||||
|
|
||||||
invoice.totalPaymentAmount = userCartItems.totalPrice; |
|
||||||
await invoice.save(); |
|
||||||
} |
} |
||||||
|
async getInvoicesByUser(userId: number): Promise<Invoice[]> { |
||||||
|
|
||||||
async getInvoiceByUserAndCart(userId: number): Promise<Invoice> { |
|
||||||
try { |
try { |
||||||
if (!userId ) { |
if (!userId) { |
||||||
throw new HttpException("User ID are required.", HttpStatus.BAD_REQUEST); |
throw new HttpException('User ID is required.', HttpStatus.BAD_REQUEST); |
||||||
} |
} |
||||||
|
|
||||||
const invoice = await this.invoiceModel.findOne({ |
const invoices = await this.invoiceModel.findAll({ |
||||||
where: { userId, status:'pending' }, |
where: { userId }, |
||||||
}); |
}); |
||||||
|
|
||||||
if (!invoice) { |
if (!invoices || invoices.length === 0) { |
||||||
throw new HttpException("Invoice not found for this user and cart.", HttpStatus.NOT_FOUND); |
throw new HttpException('No invoices found for this user.', HttpStatus.NOT_FOUND); |
||||||
} |
} |
||||||
|
|
||||||
return invoice; |
return invoices; |
||||||
} catch (error) { |
} catch (error) { |
||||||
if (error instanceof HttpException) { |
if (error instanceof HttpException) { |
||||||
throw error; |
throw error; |
||||||
} |
} |
||||||
throw new HttpException("An error occurred while retrieving the invoice.", HttpStatus.INTERNAL_SERVER_ERROR); |
throw new HttpException( |
||||||
|
'An error occurred while retrieving invoices.', |
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR, |
||||||
|
); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,55 +1,37 @@ |
|||||||
import { Injectable, InternalServerErrorException } from '@nestjs/common'; |
import { Injectable } from '@nestjs/common'; |
||||||
|
|
||||||
const ZarinpalCheckout = require('zarinpal-checkout'); |
const ZarinpalCheckout = require('zarinpal-checkout'); |
||||||
|
|
||||||
@Injectable() |
@Injectable() |
||||||
export class PaymentService { |
export class PaymentService { |
||||||
private zarinpal; |
private zarinpal; |
||||||
|
|
||||||
constructor( |
constructor() { |
||||||
) { |
this.zarinpal = ZarinpalCheckout.create('00000000-0000-0000-0000-000000000000', true);
|
||||||
this.zarinpal = this.initializeZarinpal(); |
|
||||||
} |
|
||||||
|
|
||||||
private initializeZarinpal() { |
|
||||||
const merchantId = '00000000-0000-0000-0000-000000000000'; // Merchant ID should be valid
|
|
||||||
const sandboxMode = true;
|
|
||||||
return ZarinpalCheckout.create(merchantId, sandboxMode); |
|
||||||
} |
} |
||||||
|
|
||||||
async requestPayment(amount: number, description: string, callbackUrl: string): Promise<string> { |
async requestPayment(amount: number, description: string, callbackUrl: string) { |
||||||
try { |
const result = await this.zarinpal.PaymentRequest({ |
||||||
const result = await this.zarinpal.PaymentRequest({ |
Amount: amount, |
||||||
Amount: amount,
|
CallbackURL: callbackUrl, |
||||||
CallbackURL: callbackUrl, |
Description: description, |
||||||
Description: description, |
}); |
||||||
}); |
|
||||||
|
if (result.status === 100) { |
||||||
if (result.status === 100) { |
return result.url; |
||||||
return result.url; |
} else { |
||||||
} else { |
throw new Error(`Error in payment request: ${result.status}`); |
||||||
throw new Error(`Payment request failed with status: ${result.status}`); |
|
||||||
} |
|
||||||
} catch (error) { |
|
||||||
console.log('Error in PaymentRequest:', error); |
|
||||||
throw new InternalServerErrorException(`Error in payment request: ${error.message}`); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
async verifyPayment(authority: string, amount: number) { |
||||||
async verifyPayment(authority: string, amount: number): Promise<string> { |
const result = await this.zarinpal.PaymentVerification({ |
||||||
try { |
Amount: amount, |
||||||
const result = await this.zarinpal.PaymentVerification({ |
Authority: authority, |
||||||
Amount: amount, |
}); |
||||||
Authority: authority, |
|
||||||
}); |
if (result.status === 100) { |
||||||
|
return result.RefID;
|
||||||
if (result.status === 100) { |
} else { |
||||||
return result.RefID;
|
throw new Error(`Payment verification failed: ${result.status}`); |
||||||
} else { |
|
||||||
throw new Error(`Payment verification failed with status: ${result.status}`); |
|
||||||
} |
|
||||||
} catch (error) { |
|
||||||
throw new InternalServerErrorException(`Error in payment verification: ${error.message}`); |
|
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,16 +1,19 @@ |
|||||||
import { Controller, Get, Post, Body, Patch, Param, Delete } from "@nestjs/common"; |
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; |
||||||
import { WalletService } from "./wallet.service"; |
import { WalletService } from './wallet.service'; |
||||||
import { AddBalanceResponse } from "./add-balance-response.interface"; |
import { AddBalanceResponse } from './add-balance-response.interface'; |
||||||
|
|
||||||
@Controller("wallet") |
@Controller('wallet') |
||||||
export class WalletController { |
export class WalletController { |
||||||
constructor(private readonly walletService: WalletService) {} |
constructor(private readonly walletService: WalletService) {} |
||||||
@Get(":userId") |
@Get(':userId') |
||||||
async getBalance(@Param("userId") userId: number): Promise<number> { |
async getBalance(@Param('userId') userId: number): Promise<number> { |
||||||
return this.walletService.getBalance(userId); |
return this.walletService.getBalance(userId); |
||||||
} |
} |
||||||
@Post(":userId/add") |
@Post(':userId/add') |
||||||
async addBalance(@Param("userId") userId: number, @Body("amount") amount: number): Promise<AddBalanceResponse> { |
async addBalance( |
||||||
|
@Param('userId') userId: number,
|
||||||
|
@Body('amount') amount: number
|
||||||
|
): Promise<AddBalanceResponse> { |
||||||
return this.walletService.addBalance(userId, amount); |
return this.walletService.addBalance(userId, amount); |
||||||
} |
} |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue