Tất cả tài liệu
Self-Host & Kỹ Thuật8 phút đọc

Tài liệu API

Các endpoint công khai, tham số, giới hạn tần suất và mã lỗi thực tế.

Quy ước chung

  • Tất cả request và response dùng JSON.
  • Response thành công có dạng { success: true, data: {...}, timestamp }.
  • Response lỗi có dạng { success: false, error: "...", timestamp }.
  • Mọi endpoint đều bị giới hạn tần suất; vượt ngưỡng trả về mã 429.

POST /api/leads — Ghi nhận khách tiềm năng

Giới hạn 10 request mỗi giờ cho mỗi địa chỉ IP. Endpoint này kích hoạt gửi email nên ngưỡng đặt thấp có chủ đích.

Người nhận email thông báo luôn lấy từ cấu hình máy chủ, không bao giờ lấy từ nội dung request — đây là biện pháp chống lạm dụng để phát tán thư rác.

TrườngKiểuBắt buộcGhi chú
namestringTối đa 120 ký tự
phonestring6–20 ký tự
emailstringKhôngPhải đúng định dạng email nếu có
formTypestringKhôngDùng để phân loại nguồn
selectedPackagestringKhôngGói khách quan tâm
notesstringKhôngTối đa 2000 ký tự

POST /api/checkout — Tạo đơn hàng

Trả về orderId, statusToken, qrUrl và transferContent. Giới hạn 10 request mỗi phút cho mỗi IP.

statusToken là chìa khoá để tra cứu trạng thái đơn — giữ ở phía trình duyệt của người mua, không ghi vào log.

TrườngKiểuBắt buộc
productNamestring
priceVndnumber nguyên dương
customerPhonestring
customerEmailstring (email)
customerNamestringKhông
packageTypestringKhông

GET /api/checkout/status — Tra cứu trạng thái

Bắt buộc có cả orderId và token. Thiếu token trả về 400.

Mã đơn chỉ có 4 chữ số nên bản thân nó không đủ bảo vệ; token mới là thứ chứng minh quyền truy cập. Token được so sánh theo cách không rò rỉ thời gian.

Ví dụ
GET /api/checkout/status?orderId=LEXI-1234&token=<statusToken>

# Chưa thanh toán
{ "success": true, "data": { "status": "PENDING_PAYMENT" } }

# Đã thanh toán
{ "success": true, "data": { "status": "PAID_AND_FULFILLED", "fulfilledOrder": { ... } } }

POST /api/webhooks/sepay — Đối soát thanh toán

Endpoint dành cho cổng thanh toán gọi vào, không dành cho ứng dụng của bạn.

  • Bắt buộc kèm bí mật ở header Authorization hoặc x-sepay-secret.
  • Máy chủ chưa cấu hình SEPAY_WEBHOOK_SECRET sẽ từ chối mọi request với mã 500 — không có chế độ chạy không xác thực.
  • Sai bí mật trả về 401.
  • Mỗi mã giao dịch ngân hàng chỉ được xử lý một lần; gọi lại cùng mã trả về reconciled: false.
  • Số tiền phải bằng hoặc lớn hơn giá đơn hàng đã lưu, nếu không đơn chuyển sang diện đối soát thủ công.

POST /api/approval-gate — Đánh giá cấp rủi ro

  • actionType chỉ nhận 4 giá trị: EMAIL_BULK, FINANCIAL_TRANSACTION, SYSTEM_DEPLOYMENT, SOCIAL_PUBLISH. Giá trị khác trả về 422.
  • riskLevel là số nguyên 1–6.
  • Cấp 1–2 tự động duyệt, 3–4 duyệt qua Zalo, 5–6 duyệt qua Telegram.
Ví dụ
POST /api/approval-gate
{
  "actionType": "FINANCIAL_TRANSACTION",
  "riskLevel": 3
}

{
  "success": true,
  "data": {
    "riskLevel": 3,
    "status": "PENDING_HUMAN_APPROVAL",
    "requiresApproval": true,
    "approvalChannel": "ZALO"
  }
}

GET /api/ai-employees/scenarios — Danh mục kịch bản

Trả về danh sách kịch bản demo kèm chỉ tiêu độ trễ và tỉ lệ xử lý ngay lần đầu. Không yêu cầu xác thực, dùng cho trang giới thiệu.

Mã lỗi

Ý nghĩaCách xử lý
400Thiếu tham số bắt buộcKiểm tra lại tham số trên URL
401Sai bí mật xác thựcĐối chiếu lại giá trị bí mật hai đầu
404Tính năng chưa bật trên máy chủ nàyKiểm tra biến môi trường tương ứng
422Dữ liệu không hợp lệĐọc trường error để biết tên trường sai
429Vượt giới hạn tần suấtChờ hết cửa sổ thời gian rồi thử lại
500Máy chủ chưa cấu hình hoặc lỗi nội bộKiểm tra nhật ký ứng dụng
Bài tiếp theo

Nhật ký thay đổi