Skip to content

Naman501/Bank-Ledger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Banking Ledger API

A Node.js + Express + MongoDB backend for a ledger-based banking workflow.

This project provides:

  • User authentication with JWT and cookie support
  • Account creation and balance lookup
  • Double-entry ledger transactions (debit + credit)
  • Idempotency protection for transaction creation
  • Token blacklist-based logout
  • Email notifications for registration and transactions

Tech Stack

  • Node.js
  • Express
  • MongoDB + Mongoose
  • JWT (jsonwebtoken)
  • Cookies (cookie-parser)
  • Password hashing (bcrypt)
  • Email (nodemailer with Gmail OAuth2)

Project Structure

Banking Ledger/
	package.json
	server.js
	src/
		app.js
		config/
			db.js
		controller/
			auth.controller.js
			account.controller.js
			transaction.controller.js
		middleware/
			auth.middleware.js
		models/
			user.model.js
			account.model.js
			ledger.model.js
			transactiion.model.js
			blackList.model.js
		routes/
			auth.routes.js
			account.routes.js
			transaction.routes.js
		services/
			email.service.js

How It Works

1. Auth Flow

  • POST /api/auth/register creates a user and returns a JWT.
  • POST /api/auth/login validates credentials and returns a JWT.
  • JWT is sent in response and also set in a token cookie.
  • Protected routes read token from either:
    • Cookie: token
    • Header: Authorization: Bearer <token>

2. Accounts

  • Each account belongs to a user.
  • Account has status (ACTIVE, FROZEN, CLOSED) and currency (default INR).
  • Balance is derived from ledger entries:
    • Credits increase balance
    • Debits decrease balance

3. Transactions (Double-entry)

For each transfer:

  • A transaction document is created (PENDING -> COMPLETED).
  • One DEBIT ledger entry is created for sender account.
  • One CREDIT ledger entry is created for receiver account.
  • The operation runs in a MongoDB session/transaction.

4. Idempotency

  • Each transaction requires a unique idempotencyKey.
  • If the key already exists, API returns a status-aware response instead of duplicating transfer.

5. Logout Security

  • Logout stores token in blacklist collection.
  • Blacklisted tokens are rejected by auth middleware.
  • Blacklist documents expire automatically (TTL index: 3 days).

Prerequisites

  • Node.js 18+
  • MongoDB connection URI
  • Gmail OAuth2 credentials (for email notifications)

Installation

npm install

Environment Variables

Create a .env file in project root:

MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_jwt_secret

EMAIL_USER=your_email@gmail.com
CLIENT_ID=your_google_oauth_client_id
CLIENT_SECRET=your_google_oauth_client_secret
REFRESH_TOKEN=your_google_oauth_refresh_token

Run the Server

Development:

npm run dev

Production:

npm start

Server starts on:

http://localhost:2000

API Base URL

http://localhost:2000/api

API Endpoints

Auth

Register

POST /auth/register

Request body:

{
	"name": "Naman",
	"email": "naman@example.com",
	"password": "password123"
}

Login

POST /auth/login

Request body:

{
	"email": "naman@example.com",
	"password": "password123"
}

Logout

POST /auth/logout

Auth required.


Accounts

Create Account

POST /accounts

Auth required.

Get User Accounts

GET /accounts

Auth required.

Get Account Balance

GET /accounts/balance/:accountId

Auth required.


Transactions

Create Transfer

POST /transactions

Auth required.

Request body:

{
	"fromAccount": "ACCOUNT_ID_1",
	"toAccount": "ACCOUNT_ID_2",
	"amount": 500,
	"idempotencyKey": "txn-2026-03-16-0001"
}

Create Initial Funds Transaction (System User Only)

POST /transactions/system/initial-funds

Requires authenticated user with systemUser=true.

Request body:

{
	"toAccount": "ACCOUNT_ID",
	"amount": 1000,
	"idempotencyKey": "init-funds-2026-03-16-0001"
}

Authentication Notes

  • Send token in cookie or bearer header.
  • Blacklisted tokens are denied.
  • Some routes require system-user authorization.

Bearer header format:

Authorization: Bearer <jwt_token>

Data Models (Overview)

User

  • name
  • email (unique)
  • password (hashed, hidden by default)
  • systemUser (default false, hidden by default)

Account

  • user (ObjectId -> User)
  • status (ACTIVE | FROZEN | CLOSED)
  • currency (default INR)

Transaction

  • fromAccount (ObjectId -> Account)
  • toAccount (ObjectId -> Account)
  • amount
  • status (PENDING | COMPLETED | FAILED | REVERSED)
  • idempotencyKey (unique)

Ledger

  • account (ObjectId -> Account)
  • transaction (ObjectId -> Transaction)
  • amount
  • type (DEBIT | CREDIT)
  • Immutable after creation (update/delete operations are blocked)

Token Blacklist

  • token (unique)
  • TTL expiration (3 days)

Example cURL Requests

Register:

curl -X POST http://localhost:2000/api/auth/register \
	-H "Content-Type: application/json" \
	-d '{"name":"Naman","email":"naman@example.com","password":"password123"}'

Create account (Bearer token):

curl -X POST http://localhost:2000/api/accounts \
	-H "Authorization: Bearer YOUR_TOKEN"

Create transaction:

curl -X POST http://localhost:2000/api/transactions \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer YOUR_TOKEN" \
	-d '{"fromAccount":"ACCOUNT_ID_1","toAccount":"ACCOUNT_ID_2","amount":500,"idempotencyKey":"txn-001"}'

License

ISC

About

Developed a Bank Ledger API using Node.js, Express, and MongoDB supporting secure transactions, ledger-based balance tracking, JWT authentication, and Swagger-documented endpoints.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors