Kiến trúc kết nối Website thương mại điện tử với ERPNext: đồng bộ Item, Price List, Sales Order và Stock Ledger
Kết nối Website thương mại điện tử với ERPNext đòi hỏi kiến trúc đồng bộ hai chiều thông qua giao thức Frappe REST API và cơ chế Webhook sự kiện. Thay vì truy vấn trực tiếp vào cơ sở dữ liệu MariaDB của ERPNext gây nghẽn khóa bảng khi lưu lượng truy cập tăng cao, website lưu trữ bộ nhớ đệm danh mục sản phẩm (Item), bảng giá (Price List) và tồn kho khả dụng từ sổ cái kho (Stock Ledger Entry). Khi phát sinh giao dịch, đơn hàng được đẩy bất đồng bộ qua hàng đợi vào Sales Order.
ERPNext (trên nền tảng Frappe Framework) được nhiều doanh nghiệp sản xuất và bán lẻ tại Việt Nam lựa chọn nhờ mã nguồn mở linh hoạt cùng quy trình kế toán - kho vận chặt chẽ. Tuy nhiên, module bán hàng có sẵn của ERPNext khó đáp ứng yêu cầu tùy biến giao diện và tốc độ tải trang Core Web Vitals, nên xây dựng website độc lập kết nối với ERPNext là giải pháp bền vững.
1. Đặc thù kiến trúc DocType của Frappe/ERPNext và bài toán phân tách tải với Website TMĐT
Trong hệ sinh thái ERPNext, mọi thực thể nghiệp vụ từ hàng hóa, bảng giá, khách hàng cho tới đơn bán hàng và bút toán kho đều được định nghĩa dưới dạng DocType lưu trữ trên hệ quản trị cơ sở dữ liệu MariaDB (hoặc PostgreSQL). Điểm mạnh của ERPNext là tính ràng buộc toàn vẹn: mỗi khi một chứng từ được xác nhận (Submit), hàng loạt sự kiện kiểm tra tồn kho, hạn mức công nợ và hạch toán sổ cái kế toán (GL Entry) sẽ chạy đồng bộ trong cùng một giao dịch cơ sở dữ liệu.
Chính cơ chế kiểm tra nghiêm ngặt này lại trở thành điểm nghẽn nếu doanh nghiệp để giao diện Website thương mại điện tử gọi trực tiếp vào API của ERPNext ở mỗi lượt tải trang sản phẩm. Khi có hàng nghìn người dùng cùng lúc xem trang danh mục hoặc lọc sản phẩm, việc truy vấn trực tiếp vào bảng tabItem, tabItem Price và tabBin của ERPNext sẽ làm tăng tải CPU máy chủ ERP, gây chậm trễ cho bộ phận kế toán, thu mua và kho vận đang làm việc nội bộ.
Do đó, nguyên tắc cốt lõi khi thiết kế tích hợp là tách biệt hoàn toàn lớp hiển thị và đọc dữ liệu (Read Model) trên Website khỏi lớp xử lý giao dịch (Write/Transactional Model) của ERPNext. Website duy trì cơ sở dữ liệu riêng (PostgreSQL kết hợp bộ nhớ đệm Redis hoặc công cụ tìm kiếm Elasticsearch) để phục vụ người mua với độ trễ tính bằng mili giây, trong khi mọi thay đổi dữ liệu gốc từ ERPNext được đồng bộ sang Website qua cơ chế sự kiện.
- Sử dụng xác thực Token-based Authentication (API Key và API Secret gắn với tài khoản Service Account chuyên biệt trên ERPNext) thay vì dùng phiên đăng nhập Session Cookie dễ hết hạn.
- Phân quyền Role Permission Manager chặt chẽ cho tài khoản tích hợp: chỉ cấp quyền Đọc (Read) đối với Item, Item Price, Bin và quyền Tạo/Ghi (Create/Write) đối với Customer, Sales Order, Payment Entry.
- Giới hạn tần suất gọi API (Rate Limiting) và gom nhóm dữ liệu (Batching) khi đồng bộ danh mục lớn hàng chục nghìn mã SKU để tránh làm tràn hàng đợi Redis Queue (RQ) nội bộ của Frappe.
2. Ánh xạ cấu trúc dữ liệu (Data Mapping): Item, Price List, Bin và Sales Order
Để hai hệ thống nói cùng một ngôn ngữ dữ liệu, đội ngũ kỹ thuật cần thiết lập bảng ánh xạ định danh duy nhất (Master ID Mapping) giữa các thực thể trên ERPNext và cấu trúc bảng trên Website. Sai lầm thường gặp là dùng tên sản phẩm hoặc đường dẫn tĩnh (Slug) làm khóa đối chiếu; khi nhân sự ngành hàng đổi tên hiển thị chuẩn SEO trên web, liên kết đồng bộ sẽ bị đứt gãy ngay lập tức.
Đối với sản phẩm có nhiều biến thể (như quần áo phân theo màu sắc, kích cỡ hoặc thiết bị công nghiệp phân theo công suất), ERPNext quản lý thông qua mô hình Item Template (has_variants = 1) và các Item Variant con kế thừa thuộc tính từ bảng Item Variant Attribute. Khi đồng bộ sang Website, cấu trúc này cần được chuyển đổi nguyên vẹn thành mô hình Sản phẩm cha (Configurable/Variable Product) và các mã SKU con để bộ chọn thuộc tính trên trang chi tiết hoạt động mượt mà.
Về giá bán và tồn kho, ERPNext không lưu một mức giá cố định bên trong bảng Item mà tách riêng sang DocType Item Price gắn với từng Price List (Bảng giá bán lẻ, Bảng giá đại lý cấp 1, Bảng giá khuyến mại theo thời gian) và Pricing Rule (Quy tắc chiết khấu theo số lượng hoặc nhóm khách hàng). Tương tự, số lượng tồn kho thực tế nằm ở sổ cái Stock Ledger Entry và được tổng hợp nhanh tại bảng tabBin theo từng kho (Warehouse).
| Thực thể trên ERPNext (DocType) | Thực thể tương ứng trên Website TMĐT | Chiều đồng bộ chuẩn | Trường dữ liệu và quy tắc xử lý trọng tâm |
|---|---|---|---|
| Item & Item Group | Product, Product Variant & Category | ERPNext -> Website (Webhook / Cron) | Đồng bộ mã item_code làm khóa chính, thuộc tính biến thể, đơn vị tính (UOM), trọng lượng và cờ cho phép bán trên web. |
| Item Price & Pricing Rule | Price Tier, Discount Rule & Promotion | ERPNext -> Website (Theo sự kiện) | Lọc theo bảng giá bán lẻ hoặc bảng giá B2B, áp dụng thời hạn hiệu lực valid_from, valid_upto và bậc số lượng tối thiểu. |
| Bin & Stock Ledger Entry | Inventory Stock & Warehouse Allocation | ERPNext -> Website (Thời gian thực) | Lấy chỉ số projected_qty hoặc tính toán actual_qty trừ đi reserved_qty tại các kho được cấu hình cho phép bán trực tuyến. |
| Customer & Address | User Account, B2B Profile & Shipping Address | Hai chiều (Bi-directional) | Đối chiếu qua số điện thoại hoặc mã số thuế doanh nghiệp; tự động khởi tạo Customer mới nếu khách đặt hàng lần đầu. |
| Sales Order & Sales Invoice | Order, Order Line Items & Tax Invoice Info | Website -> ERPNext (Qua Message Queue) | Chuyển chi tiết dòng hàng, phí vận chuyển (Shipping Rule), mã giảm giá và trạng thái thanh toán sang chứng từ Sales Order. |
| Payment Entry | Payment Transaction Log | Website -> ERPNext (Tự động khi thu tiền) | Tự động lập phiếu thu Payment Entry tham chiếu tới Sales Order ngay khi cổng thanh toán trực tuyến báo giao dịch thành công. |
3. Thiết kế luồng đồng bộ tồn kho từ Stock Ledger và quy trình đẩy Sales Order bất đồng bộ
Trong vận hành thực tế, bài toán khó xử lý nằm ở độ trễ cập nhật tồn kho giữa lúc nhân viên kho xuất/nhập hàng trên ERPNext và lúc khách hàng bấm nút thanh toán trên Website. Trên ERPNext, bảng tabBin lưu trữ ba chỉ số quan trọng cho mỗi cặp Sản phẩm - Kho hàng: actual_qty (tồn kho vật lý thực tế trong kho), reserved_qty (số lượng đã nằm trong các Sales Order đã duyệt nhưng chưa xuất kho Delivery Note) và projected_qty (số lượng dự kiến).
Công thức chuẩn để hiển thị số lượng có thể bán (Available to Promise - ATP) trên Website là lấy tổng actual_qty - reserved_qty của riêng các kho hàng được chỉ định phục vụ kênh trực tuyến (bỏ qua kho hàng lỗi, kho bảo hành hoặc kho nguyên vật liệu). Mỗi khi trên ERPNext phát sinh sự kiện xác nhận phiếu nhập kho (Purchase Receipt), phiếu xuất giao hàng (Delivery Note) hoặc kiểm kê kho (Stock Reconciliation), một Hook sự kiện on_submit và on_cancel trong Frappe sẽ bắn gói tin JSON qua Webhook sang lớp nhận của Website để cập nhật lại bộ nhớ đệm tồn kho trong vòng vài giây.
Ở chiều ngược lại, khi khách hàng hoàn tất đặt hàng trên Website, hệ thống web không bắt người dùng phải chờ ERPNext tạo xong chứng từ Sales Order mới hiển thị trang cảm ơn. Thay vào đó, Website ghi nhận đơn hàng vào cơ sở dữ liệu cục bộ, trừ tạm số lượng tồn kho trên Redis và đẩy sự kiện order.created vào hàng đợi thông điệp (như RabbitMQ hoặc BullMQ). Tiến trình Worker chạy ngầm sẽ gọi Frappe REST API (POST /api/resource/Sales Order) để tạo chứng từ trên ERPNext, điền đầy đủ bảng con items, bảng thuế taxes và điều khoản thanh toán.
- Thiết lập khóa chống trùng lặp (Idempotency Key) bằng cách lưu mã đơn hàng của Website vào trường tùy chỉnh custom_web_order_id (Unique) trên DocType Sales Order của ERPNext, ngăn chặn tình trạng mạng chập chờn khiến Worker gửi lại tạo ra hai đơn hàng trùng nhau.
- Tách bạch phí vận chuyển và chiết khấu: trên ERPNext, phí giao hàng cần được ánh xạ vào bảng Sales Taxes and Charges (với loại Actual gắn tài khoản doanh thu/chi phí vận chuyển) thay vì tạo thành một mã sản phẩm ảo làm sai lệch báo cáo nhập xuất tồn.
- Tự động hóa luồng trạng thái: khi bộ phận kho hoàn tất đóng gói và xác nhận Delivery Note trên ERPNext, Webhook sẽ gọi ngược về Website để chuyển trạng thái đơn hàng sang Đang giao kèm theo mã vận đơn tra cứu.
4. Xử lý lỗi bất đồng bộ, đối soát dữ liệu định kỳ và bảo mật kênh truyền
Không một hệ thống tích hợp mạng nào miễn nhiễm hoàn toàn với sự cố đứt kết nối tạm thời, máy chủ ERPNext bảo trì nâng cấp phiên bản hoặc dữ liệu đầu vào vi phạm quy tắc nghiệp vụ (ví dụ: mã sản phẩm vừa bị khóa trạng thái disabled = 1 trên ERPNext đúng lúc khách trên web bấm thanh toán). Nếu không có cơ chế phòng vệ, những đơn hàng này sẽ bị rơi vào trạng thái thất lạc giữa hai hệ thống, gây bức xúc cho khách mua và làm lệch báo cáo doanh thu.
Để kiểm soát rủi ro, kiến trúc tích hợp cần trang bị cơ chế thử lại theo cấp số nhân (Exponential Backoff Retry) kết hợp với hàng đợi thư chết (Dead-Letter Queue - DLQ). Khi API của ERPNext trả về mã lỗi máy chủ bận (HTTP 502/503/504) hoặc lỗi khóa bảng (QueryTimeoutError), tiến trình Worker sẽ tự động thử gửi lại sau 5 giây, 30 giây, 2 phút và 10 phút. Ngược lại, nếu gặp lỗi logic dữ liệu (HTTP 400/417 Expectation Failed do Frappe trả về như thiếu trường bắt buộc hoặc kỳ kế toán đã đóng), hệ thống dừng thử lại ngay và đẩy thông báo cảnh báo kèm toàn bộ nội dung gói tin JSON lên bảng điều khiển quản trị để nhân viên vận hành xử lý thủ công.
Bên cạnh luồng đồng bộ thời gian thực qua Webhook, doanh nghiệp cần thiết lập một tác vụ đối soát định kỳ (Reconciliation Cronjob) chạy vào khung giờ thấp điểm ban đêm. Tác vụ này sẽ so sánh tổng số đơn hàng phát sinh trong ngày trên Website với danh sách Sales Order trên ERPNext, đồng thời quét lại toàn bộ bảng tabBin để đồng bộ hóa lại tồn kho một lần nữa, triệt tiêu hoàn toàn sai số tích lũy do các gói tin Webhook bị rớt trong ngày.
- Bảo mật kênh truyền bằng chữ ký số HMAC-SHA256 trong phần Header (X-Frappe-Webhook-Signature) cho mọi yêu cầu Webhook xuất phát từ ERPNext, chỉ chấp nhận các gói tin được ký bằng khóa bí mật chung giữa hai máy chủ.
- Xây dựng giao diện Sync Log ngay trên trang quản trị Website hoặc một DocType Integration Error Log tùy chỉnh trên ERPNext, cho phép quản trị viên bấm nút Đồng bộ lại (Manual Retry) cho từng đơn hàng sau khi đã điều chỉnh dữ liệu gốc.
- Thực hiện kiểm thử chịu tải (Load Testing) riêng cho luồng đồng bộ trước các dịp khuyến mại lớn để xác định ngưỡng chịu đựng của các Background Worker trên Frappe và điều chỉnh số lượng tiến trình Gunicorn/RQ phù hợp.
Câu hỏi thường gặp
Giải đáp nhanh những điểm thương hiệu bán lẻ D2C, chuỗi cửa hàng đa chi nhánh, doanh nghiệp sản xuất – phân phối B2B và đơn vị xây dựng sàn giao dịch thương mại điện tử hay hỏi về chủ đề này.
Tại sao không dùng trực tiếp module E-commerce có sẵn trong ERPNext mà phải xây dựng Website riêng rồi kết nối API?
Module E-commerce mặc định của ERPNext phù hợp cho nhu cầu cổng đặt hàng nội bộ đơn giản nhưng bị phụ thuộc chặt vào cấu trúc kết xuất giao diện của Frappe, khó tối ưu tốc độ tải trang Core Web Vitals, hạn chế khả năng tùy biến trải nghiệm người dùng (UI/UX) theo ngành hàng và dễ làm lộ tải trực tiếp vào cơ sở dữ liệu ERP khi có lượng truy cập đột biến.
Khi ERPNext đang bảo trì hoặc nâng cấp phiên bản, khách hàng trên Website có đặt hàng bình thường được không?
Hoàn toàn bình thường nếu kiến trúc tích hợp sử dụng cơ chế bất đồng bộ qua Message Queue và lưu bộ nhớ đệm danh mục, tồn kho trên Website. Đơn hàng của khách vẫn được ghi nhận thành công trên web và xếp vào hàng đợi; ngay khi máy chủ ERPNext hoạt động trở lại, Worker sẽ tự động đẩy toàn bộ đơn hàng tồn đọng vào Sales Order mà không mất dữ liệu.
Làm thế nào để xử lý trường hợp khách hàng mua theo thùng hoặc lốc trên Website nhưng ERPNext quản lý tồn kho theo từng cái lẻ?
ERPNext hỗ trợ sẵn bảng quy đổi đa đơn vị tính (UOM Conversion Factor) trong từng Item. Khi đồng bộ sang Website, hệ thống sẽ lấy hệ số quy đổi (ví dụ: 1 Thùng = 24 Cái) để hiển thị tồn kho khả dụng tương ứng theo đơn vị khách chọn, đồng thời khi đẩy Sales Order về ERPNext sẽ truyền chính xác cả trường uom (Đơn vị mua) và conversion_factor để sổ cái kho tự động trừ đúng số lượng đơn vị gốc.
Nhận tư vấn kiến trúc & Báo giá chi tiết hệ thống Website Thương mại điện tử
Hãy cho Uptech biết mô hình bán hàng của bạn (B2C, B2B hay Đa kho/Sàn), số lượng mã sản phẩm (SKU) dự kiến và các phần mềm cổng thanh toán, vận chuyển, ERP/POS cần kết nối. Kỹ sư giải pháp của Uptech sẽ phân tích và gửi bản đề xuất kiến trúc kèm dự toán chi phí minh bạch trong 24 giờ làm việc.
- Phản hồi kèm sơ đồ kiến trúc đề xuất trong vòng 24 giờ làm việc
- Tư vấn miễn phí lộ trình đồng bộ tồn kho ERP/POS và cấu trúc SEO danh mục lớn
- Hợp đồng pháp nhân rõ ràng, bàn giao mã nguồn, xuất hóa đơn GTGT (VAT) đầy đủ