API Kết nối ISale
Tài liệu dành cho lập trình viên tích hợp ERP, website, POS và hệ thống bên thứ ba với iSale.
Tổng quan
External API cho phép hệ thống bên thứ ba (ERP, website, POS, chatbot…) đồng bộ dữ liệu với iSale qua API key, không dùng OAuth/Bearer nội bộ.
- Namespace:
/ext/v1/*— tách khỏi API app (/data/*, Bearer token). - Mỗi mã kết nối gắn với một shop (
tenantUserId); quyền theo danh sách permission gán trên mã. - Phase 1: quyền truy cập dữ liệu ở mức full shop (chưa áp OWD/row-scope CRM như staff).
↓
Services / DB (lọc theo shop)
Bắt đầu nhanh
- Đăng nhập iSale với tài khoản chủ shop hoặc nhân viên có quyền quản trị đầy đủ.
- Mở màn hình Kết nối phần mềm khác (
#/external-apitrong app). - Nhấn Tạo mã mới —
publicKeychỉ hiển thị một lần; lưu ngay nơi an toàn. - Chọn quyền tối thiểu cần thiết (accordion theo nhóm CRM, Bán hàng, Danh mục…).
- Gọi thử API với header
Authorization: Apikey <publicKey>.
Xác thực
Header bắt buộc
Authorization: Apikey <publicKey>
Mọi request tới /ext/v1/* phải có header trên. Key và client phải ở trạng thái active (status=1).
HMAC (tùy chọn — khuyến nghị production cho request ghi)
Áp dụng khi gửi ít nhất một header X-Timestamp, X-Nonce hoặc X-Signature trên POST/PUT/PATCH/DELETE:
X-Timestamp— unix ms, lệch tối đa ±5 phútX-Nonce— UUID, không được trùng trong cửa sổX-Signature— HMAC-SHA256 hex (khóa hiện dùngpublicKey)
Mã lỗi thường gặp
| HTTP | code | Ý nghĩa |
|---|---|---|
| 401 | unauthorized | Thiếu/sai Apikey hoặc key đã thu hồi |
| 403 | forbidden | Thiếu permission (ví dụ crm.leads.read) |
| 429 | rate_limit_exceeded | Vượt giới hạn tần suất |
Response có thể kèm header X-Request-Id để tra audit log phía shop.
Quy ước chung
Base URL: https://api2.isale.online (cấu hình production; không có dấu / cuối).
Versioning: prefix /ext/v1. Breaking change sẽ tăng version (/ext/v2).
Định dạng lỗi
{
"error": {
"code": "invalid_request",
"message": "Missing required field: fullName",
"details": { "field": "fullName" }
}
}
Phân trang
limit— mặc định 50, tối đa 200 (áp dụng trên nhiều endpoint list).- Một số API hỗ trợ
idđể lọc/lấy từ bản ghi cụ thể (xem từng module).
Ví dụ kiểm tra kết nối
curl -s -H "Authorization: Apikey YOUR_PUBLIC_KEY" \
"https://api2.isale.online/ext/v1/crm/leads?limit=5"
Phân quyền
Gán quyền trên app Kết nối phần mềm khác. Mỗi endpoint yêu cầu permission tương ứng; thiếu quyền trả 403.
/ext/v1/data/tables/{table}/records dùng permission theo từng bảng hoặc umbrella data.tables.read / data.tables.write.
CRM
Leads
| Method | Path | Permission | Query / body |
|---|---|---|---|
| GET | /ext/v1/crm/leads | crm.leads.read | q, ownerStaffId, status, limit, id |
| GET | /ext/v1/crm/leads/{id} | crm.leads.read | — |
| POST | /ext/v1/crm/leads | crm.leads.write | JSON: fullName (bắt buộc), mobile, email, … |
curl -X POST "https://api2.isale.online/ext/v1/crm/leads" \
-H "Authorization: Apikey YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"fullName":"Lead từ website","mobile":"0901234567","source":"website"}'
Contacts
| Method | Path | Permission |
|---|---|---|
| GET | /ext/v1/crm/contacts | crm.contacts.read |
| GET | /ext/v1/crm/contacts/{id} | crm.contacts.read |
| POST | /ext/v1/crm/contacts | crm.contacts.write |
| PATCH | /ext/v1/crm/contacts/{id} | crm.contacts.write |
Query list: limit, q (tìm theo tên, SĐT, email, mã).
Flows (automation)
| Method | Path | Permission |
|---|---|---|
| GET | /ext/v1/crm/flows | crm.flows.read |
| GET | /ext/v1/crm/flows/{id} | crm.flows.read |
| POST | /ext/v1/crm/flows | crm.flows.write |
| GET | /ext/v1/crm/flows/{flowId}/runs | crm.flows.read |
| GET | /ext/v1/crm/flow-runs/{runId} | crm.flows.read |
Bán hàng
| Method | Path | Permission | Ghi chú |
|---|---|---|---|
| GET | /ext/v1/sales/orders | sales.orders.read | dateFrom, dateTo, contactId, staffId, storeId, status |
| GET | /ext/v1/sales/orders/{id} | sales.orders.read | — |
| POST | /ext/v1/sales/orders | sales.orders.write | Tạo đơn |
| PATCH | /ext/v1/sales/orders/{id} | sales.orders.write | Cập nhật đơn |
curl -s -H "Authorization: Apikey YOUR_KEY" \
"https://api2.isale.online/ext/v1/sales/orders?dateFrom=2026-06-01&dateTo=2026-06-30"
Danh mục sản phẩm
| Method | Path | Permission | Query |
|---|---|---|---|
| GET | /ext/v1/catalog/products | catalog.products.read | storeId, categoryId, isMaterial |
| GET | /ext/v1/catalog/products/{id} | catalog.products.read | storeId |
| POST | /ext/v1/catalog/products | catalog.products.write | — |
| PATCH | /ext/v1/catalog/products/{id} | catalog.products.write | — |
Lịch
| Method | Path | Permission | Query |
|---|---|---|---|
| GET | /ext/v1/calendar/events | calendar.read | staffId, contactId, id, limit |
| GET | /ext/v1/calendar/events/{id} | calendar.read | — |
| POST | /ext/v1/calendar/events | calendar.write | — |
| PATCH | /ext/v1/calendar/events/{id} | calendar.write | — |
Bảng dữ liệu (generic)
API đọc/ghi các bảng standard_table trong whitelist. Không thay thế API chuyên biệt cho contact, product, order, calendar, lead, flow.
| Method | Path | Permission |
|---|---|---|
| GET | /ext/v1/data/tables | Quyền đọc ít nhất một bảng / data.tables.read |
| GET | /ext/v1/data/tables/{table}/records | Đọc theo bảng |
| GET | /ext/v1/data/tables/{table}/records/{id} | Đọc theo bảng |
| POST | /ext/v1/data/tables/{table}/records | Ghi theo bảng (nếu bảng cho phép write) |
Query: limit, id. Mọi bản ghi lọc theo userId của shop.
Bảng đọc được (whitelist)
store, staff, note, debt, quote, trade, trade_category, sales_line, business_type, money_account, transfer_note, received_note, level_config, shift_log, product_attribute, product_type, product_attribute_quantity, custom_table, custom_table_data, crm_task, crm_deal, crm_deal_item, crm_deal_stage, crm_pipeline
Bảng ghi được
store, note, debt, quote, trade, sales_line, business_type, money_account, transfer_note, received_note, custom_table_data
contact, product, order, calendar, crm_lead, crm_flow… dùng API chuyên biệt ở các mục trên.
Rate limit
Áp dụng cho mọi request /ext/*. Vượt ngưỡng trả 429 kèm Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining.
| Giới hạn | Mặc định (production) | Cửa sổ |
|---|---|---|
| Theo IP | 120 request | 60 giây |
| Theo API key | 300 request | 60 giây |
| Ghi (POST/PUT/PATCH/DELETE) / key | 60 request | 60 giây |
{
"error": {
"code": "rate_limit_exceeded",
"message": "...",
"retryAfterSeconds": 42
}
}
Đếm theo từng instance API (memory). Môi trường dev thường tắt rate limit.
Bảo mật & vận hành
- Chỉ cấp quyền tối thiểu cho từng đối tác tích hợp.
- Thu hồi mã ngay khi nghi ngờ lộ — trên app Kết nối phần mềm khác.
- Không log
publicKeytrong log ứng dụng phía bạn. - Production: khuyến nghị bật HMAC cho mọi request ghi.
- Dữ liệu luôn scoped theo shop của mã — không truy cập chéo tenant.
Chủ shop xem audit log qua API nội bộ (Bearer): GET /external-integration/audit-logs?limit= — không dùng External API key.
OpenAPI / Swagger
Trang này là tài liệu tham khảo nhanh. Nếu cần schema chi tiết (model, field), mở Swagger document ext-v1:
https://api2.isale.online/swagger/index.html?urls.primaryName=ISale%20External%20API%20ext-v1