A modern, secure banking API built with Go that follows Tunisian banking standards and regulations.
- π§ Tunisian IBAN format support (TN59 + 20 digits)
- ποΈ Tunisian BIC codes (STB, BIAT, BNA, ATB, UBCI)
- π° Tunisian Dinar (TND) as primary currency with millimes precision
- π± Multi-currency support for EUR/USD foreign currency accounts
- π Account types following Central Bank of Tunisia (BCT) regulations
- π JWT-based authentication with secure token management
- π‘οΈ Password hashing with bcrypt encryption
- πͺ Protected endpoints with middleware authorization
- π CORS support for web applications
- β° Token refresh functionality
- πΈ Multi-currency transactions (TND, EUR, USD)
- π Automatic fee calculation based on transaction type
- β‘ Real-time balance updates in millimes precision
- π Transaction status tracking (PENDING, COMPLETED, FAILED)
- π Comprehensive transaction history with filtering options
- π― RESTful API design with clean endpoints
- β Proper HTTP status codes for all responses
- π Structured JSON responses with consistent format
- π Input validation with detailed error messages
β οΈ Error handling with timestamps and tracking
- π§ Go 1.23.0 or higher
- π PostgreSQL database
- π¦ Git version control
- π³ Docker & Docker Compose (for containerized deployment)
-
π₯ Clone the repository
git clone <repository-url> cd bank-api
-
π¦ Install dependencies
go mod tidy
-
βοΈ Set up environment variables
CRITICAL: Copy and configure environment file:
# Copy the example file copy .env.example .env # Edit .env with your SECURE values # β οΈ NEVER use the example values in production!
Required secure configuration in
.env:# IMPORTANT: Generate secure values for production! # Database - Use strong credentials DB_USER=your_secure_db_user DB_PASSWORD=your_very_secure_password_min_16_chars DB_NAME=your_database_name # JWT - Generate with: openssl rand -hex 32 JWT_SECRET=your_32_char_minimum_secure_jwt_secret # PgAdmin (dev only) PGADMIN_DEFAULT_EMAIL=admin@your-company.local PGADMIN_DEFAULT_PASSWORD=your_secure_pgadmin_password
-
ποΈ Start PostgreSQL database
You can use Docker to run PostgreSQL:
# Uses environment variables from .env file docker run --name postgres-bank ` -e POSTGRES_USER=$env:DB_USER ` -e POSTGRES_PASSWORD=$env:DB_PASSWORD ` -e POSTGRES_DB=$env:DB_NAME ` -p 5434:5432 ` -d postgres:15-alpine
Or make sure PostgreSQL is running with the configured database.
-
π Run the application
make dev
The API will be available at
http://localhost:8080
-
π₯ Clone the repository
git clone <repository-url> cd bank-api
-
π³ Start with Docker Compose ```bash
make docker-run
make docker-dev
This will: - π Create and start PostgreSQL with initialization data - ποΈ Build and start the banking API - π§ Optionally start PgAdmin for database administration -
β Check status
# View logs make docker-logs # Check API health curl http://localhost:8080/api/v1/health
-
π Stop services
# Stop containers make docker-stop # Clean everything (removes volumes and data) make docker-clean
The Docker Compose setup starts these services:
- π¦ bank-api: Main API on configured port (default: 8080)
- π postgres: PostgreSQL database on configured port (default: 5434)
- π§ pgadmin: PostgreSQL admin interface (development profile only)
- Access via your configured credentials in
.envfile - URL:
http://localhost:5050
- Access via your configured credentials in
go build -o bin/bank-api cmd/server/main.go
./bin/bank-apihttp://localhost:8080/api/v1
Most endpoints require JWT authentication. Include the token in the Authorization header:
Authorization: Bearer <your-jwt-token>
GET /api/v1/healthReturns the API health status.
POST /api/v1/accounts
Content-Type: application/json
{
"first_name": "Mohamed",
"last_name": "Ben Ahmed",
"email": "mohamed.benahmed@example.tn",
"phone": "+21612345678",
"date_of_birth": "1990-01-15T00:00:00Z",
"password": "securepassword123",
"account_type": "CHECKING",
"currency": "TND",
"address": {
"street": "Avenue Habib Bourguiba 123",
"city": "Tunis",
"postal_code": "1001",
"country": "Tunisia",
"state": "Tunis"
}
}POST /api/v1/auth/login
Content-Type: application/json
{
"account_number": "TN59...",
"password": "securepassword123"
}POST /api/v1/auth/refresh
Authorization: Bearer <token>POST /api/v1/auth/logout
Authorization: Bearer <token>GET /api/v1/accounts/{id}
Authorization: Bearer <token>GET /api/v1/accounts/number/{account_number}
Authorization: Bearer <token>GET /api/v1/accounts/customer/{customer_id}
Authorization: Bearer <token>GET /api/v1/accounts?limit=10&offset=0
Authorization: Bearer <token>PUT /api/v1/accounts/{id}
Authorization: Bearer <token>
Content-Type: application/json
{
"phone": "+1234567891",
"address": {
"street": "456 Oak St",
"city": "Boston",
"postal_code": "02101",
"country": "United States",
"state": "MA"
}
}DELETE /api/v1/accounts/{id}
Authorization: Bearer <token>GET /api/v1/accounts/{account_number}/balance
Authorization: Bearer <token>PATCH /api/v1/accounts/{id}/status
Authorization: Bearer <token>
Content-Type: application/json
{
"status": "ACTIVE"
}POST /api/v1/transactions/transfer
Authorization: Bearer <token>
Content-Type: application/json
{
"from_account_number": "TN5961705312451143542106",
"to_account_number": "TN5959238705041140193701",
"amount": 25000,
"currency": "TND",
"description": "Transfer to friend",
"reference": "TXN-2025-001"
}POST /api/v1/transactions/deposit
Authorization: Bearer <token>
Content-Type: application/json
{
"account_number": "TN5961705312451143542106",
"amount": 100000,
"currency": "TND",
"description": "Initial deposit"
}POST /api/v1/transactions/withdraw
Authorization: Bearer <token>
Content-Type: application/json
{
"account_number": "TN5961705312451143542106",
"amount": 10000,
"currency": "TND",
"description": "ATM withdrawal"
}GET /api/v1/transactions/{id}
Authorization: Bearer <token>GET /api/v1/transactions/account/{account_id}?limit=10&offset=0
Authorization: Bearer <token>GET /api/v1/transactions?limit=10&offset=0
Authorization: Bearer <token>PUT /api/v1/transactions/{id}/status
Authorization: Bearer <token>
Content-Type: application/json
{
"status": "COMPLETED"
}{
"success": true,
"data": {
// Response data
},
"message": "Success message",
"timestamp": "2025-05-31T06:15:30Z"
}{
"success": false,
"error": "Error message",
"timestamp": "2025-05-31T06:15:30Z"
}CHECKING- Standard checking accountSAVINGS- High-yield savings accountBUSINESS- Business banking accountFOREIGN_CURRENCY- Multi-currency account (EUR/USD)
TRANSFER- Transfer between accountsDEPOSIT- Account depositWITHDRAWAL- Account withdrawalPAYMENT- Payment transaction
PENDING- Awaiting processingCOMPLETED- Successfully completed transactionFAILED- Failed transaction
TND- Tunisian Dinar (primary currency)EUR- Euro (foreign currency accounts)USD- US Dollar (foreign currency accounts)
Run the comprehensive test suite:
go test ./tests/...The test suite includes:
- Account creation and management
- Authentication flow
- Transaction processing
- Error handling
- Edge cases
bank-api/
βββ cmd/
β βββ server/
β βββ main.go # Application entry point
βββ internal/
β βββ api/
β β βββ handlers/ # HTTP request handlers
β β βββ middleware/ # Authentication, logging, CORS
β β βββ routes/ # Route definitions
β βββ config/ # Configuration management
β βββ models/ # Data models and DTOs
β βββ repository/ # Data access layer
β βββ services/ # Business logic layer
β βββ utils/ # Utility functions
βββ tests/ # Comprehensive test suite
βββ README.md # This file
The application uses environment variables for configuration:
SERVER_PORT- Server port (default: 3000)SERVER_HOST- Server host (default: localhost)SERVER_READ_TIMEOUT- Read timeout (default: 30s)SERVER_WRITE_TIMEOUT- Write timeout (default: 30s)
DB_HOST- Database host (default: localhost)DB_PORT- Database port (default: 5433)DB_USER- Database user (default: bankgo)DB_PASSWORD- Database password (default: testbank)DB_NAME- Database name (default: bankdb)DB_SSLMODE- SSL mode (default: disable)
JWT_SECRET- JWT signing secret (required in production)JWT_EXPIRES_IN- Token expiration time (default: 24h)JWT_ISSUER- JWT issuer (default: bank-api)
- Change the JWT secret in production
- Use HTTPS in production environments
- Implement rate limiting for API endpoints
- Regular security audits of dependencies
- Input validation on all endpoints
- Secure database connections with SSL in production
- Database indexes on frequently queried fields
- Connection pooling for database connections
- Pagination for large result sets
- Efficient JSON marshaling/unmarshaling
- Proper HTTP caching headers
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
This project is licensed under the MIT License .
For support and questions, please open an issue in the repository.
Built by Mohamed Amine Ammar with β€οΈ using Go and following international banking standards