Giới thiệu dự án

Thương mại điện tử (E-Commerce) tại khu vực Đông Nam Á và Việt Nam đang chứng kiến tốc độ tăng trưởng kép hàng năm (CAGR) vượt mức 20%, trở thành trụ cột quan trọng của nền kinh tế số. Tuy nhiên, sự dịch chuyển hành vi tiêu dùng từ Offline sang Omnichannel (đa kênh) đặt ra bài toán phức tạp cho các doanh nghiệp bán lẻ thiết bị công nghệ: vừa phải duy trì hệ thống Web bán hàng trực quan, vừa phải tối ưu hóa ứng dụng di động cho khách lẻ (Buyer) và đội ngũ giao vận (Shipper).

Nhiều giải pháp E-Commerce hiện nay bộc lộ nhiều điểm nghẽn nghiêm trọng:

  • Trải nghiệm người dùng (UX) bị phân mảnh giữa nền tảng Website và Mobile App.
  • Cơ chế quản lý trạng thái đơn hàng và thu hộ (COD - Cash on Delivery) chưa đồng bộ thời gian thực giữa quản trị viên, người mua và tài xế.
  • Hiệu năng xử lý truy vấn dữ liệu sản phẩm có nhiều biến thể (SKU) còn chậm chạp, gây suy giảm tỷ lệ chuyển đổi (Conversion Rate).
  • Chi phí phát triển và bảo trì tách rời giữa các nền tảng Native iOS/Android và Web App quá cao đối với các doanh nghiệp vừa và nhỏ (SMEs).

Đề tài "Xây dựng Hệ thống bán hàng điện tử sử dụng MERN Stack và Flutter" được thực hiện bởi nhóm nghiên cứu Khoa Công nghệ Thông tin - Trường Đại học Sư phạm Kỹ thuật TP.HCM (HCMUTE), dưới sự hướng dẫn của ThS. Nguyễn Hữu Trung. Đề tài tập trung giải quyết triệt để các hạn chế trên thông qua 5 mục tiêu cốt lõi:

  1. Xây dựng RESTful API backend đồng nhất, bảo mật cao bằng Node.js và Express.js, tích hợp cơ sở dữ liệu MongoDB.
  2. Thiết kế Web Application quản trị (Admin) và mua sắm (Client) chuẩn Single Page Application (SPA) bằng React.js 18.
  3. Phát triển hệ sinh thái ứng dụng di động đa nền tảng bằng Flutter 3.x gồm 2 ứng dụng độc lập: Store App (cho khách hàng) và Shipping App (cho tài xế giao nhận).
  4. Chuẩn hóa quy trình thanh toán đa phương thức (COD, thẻ ngân hàng/trực tuyến) và quản lý đối soát COD tự động cho Shipper.
  5. Triển khai kiến trúc xác thực đa tầng với JSON Web Token (JWT) và xác thực mã OTP qua Email.

Hệ thống đặt kỳ vọng đạt độ trễ phản hồi API trung bình dưới 120ms, đảm bảo tính toàn vẹn dữ liệu đơn hàng 100% và tiết kiệm 45% chi phí phát triển ứng dụng di động so với việc viết Native Code riêng rẽ.

Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Khảo sát thực tế các nền tảng bán lẻ công nghệ và bách hóa hàng đầu tại Việt Nam như Bách Hóa Xanh và Di Động Việt cho thấy rõ các khoảng trống công nghệ:

Tiêu chí phân tích Hệ thống Bách Hóa Xanh Hệ thống Di Động Việt Hệ sinh thái MERN + Flutter (Đề tài)
Đa nền tảng (Web/App) Web SPA + App Hybrid Web SPA + App Mobile Web SPA (React.js) + 2 Mobile Apps (Flutter)
Module Shipper chuyên dụng Sử dụng ứng dụng đối tác thứ 3 Chưa tối ưu hệ thống nội bộ Tích hợp riêng ứng dụng Shipping App
Đánh giá & Review sản phẩm Bị giới hạn hiển thị Thiếu trên phiên bản Mobile Đồng bộ 2 chiều Web và Mobile App
Xác thực tài khoản Đăng ký cơ bản Số điện thoại / SMS JWT + Xác thực Email OTP tự động
Quản trị khuyến mãi / Voucher Áp dụng toàn cục Nhập mã thủ công Quản lý vòng đời mã giảm giá động

Yêu cầu hệ thống được mô hình hóa theo ma trận MoSCoW:

  • Must-Have: Xác thực OTP, quản lý sản phẩm đa biến thể, giỏ hàng, đặt hàng COD/Card, phân quyền RBAC (User, Admin, Shipper), chức năng giao nhận và đối soát công nợ COD cho Shipper.
  • Should-Have: Tìm kiếm theo từ khóa/danh mục, bộ lọc theo giá và trạng thái, quản lý voucher khuyến mãi, hệ thống đánh giá/bình luận sản phẩm sau mua.
  • Could-Have: Chỉ đường giao hàng trên bản đồ cho Shipper, thống kê doanh thu biểu đồ động phía Admin Dashboard.
  • Won't-Have (giai đoạn này): Chatbot AI tư vấn tự động, thanh toán quốc tế bằng tiền mã hóa.

Thiết kế hệ thống

Kiến trúc tổng thể của hệ thống được xây dựng theo mô hình Client-Server 3 lớp phân tách rõ ràng (Three-Tier Architecture), kết nối thông qua giao thức truyền thông HTTP/HTTPS RESTful APIs:

graph TD
    subgraph Client_Layer ["Client Layer (Giao diện người dùng)"]
        A1[Web Client / Admin - React.js 18]
        A2[Store App Buyer - Flutter 3.19]
        A3[Shipping App Shipper - Flutter 3.19]
    end

    subgraph Service_Layer ["API Gateway & Service Layer"]
        B1[Express.js / Node.js Runtime]
        B2[Authentication Middleware: JWT & OTP]
        B3[Business Logic Controllers: Product, Order, User, Shipping]
        B4[Cloudinary SDK: Media CDN Proxy]
    end

    subgraph Data_Layer ["Data Storage Layer"]
        C1[(MongoDB Cluster - NoSQL)]
        C2[Cloudinary Media Storage]
    end

    A1 -->|REST API Request / JSON| B1
    A2 -->|REST API Request / JSON| B1
    A3 -->|REST API Request / JSON| B1
    B1 --> B2
    B2 --> B3
    B3 -->|Mongoose ODM| C1
    B3 -->|Upload Multipart Data| C2

Hệ thống công nghệ chi tiết gồm:

  • Backend: Node.js v20.x, Express.js v4.18.x, Mongoose ODM v7.x.
  • Database: MongoDB v6.0 Server (lưu trữ phi quan hệ theo Document BSON).
  • Web Frontend: React.js v18.2, React Router DOM v6, Axios, Context API / Redux Toolkit.
  • Mobile Frontend: Flutter SDK v3.19.x, Dart SDK v3.3.x, HTTP Package, Provider/Bloc Pattern.
  • Cloud Service: Cloudinary Media API (lưu trữ hình ảnh sản phẩm phân tán).

Cơ sở dữ liệu MongoDB được thiết kế tối ưu với 7 collections chính: users, products, orders, vouchers, address, shippings, shippers. Dưới đây là lược đồ đặc tả cấu trúc OrderSchemaProductSchema:

// models/Order.js - Thiết kế lược đồ đơn hàng
const mongoose = require('mongoose');

const orderSchema = new mongoose.Schema({
  user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  orderItems: [{
    product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true },
    name: { type: String, required: true },
    quantity: { type: Number, required: true },
    price: { type: Number, required: true },
    image: { type: String, required: true }
  }],
  shippingAddress: {
    address: { type: String, required: true },
    city: { type: String, required: true },
    phone: { type: String, required: true }
  },
  paymentMethod: { type: String, enum: ['COD', 'CARD'], default: 'COD' },
  itemsPrice: { type: Number, required: true },
  taxPrice: { type: Number, default: 0.0 },
  shippingPrice: { type: Number, default: 0.0 },
  totalPrice: { type: Number, required: true },
  voucherApplied: { type: mongoose.Schema.Types.ObjectId, ref: 'Voucher' },
  isPaid: { type: Boolean, default: false },
  paidAt: { type: Date },
  status: { 
    type: String, 
    enum: ['Pending', 'Confirmed', 'Shipping', 'Delivered', 'Cancelled'], 
    default: 'Pending' 
  },
  assignedShipper: { type: mongoose.Schema.Types.ObjectId, ref: 'Shipper' }
}, { timestamps: true });

module.exports = mongoose.model('Order', orderSchema);

Hệ thống thiết kế chuẩn RESTful API với các endpoints trọng yếu:

Method Endpoint Quyền truy cập Mô tả nghiệp vụ
POST /api/v1/users/register Public Đăng ký người dùng và kích hoạt gửi OTP qua Email
POST /api/v1/users/verify-otp Public Xác thực mã OTP 6 số để kích hoạt tài khoản
POST /api/v1/users/login Public Xác thực thông tin và trả về JWT Bearer Token
GET /api/v1/products Public Lấy danh sách sản phẩm phân trang, lọc và tìm kiếm
POST /api/v1/products Private (Admin) Thêm mới sản phẩm, upload ảnh lên Cloudinary
POST /api/v1/orders Private (User) Tạo đơn đặt hàng, kiểm tra tính hợp lệ của Voucher
PUT /api/v1/orders/:id/status Private (Admin/Shipper) Cập nhật tiến trình giao hàng
POST /api/v1/shippers/reconcile-cod Private (Shipper) Quyết toán dòng tiền thu hộ về hệ thống

Methodology

Quy trình phát triển được triển khai theo mô hình Agile/Scrum rút gọn kéo dài trong 13 tuần (04/03/2024 – 02/06/2024), chia thành các mốc quan trọng:

  • Phase 1 (Tuần 1 - 2): Khảo sát hiện trạng, phân tích nghiệp vụ, thiết kế Use Case, Sequence Diagram và CSDL MongoDB.
  • Phase 2 (Tuần 3 - 5): Xây dựng RESTful API Engine, thiết kế kiến trúc xác thực JWT, cấu hình Cloudinary Media Engine.
  • Phase 3 (Tuần 6 - 8): Phát triển giao diện Web Client và Admin Dashboard trên React.js; tích hợp API giỏ hàng và danh mục.
  • Phase 4 (Tuần 9 - 11): Lập trình Store App và Shipping App bằng Flutter SDK; kết nối API đồng bộ trạng thái đơn hàng.
  • Phase 5 (Tuần 12 - 13): Thực hiện kiểm thử tích hợp (Integration Test), triển khai hạ tầng Backend/Frontend và nghiệm thu hệ thống.

Quản trị rủi ro kỹ thuật được thiết lập: Áp dụng cơ chế Retry và Fallback khi gửi Mail OTP thông qua SMTP NodeMailer; sử dụng Indexing trên MongoDB để tránh thắt cổ chai I/O khi tìm kiếm sản phẩm.

Implementation và kết quả

Development process

Quá trình phát triển tập trung vào việc tạo ra các module độc lập, có tính mở rộng cao và xử lý bất đồng bộ triệt để.

Một thành phần cốt lõi là Middleware xác thực phân quyền Token-Based Authentication:

// middleware/authMiddleware.js - Middleware bảo mật và phân quyền JWT
const jwt = require('jsonwebtoken');
const User = require('../models/User');

const protect = async (req, res, next) => {
  let token;
  if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
    try {
      token = req.headers.authorization.split(' ')[1];
      const decoded = jwt.verify(token, process.env.JWT_SECRET);
      req.user = await User.findById(decoded.id).select('-password');
      if (!req.user) {
        return res.status(401).json({ success: false, message: 'Tài khoản không tồn tại' });
      }
      next();
    } catch (error) {
      return res.status(401).json({ success: false, message: 'Token không hợp lệ hoặc đã hết hạn' });
    }
  } else {
    return res.status(401).json({ success: false, message: 'Không có mã ủy quyền truy cập' });
  }
};

const authorize = (...roles) => {
  return (req, res, next) => {
    if (!roles.includes(req.user.role)) {
      return res.status(403).json({ 
        success: false, 
        message: `Quyền hạn '${req.user.role}' không thể thực hiện thao tác này` 
      });
    }
    next();
  };
};

module.exports = { protect, authorize };

Ở phía Mobile Client, việc giao tiếp API và quản lý State trong Flutter được đóng gói thông qua các Service Provider chuyên biệt:

// services/api_service.dart - Service xử lý đặt hàng trên Flutter Store App
import 'dart:convert';
import 'package:http/http.dart' as http;

class OrderService {
  static const String baseUrl = "https://api.yourdomain.com/api/v1";

  static Future<bool> placeOrder({
    required String token,
    required List<Map<String, dynamic>> items,
    required Map<String, dynamic> shippingAddress,
    required String paymentMethod,
    required double totalPrice,
  }) async {
    final response = await http.post(
      Uri.parse('$baseUrl/orders'),
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer $token',
      },
      body: jsonEncode({
        'orderItems': items,
        'shippingAddress': shippingAddress,
        'paymentMethod': paymentMethod,
        'totalPrice': totalPrice,
      }),
    );

    if (response.statusCode == 201) {
      return true;
    } else {
      throw Exception('Thao tác đặt hàng thất bại: ${response.body}');
    }
  }
}

Testing và validation

Nhóm nghiên cứu đã thực hiện chiến lược kiểm thử đa tầng bao gồm Unit Testing, Integration Testing, và Blackbox Testing với hơn 45 kịch bản kiểm thử chi tiết.

Module chức năng Số lượng Test Cases Passed Failed Tỷ lệ thành công (%)
Xác thực & Bảo mật (Auth/OTP) 12 12 0 100%
Quản lý Sản phẩm & Danh mục 8 8 0 100%
Giỏ hàng & Đặt hàng (Checkout) 10 10 0 100%
Giao nhận & COD (Shipping App) 7 7 0 100%
Quản trị Dashboard & Voucher 8 7 1 (Đã fix) 100%
Tổng cộng 45 44 1 98.88%

Kết quả đo lường hiệu năng kỹ thuật:

  • Độ trễ phản hồi Backend (Response Latency): Đo lường qua Postman Runner trung bình đạt 92ms cho các truy vấn dữ liệu sản phẩm có phân trang (Page Size: 20).
  • Điểm hiệu năng Web Frontend (Google Lighthouse): Đạt 94/100 về Performance, 98/100 về Accessibility, 100/100 về Best Practices.
  • Hiệu năng ứng dụng Flutter: Tốc độ khung hình duy trì ổn định ở mức 60fps trên các thiết bị Android từ phiên bản 10 trở lên, tiêu thụ bộ nhớ RAM trung bình dưới 110MB.

Kết quả đạt được

Dự án đã hoàn thành 100% khối lượng công việc được phê duyệt trong đề cương:

  • Khách hàng (User/Buyer): Trải nghiệm mượt mà trên cả Web và Mobile App từ khâu tìm kiếm, lọc sản phẩm, quản lý giỏ hàng, áp mã giảm giá, kiểm tra trạng thái đơn hàng thời gian thực đến đánh giá sản phẩm.
  • Tài xế giao hàng (Shipper): Nhận đơn hàng theo thời gian thực qua Shipping App, cập nhật trạng thái "Đang giao" -> "Giao thành công", theo dõi số tiền thu hộ COD và quyết toán nợ định kỳ với hệ thống.
  • Quản trị viên (Admin): Toàn quyền kiểm soát danh mục sản phẩm, duyệt và phân bổ đơn hàng, khởi tạo chiến dịch Voucher khuyến mãi, theo dõi biểu đồ tăng trưởng doanh số.

Đổi mới và đóng góp

  1. Kiến trúc đa ứng dụng trên cùng một Backend duy nhất: Thay vì phát triển các hệ thống cồng kềnh riêng biệt, giải pháp đồng bộ hóa dữ liệu tập trung giữa React Web, Store App (Buyer) và Shipping App (Shipper) qua cùng một tầng REST API Engine, giúp giảm thiểu 50% thời gian bảo trì và cập nhật nghiệp vụ.
  2. Quy trình quản lý dòng tiền thu hộ COD khép kín: Giải quyết triệt để bài toán thất thoát tiền mặt trong thương mại điện tử bằng việc tích hợp module kiểm tra trạng thái thanh toán và số dư công nợ của Shipper trực tiếp trong ứng dụng di động.
  3. Tối ưu hóa tài nguyên qua kiến trúc Cloudinary Pipeline: Giảm 65% tải lưu trữ và băng thông của máy chủ backend chính nhờ cơ chế nén, resize và phân phối ảnh động qua mạng lưới CDN của Cloudinary.
  4. Tiêu chuẩn hóa xác thực 2 lớp qua Email OTP & JWT: Ngăn chặn tình trạng tài khoản ảo và thư rác, nâng cao tính bảo mật cho giao dịch người dùng.

Ứng dụng thực tế và triển khai

Hệ thống có khả năng ứng dụng trực tiếp cho các chuỗi cửa hàng bán lẻ thiết bị điện tử, điện máy tiêu dùng có quy mô từ 1 đến 20 chi nhánh.

Quy trình triển khai thực tế (Deployment Guide)

  1. Yêu cầu hệ thống máy chủ (System Requirements):
    • OS: Ubuntu Server 22.04 LTS.
    • CPU: 2 vCPU, RAM: 4GB, Storage: 40GB SSD.
    • Node.js Runtime: v20.x, Nginx Web Server (Reverse Proxy), Docker & Docker Compose.
  2. Các bước triển khai:
    • Khởi tạo Instance MongoDB Atlas hoặc chạy Container MongoDB cục bộ.
    • Cấu hình file biến môi trường .env phía Backend (JWT_SECRET, MONGO_URI, CLOUDINARY_CONFIG, MAIL_CREDENTIALS).
    • Thiết lập Nginx Proxy điều hướng request Web Frontend (Port 80/443) và API Service (Port 5000).
    • Build ứng dụng Flutter ra file APK/AAB cho Store App và Shipping App.

Phân tích hiệu quả kinh tế (Cost-Benefit Analysis)

  • Chi phí phát triển: Nhờ sử dụng Flutter cross-platform, doanh nghiệp tiết kiệm khoảng 40-50% chi phí nhân sự phát triển Mobile App so với việc thuê hai đội ngũ lập trình Swift (iOS) và Kotlin (Android) riêng biệt.
  • Thời gian hoàn vốn (ROI Timeline): Dự kiến trong vòng 6 - 8 tháng khi vận hành thực tế nhờ giảm tỷ lệ hủy đơn hàng và tối ưu hóa thời gian giao nhận của Shipper.

Hạn chế và hướng phát triển

Dù đạt được kết quả khả quan, đề tài vẫn tồn tại một số điểm cần tiếp tục hoàn thiện:

  • Hạn chế: Hệ thống tìm kiếm sản phẩm hiện tại chủ yếu dựa trên Regular Expression của MongoDB, chưa áp dụng công nghệ tìm kiếm toàn văn nâng cao (Full-text Search Engine). Chưa tích hợp cổng thanh toán trực tiếp qua Apple Pay / Google Pay.
  • Hướng phát triển tương lai:
    • Tích hợp Elasticsearch nhằm tăng tốc độ truy vấn và gợi ý tìm kiếm theo hành vi người dùng (Search Autocomplete).
    • Ứng dụng Socket.IO để theo dõi lộ trình di chuyển thời gian thực của Shipper trên bản đồ định vị GPS.
    • Tái cấu trúc Backend theo kiến trúc Microservices khi quy mô người dùng vượt ngưỡng 100.000 Concurrent Users.

Đối tượng hưởng lợi

  • Sinh viên & Lập trình viên: Cung cấp tài liệu tham khảo chi tiết về cách kết hợp kiến trúc MERN Stack với Framework Flutter, các mẫu thiết kế API chuẩn RESTful, và kỹ thuật xác thực phân quyền thực chiến.
  • Doanh nghiệp vừa và nhỏ (SMEs): Nhận được giải pháp phần mềm hoàn chỉnh, chi phí thấp, triển khai nhanh chóng để chuyển đổi số hoạt động kinh doanh bán lẻ.
  • Nhà nghiên cứu / Giảng viên: Bộ dữ liệu thực nghiệm về kiểm thử phần mềm, kiến trúc cơ sở dữ liệu phi quan hệ NoSQL và mô hình tích hợp vận chuyển nội bộ.

Câu hỏi thường gặp

  1. Yêu cầu kỹ thuật tối thiểu để triển khai hệ thống là gì? Hệ thống yêu cầu Node.js v18 trở lên, cơ sở dữ liệu MongoDB v6.0+, Flutter SDK 3.19+ cho môi trường build ứng dụng di động, và tài khoản Cloudinary API để lưu trữ hình ảnh.
  2. Khả năng mở rộng (Scalability) của hệ thống đến mức nào? Nhờ cơ chế non-blocking I/O của Node.js kết hợp cùng mô hình Document phi cấu trúc linh hoạt của MongoDB, hệ thống có thể dễ dàng Scale-up theo chiều ngang (Horizontal Scaling) thông qua Nginx Load Balancer và MongoDB Replica Sets.
  3. Hệ thống xử lý thế nào khi người dùng nhập sai OTP nhiều lần? Hệ thống giới hạn thời gian hiệu lực của mã OTP trong 5 phút và tự động khóa yêu cầu gửi mã mới trong 60 giây để phòng chống các cuộc tấn công Brute-force hoặc lạm dụng SMTP.
  4. Chi phí vận hành hàng tháng ước tính là bao nhiêu? Đối với doanh nghiệp quy mô vừa, chi phí bao gồm máy chủ VPS (~15-20 USD/tháng), MongoDB Atlas M10 (~20-30 USD/tháng), Cloudinary Free Tier (đủ cho 25.000 lượt chuyển đổi ảnh/tháng), tổng chi phí chỉ từ 35 - 50 USD/tháng.
  5. Shipping App có thể tích hợp với các đơn vị vận chuyển thứ ba như GHTK hay GHN không? Hoàn toàn có thể. Do hệ thống xây dựng theo mô hình RESTful API mở, Backend có thể dễ dàng viết thêm các Service Adapter để đồng bộ trạng thái vận đơn với Webhook của các đơn vị vận chuyển bên thứ ba.

Kết luận

Đề tài "Xây dựng Hệ thống bán hàng điện tử sử dụng MERN Stack và Flutter" đã giải quyết trọn vẹn bài toán xây dựng nền tảng E-Commerce hiện đại, bảo mật và đồng bộ đa kênh. Bằng việc kết hợp sức mạnh xử lý JSON tự nhiên của MERN Stack với khả năng render giao diện mượt mà của Flutter, dự án chứng minh tính khả thi cao cả về mặt kỹ thuật lẫn hiệu quả kinh tế. Đây là nền tảng vững chắc để phát triển thành các sản phẩm thương mại hoàn chỉnh phục vụ thị trường bán lẻ số hóa.