> For the complete documentation index, see [llms.txt](https://evotech-1.gitbook.io/evotech-open-api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://evotech-1.gitbook.io/evotech-open-api/readme.md).

# Giới thiệu

Tài liệu tích hợp dành cho đối tác kết nối vào hệ thống Evotech: đồng bộ sản phẩm, đơn hàng, khách hàng, điểm thành viên và nhận thông báo sự kiện qua Webhook.

## Kiến trúc tích hợp

Có hai chiều dữ liệu:

| Chiều                 | Cơ chế   | Mô tả                                                        |
| --------------------- | -------- | ------------------------------------------------------------ |
| **Đối tác → Evotech** | REST API | Đối tác chủ động gọi API để đọc/ghi dữ liệu                  |
| **Evotech → Đối tác** | Webhook  | Evotech gửi thông báo khi có sự kiện (đơn mới, tồn kho đổi…) |

## Base URL

```
https://<domain-cua-ban>/api/public/v1
```

Toàn bộ REST API nằm dưới tiền tố `/api/public/v1`. Webhook được quản lý qua khu vực quản trị (admin) của shop.

## Bắt đầu nhanh

1. **Lấy API Key**: Chủ shop vào **Cài đặt → API Keys** trong trang quản trị, tạo một key mới và chọn phạm vi quyền. Chuỗi key chỉ hiển thị ở màn hình vừa tạo — hãy sao chép và lưu lại ngay.
2. **Gọi thử**: Đính kèm key vào header `X-Webhook-Secret` mọi request. Xem [Xác thực](/evotech-open-api/authentication.md).
3. **Nhận sự kiện** (tuỳ chọn): Đăng ký Webhook endpoint để nhận thông báo real-time. Xem [Tổng quan Webhook](/evotech-open-api/webhook/webhooks.md).

```bash
curl https://<domain>/api/public/v1/items \
  -H "X-Webhook-Secret: <API_KEY_CUA_BAN>"
```

## Cách đọc tài liệu này

Mỗi nhóm chức năng là một thư mục, gồm:

* **Trang tổng quan** — khái niệm, cấu trúc response dùng chung và bảng lỗi của cả nhóm.
* **Một trang cho mỗi endpoint** — mô tả, tham số, ví dụ và lỗi riêng của endpoint đó.

Ba trang nền dùng chung cho mọi nhóm: [Xác thực & Giới hạn](/evotech-open-api/authentication.md), [Quy ước chung](/evotech-open-api/conventions.md) (định danh, phân trang, thời gian, cấu trúc response, mã HTTP) và [Giá trị hợp lệ](/evotech-open-api/enums.md).

## Nhóm tài nguyên

| Nhóm                                                               | Tiền tố                                  | Quyền                  |
| ------------------------------------------------------------------ | ---------------------------------------- | ---------------------- |
| [Sản phẩm](/evotech-open-api/rest-api/products.md)                 | `/items`                                 | `Items`                |
| [Tồn kho & Chi nhánh](/evotech-open-api/rest-api/inventory.md)     | `/items/{itemNo}/inventory`, `/branches` | `Inventory`            |
| [Danh mục](/evotech-open-api/rest-api/categories.md)               | `/category`                              | `Category`             |
| [Đơn hàng](/evotech-open-api/rest-api/orders.md)                   | `/order`                                 | `Orders`               |
| [Đơn hàng offline](/evotech-open-api/rest-api/offline-orders.md)   | `/offline-orders`                        | `Orders`               |
| [Khách hàng](/evotech-open-api/rest-api/customers.md)              | `/user`                                  | `Users`                |
| [Hạng thành viên](/evotech-open-api/rest-api/membership-levels.md) | `/membership-level`                      | `Users`                |
| [Tỉnh / phường](/evotech-open-api/rest-api/locations.md)           | `/locations`                             | Chỉ cần API Key hợp lệ |
| [Điểm thành viên](/evotech-open-api/rest-api/points.md)            | `/points`                                | `Points`               |
| [Voucher](/evotech-open-api/rest-api/voucher.md)                   | `/voucher`                               | `Vouchers`             |
| [Gửi thông báo Zalo](/evotech-open-api/rest-api/zalo.md)           | `/trigger-event`                         | `TriggerEvents`        |

## Nguyên tắc định danh

Mọi tài nguyên được định danh bằng **số thứ tự tăng dần theo shop** — gọn, dễ đọc, dễ tra cứu:

* Sản phẩm: `itemNo`, nhóm sản phẩm: `parentNo`
* Đơn hàng: `orderNo`
* Khách hàng: `userNo`
* Danh mục: `categoryNo`
* Hạng thành viên: `levelNo`
* Chi nhánh: `branchId` — **ngoại lệ duy nhất**, là chuỗi GUID chứ không phải số

Bạn nhận các số này trong response khi tạo/đọc dữ liệu, và dùng chúng cho mọi thao tác sau đó. Chi tiết ở [Quy ước chung](/evotech-open-api/conventions.md). Giá trị enum hợp lệ xem [tại đây](/evotech-open-api/enums.md).

> ⚠️ Dữ liệu tạo từ trước khi có cơ chế này có thể mang `No = 0` — đó không phải mã hợp lệ. Xem [cách xử lý](https://evotech-1.gitbook.io/evotech-open-api/pages/ZCEQDLslkhFRAoQ7qzkR#dữ-liệu-cũ-có-thể-có-no--0) trước khi viết code đồng bộ.

## Bản cập nhật gần đây

| Thay đổi                                                                                                                                                                                                                                                                                                                                                                             | Ảnh hưởng tới tích hợp cũ                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| [`GET /branches`](/evotech-open-api/rest-api/inventory/branches.md) nhận `search` (tìm theo tên) và `externalId` (tìm theo ID nguồn), response có thêm `externalId` / `externalSource`                                                                                                                                                                                               | Không phá vỡ — tham số và trường mới                                                                                         |
| [Khoá voucher](/evotech-open-api/rest-api/voucher/lock.md) `POST /voucher/lock`, [mở khoá](/evotech-open-api/rest-api/voucher/unlock.md) `POST /voucher/unlock` — giữ voucher lúc thanh toán, tạo đơn offline thì chuyển thành đã dùng                                                                                                                                               | Không phá vỡ — endpoint mới                                                                                                  |
| [Tạo đơn offline](/evotech-open-api/rest-api/offline-orders/create.md): nhận `orderNo` của bạn (chống tạo trùng), thêm `items[].price`, `amount`; bỏ `pointsEarned` — Evotech tự tính điểm cộng                                                                                                                                                                                      | `pointsEarned` gửi lên bị bỏ qua                                                                                             |
| Voucher: `usageStatus` cấp voucher ở [danh sách](/evotech-open-api/rest-api/voucher/list.md) / [chi tiết](/evotech-open-api/rest-api/voucher/detail.md), `scope` ở [voucher của khách](/evotech-open-api/rest-api/voucher/customer.md), [`GET /usages`](/evotech-open-api/rest-api/voucher/usages.md), webhook [nhóm Voucher](/evotech-open-api/webhook/webhooks/payload-voucher.md) | Không phá vỡ — trường, tham số và endpoint mới. `/voucher/customer` không gửi `scope` vẫn trả voucher còn dùng được          |
| [`GET /voucher/{voucherId}/codes`](/evotech-open-api/rest-api/voucher/codes.md) thêm trạng thái sử dụng (`usageStatus`, `usedCount`, `isUsable`, `lastOrderNo`…), bộ lọc và `summary`                                                                                                                                                                                                | Voucher dùng chung trả **mỗi khách một dòng** thay vì một dòng mã. `status` của mã theo voucher khi voucher đã tắt / hết hạn |
| Nhóm mới [Đơn hàng offline](/evotech-open-api/rest-api/offline-orders.md) `POST /offline-orders`, `PUT /offline-orders/{orderNo}`                                                                                                                                                                                                                                                    | Không phá vỡ — endpoint mới                                                                                                  |
| [Tra cứu thành viên tại quầy](/evotech-open-api/rest-api/customers/lookup.md) `POST /user/lookup` theo SĐT hoặc mã thành viên                                                                                                                                                                                                                                                        | Không phá vỡ — endpoint mới                                                                                                  |
| Danh mục [Tỉnh / phường](/evotech-open-api/rest-api/locations.md) `GET /locations/provinces`, `GET /locations/wards` (đơn vị hành chính 2 cấp)                                                                                                                                                                                                                                       | Không phá vỡ — endpoint mới                                                                                                  |
| Khách hàng có thêm `memberCode` (mã thành viên 12 số) trong response, webhook và bộ lọc `GET /user?memberCode=`                                                                                                                                                                                                                                                                      | Không phá vỡ — trường mới                                                                                                    |
| Tồn kho quản lý **theo chi nhánh**: object `inventory` trong response sản phẩm, nhóm endpoint [`/items/{itemNo}/inventory`](/evotech-open-api/rest-api/inventory.md) và [`GET /branches`](/evotech-open-api/rest-api/inventory/branches.md)                                                                                                                                          | Không phá vỡ. `quantity` / `quantityAvailable` vẫn được trả về như cũ                                                        |
| Quyền mới `Inventory` cho API Key                                                                                                                                                                                                                                                                                                                                                    | Key cũ **chưa có** quyền này — cần tick thêm mục **Tồn kho** nếu muốn ghi tồn qua API                                        |
| `POST /order` và `POST /items` nhận thêm `branchId`                                                                                                                                                                                                                                                                                                                                  | Không bắt buộc. Bỏ trống thì hệ thống chọn chi nhánh như trước                                                               |
| Webhook `inventory.updated` có thêm `branches`, `remain`, `available`, `holding`                                                                                                                                                                                                                                                                                                     | Các trường cũ `quantityBefore` / `quantityAfter` giữ nguyên                                                                  |
