A full-stack limit-order exchange application built with Laravel API backend and Vue.js frontend, featuring real-time order matching, WebSocket updates, and financial data integrity.
- User authentication with Laravel Sanctum
- USD balance and cryptocurrency asset management (BTC, ETH)
- Limit order placement (Buy/Sell)
- Automatic order matching engine with atomic transactions
- 1.5% commission on matched trades
- Real-time updates via Pusher WebSockets
- Race-condition safe balance & asset management
- Order cancellation with locked funds release
Backend:
- Laravel 12 (latest)
- MySQL/PostgreSQL (using SQLite for development)
- Laravel Sanctum for API authentication
- Pusher for real-time broadcasting
- BCMath for precise decimal calculations
Frontend:
- Vue.js 3 with Composition API
- TypeScript
- Pinia for state management
- Vue Router
- Tailwind CSS
- Axios for API requests
- Laravel Echo & Pusher-js for WebSocket
- PHP >= 8.2
- Composer
- Node.js >= 22.12.0
- npm or yarn
- Navigate to backend directory:
cd backend- Install PHP dependencies:
composer install- Configure environment:
cp .env.example .env
php artisan key:generate- Update
.envwith your Pusher credentials:
BROADCAST_CONNECTION=pusher
PUSHER_APP_ID=your_app_id
PUSHER_APP_KEY=your_app_key
PUSHER_APP_SECRET=your_app_secret
PUSHER_APP_CLUSTER=mt1- Run migrations:
php artisan migrate- Start the development server:
php artisan serveThe API will be available at http://localhost:8000
- Navigate to frontend directory:
cd frontend- Install dependencies:
npm install- Create
.envfile:
cp .env.example .env- Update
.envwith Pusher credentials:
VITE_API_URL=http://localhost:8000
VITE_PUSHER_APP_KEY=your_app_key
VITE_PUSHER_APP_CLUSTER=mt1- Start the development server:
npm run devThe frontend will be available at http://localhost:5173
POST /api/register- Register new userPOST /api/login- Login userPOST /api/logout- Logout user (authenticated)
GET /api/profile- Get user balance and assets (authenticated)
GET /api/orders?symbol=BTC- Get orderbook for a symbolPOST /api/orders- Place a new order (authenticated)POST /api/orders/{id}/cancel- Cancel an order (authenticated)GET /api/my-orders- Get user's order history (authenticated)
- Check if
users.balance >= amount * price - Deduct USD from user balance
- Create open buy order
- Match with first available sell order where
sell.price <= buy.price - Execute trade and update balances/assets
- Check if
assets.amount >= amount - Move amount from
assets.amounttoassets.locked_amount - Create open sell order
- Match with first available buy order where
buy.price >= sell.price - Execute trade and update balances/assets
- 1.5% commission on total USD value of trade
- Deducted from seller's proceeds
- Example: 0.01 BTC @ $95,000 = $950 total, commission = $14.25
The application uses Pusher WebSockets for real-time updates:
- Order matched events broadcast to both buyer and seller
- Private channels:
private-user.{userId} - Frontend automatically updates balance, assets, and order list
idnameemailpasswordbalance(decimal 20,8) - USD funds
iduser_idsymbol(BTC, ETH)amount(decimal 20,8) - Available amountlocked_amount(decimal 20,8) - Reserved for open sell orders
iduser_idsymbolside(buy/sell)price(decimal 20,8)amount(decimal 20,8)status(1=open, 2=filled, 3=cancelled)
idbuy_order_idsell_order_idbuyer_idseller_idsymbolprice(decimal 20,8)amount(decimal 20,8)total(decimal 20,8)commission(decimal 20,8)
- Register two users (Buyer and Seller)
- Each user starts with $100,000 USD balance
- Seller needs assets first - place a sell order at a high price
- Manually add assets to seller in database or create a seeder
- Place matching buy/sell orders
- Observe real-time updates in both user sessions
User A (Seller):
- Needs 0.1 BTC in assets
- Places sell order: 0.01 BTC @ $95,000
User B (Buyer):
- Has $100,000 USD balance
- Places buy order: 0.01 BTC @ $95,000 or higher
Result:
- Trade executes at $95,000
- Total: $950
- Commission: $14.25
- Buyer receives 0.01 BTC
- Seller receives $935.75 ($950 - $14.25)
- Both users see real-time updates
- CSRF protection
- SQL injection prevention via Eloquent ORM
- XSS protection
- Atomic database transactions
- Row-level locking to prevent race conditions
- Input validation on all endpoints
- Password hashing with bcrypt
- Set
APP_ENV=productionin.env - Set
APP_DEBUG=false - Configure proper database (MySQL/PostgreSQL)
- Set up queue workers for background jobs:
php artisan queue:work- Configure proper Pusher credentials
- Set up CORS for your frontend domain
- Build frontend for production:
npm run build- Uses BCMath for precise financial calculations
- All monetary values stored as decimal(20,8)
- Database transactions ensure atomic operations
- Lock-for-update prevents race conditions
- Full order matching happens only (no partial fills)
This project is open-source and available under the MIT License.
For issues or questions, please open an issue in the GitHub repository.