Bỏ qua để đến nội dung

Developer API Reference & Xác thực Bearer Token

TrolyPage cung cấp hệ thống RESTful API cho phép Lập trình viên tích hợp dữ liệu với phần mềm nội bộ (ERP, KiotViet, Nhanh.vn, Haravan, MISA…) — đồng bộ khách hàng, đơn hàng và gửi tin nhắn.

Khái niệm Giá trị
Base URL https://trolypage.com/app/api/v1
Content-Type application/json (mọi request body)
Accept application/json
Charset UTF-8
Kiểu dữ liệu snake_case cho field; số tiền nguyên VND (350000 = 350.000đ)
Múi giờ Mốc thời gian trả về dạng Unix timestamp (giây)

Tất cả endpoint trong tài liệu này đều ghép sau Base URL. Ví dụ GET /customers = GET https://trolypage.com/app/api/v1/customers.

Mọi yêu cầu API bắt buộc kèm Header Authorization chứa API Bearer Token (tiền tố tp_live_):

GET /app/api/v1/customers HTTP/1.1
Host: trolypage.com
Authorization: Bearer tp_live_9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c
Content-Type: application/json
Accept: application/json
Terminal window
# curl
curl -X GET https://trolypage.com/app/api/v1/customers \
-H "Authorization: Bearer tp_live_9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c" \
-H "Accept: application/json"

Query params («cần xác nhận tên param chính xác»):

Param Kiểu Mặc định Mô tả
page int 1 Trang hiện tại
per_page int 20 Số bản ghi/trang (max 100)
q string Tìm theo tên/SĐT

Response 200:

{
"data": [
{
"id": 8520,
"name": "Nguyễn Văn A",
"phone": "0912345678",
"email": "khach@example.com",
"address": "123 Lê Lợi, Q.1, TP.HCM",
"tags": ["vip", "khach-cu"],
"created_at": 1774800000
}
],
"pagination": {
"page": 1,
"per_page": 20,
"total": 153,
"has_more": true
}
}

Request body:

{
"name": "Trần Thị B",
"phone": "0987654321",
"email": "tranb@example.com",
"address": "45 Hai Bà Trưng, Đà Nẵng",
"tags": ["moi"]
}

Response 201:

{
"data": {
"id": 8521,
"name": "Trần Thị B",
"phone": "0987654321",
"email": "tranb@example.com",
"address": "45 Hai Bà Trưng, Đà Nẵng",
"tags": ["moi"],
"created_at": 1774889400
}
}
Terminal window
curl -X POST https://trolypage.com/app/api/v1/customers \
-H "Authorization: Bearer tp_live_..." \
-H "Content-Type: application/json" \
-d '{"name":"Trần Thị B","phone":"0987654321"}'

Trả về 200 + object khách (như một phần tử trong data ở trên). Nếu {id} không tồn tại → 404 (xem Error envelope).

Request body: bất kỳ field nào trong name/phone/email/address/tags. Response 200 trả object đã cập nhật.


Query params:

Param Kiểu Mô tả
status string Lọc theo pending | confirmed | shipping | completed
page, per_page int Phân trang

Response 200:

{
"data": [
{
"order_id": "DH-9821",
"status": "confirmed",
"total_amount": 350000,
"currency": "VND",
"payment_status": "paid",
"customer": { "id": 8520, "name": "Nguyễn Văn A", "phone": "0912345678" },
"items": [
{ "product_id": 101, "product_name": "Áo thun Polo", "quantity": 1, "price": 350000 }
],
"created_at": 1774889450
}
],
"pagination": { "page": 1, "per_page": 20, "total": 42, "has_more": false }
}

Request body:

{
"customer_id": 8520,
"items": [
{ "product_id": 101, "quantity": 1 }
],
"note": "Giao giờ hành chính",
"payment_method": "vietqr"
}

Response 201: object đơn (như phần tử trong data ở trên).

Request body:

{ "status": "shipping" }

Status enum: pendingconfirmedshippingcompleted. («cần xác nhận có cancelled/refunded không»)

Response 200: object đơn với status mới.


Request body:

{
"customer_id": 8520,
"channel": "facebook_msg",
"text": "Dạ đơn DH-9821 đã giao cho đơn vị vận chuyển ạ 🚚",
"attachments": []
}

Response 200:

{
"data": {
"message_id": "msg_9f8a7b6c5d4e",
"status": "sent",
"channel": "facebook_msg",
"sent_at": 1774889460
}
}

Không lạm dụng

API này gửi tin chủ động tới khách — tuân thủ chính sách chống spam của nền tảng (Facebook 24h window, Zalo OA quota). Spam = bị nền tảng chặn kênh.


Mọi lỗi trả về cùng 1 cấu trúc JSON:

{
"error": {
"code": "validation_failed",
"message": "Trường phone không hợp lệ.",
"details": { "phone": ["Số điện thoại phải có 10 chữ số."] }
}
}

Bảng mã lỗi:

HTTP error.code Ý nghĩa
400 bad_request Request sai định dạng / thiếu field bắt buộc
400 validation_failed Dữ liệu không qua validate (xem details)
401 unauthenticated Thiếu/thiếu hợp lệ Authorization header
401 token_expired Token đã hết hạn — tạo token mới
403 forbidden Token hợp lệ nhưng không có quyền thực hiện
404 not_found Resource ({id}) không tồn tại
409 conflict Trùng lặp (vd tạo khách đã có SĐT) («cần xác nhận»)
422 unprocessable_entity Đúng format nhưng logic không cho phép
429 rate_limited Vượt rate limit (xem header Retry-After)
500 server_error Lỗi máy chủ — báo dev + thử lại sau

Quy tắc Giá trị
Giới hạn 100 requests/phút («theo IP hay workspace? cần xác nhận»)
Khi vượt 429 + header Retry-After: <số giây chờ>

Header rate limit trả về ở mọi response («cần xác nhận tên header»):

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 73
X-RateLimit-Reset: 1774889460
Retry-After: 12 # chỉ có khi bị 429

Khuyến nghị client: đọc X-RateLimit-Remaining, khi sắp hết → tự throttle; gặp 429 → ngủ đúng Retry-After giây rồi retry (kèm Idempotency-Key nếu là POST).


Mọi endpoint list (GET /customers, GET /orders) dùng cùng cấu trúc pagination trong response:

"pagination": {
"page": 1,
"per_page": 20,
"total": 153,
"has_more": true
}
  • Lấy trang kế: GET /customers?page=2&per_page=20.
  • Dừng khi has_more: false.

Đường dẫn chứa version (/v1). Khi có breaking change sẽ ra /v2 và duy trì /v1 một thời gian («cần chính sách deprecation từ dev: bao lâu, thông báo ra sao»).