Charging Station Mock API (json-server)
Mock server cho feature Charging Station theo tài liệu:
docs/charging_station_final_spec.md
1. Cài dependency
cd mock/charging-station
bun install
2. Chạy server
bun run start
Mặc định chạy ở http://localhost:3100.
Có thể đổi port:
PORT=3200 bun run start
3. Static Files (Images)
Server serve static files từ folder public/. Cấu trúc:
mock/charging-station/
├── public/
│ └── images/
│ ├── banners/ # Ảnh banner (800x400 recommended)
│ │ ├── banner_summer_sale.png
│ │ ├── banner_cashback.png
│ │ └── banner_new_year.png
│ └── vouchers/ # Ảnh voucher (300x200 recommended)
│ ├── starbucks.png
│ ├── kfc.png
│ ├── grab.png
│ └── ...
├── db.json
└── server.js
Cách thêm ảnh mới:
- Đặt file ảnh vào
public/images/banners/hoặcpublic/images/vouchers/ - Cập nhật
imageUrltrongdb.jsonvới path tương đối:/images/banners/ten_file.png - Server sẽ tự động build full URL:
http://localhost:3100/images/banners/ten_file.png
Access trực tiếp:
# Xem ảnh trong browser
open http://localhost:3100/images/banners/banner_summer_sale.png
4. Endpoints
Tất cả endpoint dùng POST:
| Endpoint | Mô tả |
|---|---|
POST /charging-station/execute |
Thực thi giao dịch nạp tiền |
POST /charging-station/getHomeData |
Lấy dữ liệu trang Home |
POST /charging-station/search |
Tìm kiếm với AI gợi ý |
POST /charging-station/reward/getList |
Danh sách ưu đãi/voucher |
5. Validation Rules
POST /charging-station/execute
Input validation:
| Field | Rule | Regex |
|---|---|---|
accountNumber |
Bắt buộc, đúng 9 ký tự, chỉ chứa số | ^[0-9]{9}$ |
amount |
Bắt buộc, > 0, tối đa 1,000,000,000 | — |
accountName |
Không bắt buộc, chỉ chữ cái và khoảng trắng | ^[a-zA-ZÀ-ỹ\s]*$ |
Error codes:
| Code | Điều kiện | Message |
|---|---|---|
01 |
Dữ liệu không hợp lệ / TK không tồn tại | Tùy context |
02 |
Số dư không đủ | "Số dư không đủ" |
03 |
Vượt hạn mức (> 1 tỷ) | "Số tiền tối đa là 1,000,000,000 VND" |
Simulate scenarios:
| Scenario | Cách test |
|---|---|
| TK không tồn tại | accountNumber bắt đầu bằng 999 |
| Số dư không đủ | accountNumber bắt đầu bằng 111 + amount > 500000000 |
| Vượt hạn mức | amount > 1000000000 |
POST /charging-station/search
queryrỗng: trả full default data (recent + suggested + chips).querycó giá trị: filtersuggestionstheotitle/description.
POST /charging-station/reward/getList
- Hỗ trợ
categoryđể filter voucher/brand. - Hỗ trợ
page+pageSizeđể phân trangvouchers. - Trả thêm
pagingđể client dễ test load more.
6. Curl samples
Execute success
curl -X POST http://localhost:3100/charging-station/execute \
-H "Content-Type: application/json" \
-d '{
"sessionId": "abc123",
"deviceId": "device-001",
"accountNumber": "012345678",
"amount": "1000000",
"accountName": "NGUYEN VAN A",
"isDefaultAccount": true
}'
Execute - TK không tồn tại
curl -X POST http://localhost:3100/charging-station/execute \
-H "Content-Type: application/json" \
-d '{
"accountNumber": "999123456",
"amount": "1000000"
}'
Execute - Số dư không đủ
curl -X POST http://localhost:3100/charging-station/execute \
-H "Content-Type: application/json" \
-d '{
"accountNumber": "111234567",
"amount": "600000000"
}'
Execute - Vượt hạn mức
curl -X POST http://localhost:3100/charging-station/execute \
-H "Content-Type: application/json" \
-d '{
"accountNumber": "012345678",
"amount": "1500000000"
}'
Execute - accountNumber sai format
curl -X POST http://localhost:3100/charging-station/execute \
-H "Content-Type: application/json" \
-d '{
"accountNumber": "12345",
"amount": "1000000"
}'
Execute - accountName có ký tự đặc biệt
curl -X POST http://localhost:3100/charging-station/execute \
-H "Content-Type: application/json" \
-d '{
"accountNumber": "012345678",
"amount": "1000000",
"accountName": "Nguyen Van A@123"
}'
Get Home Data
curl -X POST http://localhost:3100/charging-station/getHomeData \
-H "Content-Type: application/json" \
-d '{"sessionId":"abc123","deviceId":"device-001"}'
Response structure:
accounts[]- Danh sách tài khoản cá nhân (DEFAULT, APPLE_PAY, OVERDRAFT, SALARY)businessAccounts[]- Danh sách tài khoản hộ kinh doanhloyaltyPoints,cashbackAmount,memberLevel- Thông tin loyaltyrecentTransactions[]- Giao dịch gần đây
Search default
curl -X POST http://localhost:3100/charging-station/search \
-H "Content-Type: application/json" \
-d '{"sessionId":"abc123","query":"","page":1,"pageSize":20}'
Search with query
curl -X POST http://localhost:3100/charging-station/search \
-H "Content-Type: application/json" \
-d '{"sessionId":"abc123","query":"chuyển tiền","page":1,"pageSize":20}'
Reward - page 1 (có banners)
curl -X POST http://localhost:3100/charging-station/reward/getList \
-H "Content-Type: application/json" \
-d '{"sessionId":"abc123","page":1,"pageSize":5}'
Response structure:
banners[]- Danh sách banner (chỉ trả về ở page 1)vouchers[]- Danh sách voucher (phân trang)paging- Thông tin phân trang
Reward - load more (page 2+, không có banners)
curl -X POST http://localhost:3100/charging-station/reward/getList \
-H "Content-Type: application/json" \
-d '{"sessionId":"abc123","page":2,"pageSize":5}'
Voucher fields:
imageUrl- URL ảnh vouchercontent- Nội dung/mô tả ưu đãiexpiry- Thời hạn (rỗng = không giới hạn)requireCardSpending-true= yêu cầu chi tiêu thẻ
7. BASE_URL Configuration
| Environment | BASE_URL |
|---|---|
| Local | http://localhost:3100 |
| VPS Production | https://api-mock.example.com |
TODO: Cập nhật VPS Production URL sau khi deploy.
8. Deploy lên VPS với PM2
8.1 Cài đặt môi trường trên VPS
# 1. Cài Bun (JavaScript runtime)
curl -fsSL https://bun.sh/install | bash
source ~/.bashrc
# 2. Cài Node.js (cần cho PM2)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
# 3. Cài PM2 globally
sudo npm install -g pm2
# 4. Verify installations
bun --version
node --version
pm2 --version
8.2 Clone và setup project
# Clone repo (hoặc copy folder mock/charging-station)
cd /var/www
git clone <repo-url> mbbank-mock
cd mbbank-mock/mock/charging-station
# Cài dependencies
bun install
8.3 Chạy với PM2
# Start server với PM2
pm2 start ecosystem.config.cjs --env production
# Hoặc start trực tiếp
pm2 start server.js --name "charging-station-mock" --interpreter bun
# Xem logs
pm2 logs charging-station-mock
# Xem status
pm2 status
# Restart
pm2 restart charging-station-mock
# Stop
pm2 stop charging-station-mock
# Delete
pm2 delete charging-station-mock
8.4 Auto-start khi reboot VPS
# Generate startup script
pm2 startup
# Save current process list
pm2 save
8.5 Cấu hình Nginx (reverse proxy)
# /etc/nginx/sites-available/charging-station-mock
server {
listen 80;
server_name api-mock.example.com;
location / {
proxy_pass http://127.0.0.1:3100;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
# Enable site
sudo ln -s /etc/nginx/sites-available/charging-station-mock /etc/nginx/sites-enabled/
# Test config
sudo nginx -t
# Reload nginx
sudo systemctl reload nginx
8.6 Cài SSL với Certbot (HTTPS)
# Cài Certbot
sudo apt install certbot python3-certbot-nginx
# Lấy SSL certificate
sudo certbot --nginx -d api-mock.example.com
# Auto-renew (đã tự động setup)
sudo certbot renew --dry-run
8.7 PM2 Commands Reference
| Command | Mô tả |
|---|---|
pm2 start ecosystem.config.cjs |
Start với config file |
pm2 start server.js --name app |
Start với tên custom |
pm2 list |
Xem danh sách processes |
pm2 logs [name] |
Xem logs |
pm2 monit |
Monitor realtime |
pm2 restart [name] |
Restart process |
pm2 reload [name] |
Zero-downtime reload |
pm2 stop [name] |
Stop process |
pm2 delete [name] |
Xóa process |
pm2 save |
Lưu process list |
pm2 startup |
Setup auto-start |
8.8 Đổi Port
# Cách 1: Environment variable
PORT=3200 pm2 start server.js --name "charging-station-mock" --interpreter bun
# Cách 2: Sửa ecosystem.config.cjs
# env_production: { PORT: 3200 }
pm2 start ecosystem.config.cjs --env production
9. Troubleshooting
PM2 không nhận Bun
# Kiểm tra path của bun
which bun
# Output: /home/user/.bun/bin/bun
# Sử dụng full path
pm2 start server.js --interpreter /home/user/.bun/bin/bun
Port đã được sử dụng
# Tìm process đang dùng port
sudo lsof -i :3100
# Kill process
sudo kill -9 <PID>
Logs quá lớn
# Rotate logs
pm2 install pm2-logrotate
# Config logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
Description
Languages
JavaScript
100%