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 { InvoiceService } from "./invoice.service"; |
||||
import { Invoice } from "./entities/invoice.entity"; |
||||
|
||||
@Controller("invoice") |
||||
export class InvoiceController { |
||||
constructor(private readonly invoiceService: InvoiceService) {} |
||||
// @Get(":userId")
|
||||
// async getInvoices(@Param("userId") userId: number): Promise<any> {
|
||||
// return this.invoiceService.getInvoicesByUser(userId);
|
||||
// }
|
||||
@Post("create") |
||||
async createInvoice(@Body() body: { userId: number; totalAmount: number }): Promise<Invoice> { |
||||
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 { SequelizeModule } from "@nestjs/sequelize"; |
||||
import { InvoiceController } from "./invoice.controller"; |
||||
import { InvoiceService } from "./invoice.service"; |
||||
import { Invoice } from "./entities/invoice.entity"; |
||||
import { CartModule } from "src/cart/cart.module"; |
||||
import { Module } from '@nestjs/common'; |
||||
import { InvoiceService } from './invoice.service'; |
||||
import { InvoiceController } from './invoice.controller'; |
||||
import { SequelizeModule } from '@nestjs/sequelize'; |
||||
import { Invoice } from './entities/invoice.entity'; |
||||
|
||||
@Module({ |
||||
imports: [SequelizeModule.forFeature([Invoice]), forwardRef(()=>CartModule)], |
||||
imports : [SequelizeModule.forFeature([Invoice])], |
||||
controllers: [InvoiceController], |
||||
providers: [InvoiceService], |
||||
exports: [InvoiceService], |
||||
}) |
||||
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 { Invoice } from "./entities/invoice.entity"; |
||||
import { CartService } from "src/cart/cart.service"; |
||||
import { User } from "src/users/entities/user.entity"; |
||||
import { where } from "sequelize"; |
||||
|
||||
@Injectable() |
||||
export class InvoiceService { |
||||
constructor( |
||||
@InjectModel(Invoice) private readonly invoiceModel: typeof Invoice, |
||||
@Inject(forwardRef(() => CartService)) |
||||
private cartService: CartService, |
||||
) {} |
||||
constructor(@InjectModel(Invoice) private readonly invoiceModel: typeof Invoice) {} |
||||
|
||||
async createInvoiceFromCart(userId: number): Promise<Invoice> { |
||||
const user = await User.findByPk(userId); |
||||
if (!user) { |
||||
throw new HttpException("User not found", HttpStatus.NOT_FOUND); |
||||
} |
||||
const invoice = await this.invoiceModel.create({ |
||||
userId, |
||||
totalPaymentAmount: 0, |
||||
}); |
||||
return invoice; |
||||
} |
||||
async updateTotalPayment(userId: number) { |
||||
const user = await User.findByPk(userId); |
||||
if (!user) { |
||||
throw new HttpException("User not found", HttpStatus.NOT_FOUND); |
||||
} |
||||
|
||||
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); |
||||
async createInvoice(userId: number, totalAmount: number): Promise<Invoice> { |
||||
try { |
||||
if (!userId) { |
||||
throw new HttpException("User id not found!", HttpStatus.BAD_REQUEST); |
||||
} |
||||
|
||||
const newInvoice = await this.invoiceModel.create({ userId, totalAmount }); |
||||
return newInvoice; |
||||
} catch (error) { |
||||
|
||||
if (error instanceof HttpException) { |
||||
throw error; |
||||
} |
||||
|
||||
throw new HttpException("An error occurred while creating the invoice.", HttpStatus.INTERNAL_SERVER_ERROR); |
||||
} |
||||
|
||||
invoice.totalPaymentAmount = userCartItems.totalPrice; |
||||
await invoice.save(); |
||||
} |
||||
|
||||
|
||||
async getInvoiceByUserAndCart(userId: number): Promise<Invoice> { |
||||
async getInvoicesByUser(userId: number): Promise<Invoice[]> { |
||||
try { |
||||
if (!userId ) { |
||||
throw new HttpException("User ID are required.", HttpStatus.BAD_REQUEST); |
||||
if (!userId) { |
||||
throw new HttpException('User ID is required.', HttpStatus.BAD_REQUEST); |
||||
} |
||||
|
||||
const invoice = await this.invoiceModel.findOne({ |
||||
where: { userId, status:'pending' }, |
||||
const invoices = await this.invoiceModel.findAll({ |
||||
where: { userId }, |
||||
}); |
||||
|
||||
if (!invoice) { |
||||
throw new HttpException("Invoice not found for this user and cart.", HttpStatus.NOT_FOUND); |
||||
if (!invoices || invoices.length === 0) { |
||||
throw new HttpException('No invoices found for this user.', HttpStatus.NOT_FOUND); |
||||
} |
||||
|
||||
return invoice; |
||||
return invoices; |
||||
} catch (error) { |
||||
if (error instanceof HttpException) { |
||||
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'); |
||||
|
||||
@Injectable() |
||||
export class PaymentService { |
||||
private zarinpal; |
||||
|
||||
constructor( |
||||
) { |
||||
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); |
||||
constructor() { |
||||
this.zarinpal = ZarinpalCheckout.create('00000000-0000-0000-0000-000000000000', true);
|
||||
} |
||||
|
||||
async requestPayment(amount: number, description: string, callbackUrl: string): Promise<string> { |
||||
try { |
||||
const result = await this.zarinpal.PaymentRequest({ |
||||
Amount: amount,
|
||||
CallbackURL: callbackUrl, |
||||
Description: description, |
||||
}); |
||||
|
||||
if (result.status === 100) { |
||||
return result.url; |
||||
} else { |
||||
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 requestPayment(amount: number, description: string, callbackUrl: string) { |
||||
const result = await this.zarinpal.PaymentRequest({ |
||||
Amount: amount, |
||||
CallbackURL: callbackUrl, |
||||
Description: description, |
||||
}); |
||||
|
||||
if (result.status === 100) { |
||||
return result.url; |
||||
} else { |
||||
throw new Error(`Error in payment request: ${result.status}`); |
||||
} |
||||
} |
||||
|
||||
async verifyPayment(authority: string, amount: number): Promise<string> { |
||||
try { |
||||
const result = await this.zarinpal.PaymentVerification({ |
||||
Amount: amount, |
||||
Authority: authority, |
||||
}); |
||||
|
||||
if (result.status === 100) { |
||||
return result.RefID;
|
||||
} else { |
||||
throw new Error(`Payment verification failed with status: ${result.status}`); |
||||
} |
||||
} catch (error) { |
||||
throw new InternalServerErrorException(`Error in payment verification: ${error.message}`); |
||||
async verifyPayment(authority: string, amount: number) { |
||||
const result = await this.zarinpal.PaymentVerification({ |
||||
Amount: amount, |
||||
Authority: authority, |
||||
}); |
||||
|
||||
if (result.status === 100) { |
||||
return result.RefID;
|
||||
} else { |
||||
throw new Error(`Payment verification failed: ${result.status}`); |
||||
} |
||||
} |
||||
} |
||||
|
@ -1,16 +1,19 @@ |
||||
import { Controller, Get, Post, Body, Patch, Param, Delete } from "@nestjs/common"; |
||||
import { WalletService } from "./wallet.service"; |
||||
import { AddBalanceResponse } from "./add-balance-response.interface"; |
||||
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; |
||||
import { WalletService } from './wallet.service'; |
||||
import { AddBalanceResponse } from './add-balance-response.interface'; |
||||
|
||||
@Controller("wallet") |
||||
@Controller('wallet') |
||||
export class WalletController { |
||||
constructor(private readonly walletService: WalletService) {} |
||||
@Get(":userId") |
||||
async getBalance(@Param("userId") userId: number): Promise<number> { |
||||
@Get(':userId') |
||||
async getBalance(@Param('userId') userId: number): Promise<number> { |
||||
return this.walletService.getBalance(userId); |
||||
} |
||||
@Post(":userId/add") |
||||
async addBalance(@Param("userId") userId: number, @Body("amount") amount: number): Promise<AddBalanceResponse> { |
||||
@Post(':userId/add') |
||||
async addBalance( |
||||
@Param('userId') userId: number,
|
||||
@Body('amount') amount: number
|
||||
): Promise<AddBalanceResponse> { |
||||
return this.walletService.addBalance(userId, amount); |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue