Giới thiệu
REST API cho hệ thống cashback: tạo affiliate link gắn theo từng user và lấy báo cáo chuyển đổi để quy hoa hồng/hoàn tiền. Mọi response là JSON với trường ok (true/false).
Kiến trúc
Shopee kiểm dấu vân tay TLS của Chrome (post-quantum X25519MLKEM768) ở endpoint tạo link — client Node/curl thuần bị chặn (90309999). Nên server dùng Puppeteer điều khiển một Chrome thật (đã đăng nhập) để gọi trong trang → TLS khớp, tạo link được.
client → POST /api/link → API (Puppeteer) → Chrome thật (đã login, đã tin cậy)
← shortLink ←──────────────────────── page.evaluate(fetch) [TLS Chrome → OK]
Hai chế độ (cấu hình ở config.puppeteer):
| Chế độ | Mô tả |
|---|---|
| connect (khuyến nghị) | Bạn tự mở Chrome cổng debug (start-chrome.bat); server gắn vào qua connectURL. Ổn định nhất. |
| launch | Server tự mở Chrome (headless true/false). Dùng cho VPS + Xvfb — xem DEPLOY.md. |
Cashback & SubIds
Shopee cho gắn tối đa 5 SubId vào mỗi link; khi có đơn, báo cáo trả lại đúng các SubId đó → dùng để quy đơn về từng user.
Quy ước mặc định của hệ thống (đổi ở config.defaultSubIds):
| SubId | Ý nghĩa | Ví dụ |
|---|---|---|
subId1 | userId — người nhận cashback (truyền qua trường userId) | u12345 |
subId2 | Nguồn / nền tảng | web, app |
subId3 | Nhãn/chiến dịch | cashback |
subId4, subId5 | Tuỳ ý (mã đơn, click id...) | — |
Luồng cashback:
- User bấm "lấy link" → gọi
POST /api/linkkèmuserId→ link gắnsubId1 = userId. - User mua hàng qua link đó.
- Định kỳ gọi
GET /api/report/by-subid?subIds=<userId>→ ra các đơn + hoa hồng của user → tính cashback.
Cài đặt & chạy
npm install
copy config.example.json config.json
start-chrome.bat # mở Chrome bot (cổng 9222) — đăng nhập Shopee 1 lần
npm start # server connect vào Chrome đó (http://localhost:4000)
Trang test: / · Tài liệu: /docs.html.
Xác thực
Nếu apiKey trong config.json khác rỗng, mọi request /api/* phải kèm header:
x-api-key: <apiKey của bạn>
Endpoints
GET /health
Kiểm tra server sống + liệt kê endpoint.
{ "ok": true, "service": "shopee-aff-api", "mode": "puppeteer", "endpoints": [ ... ] }
GET /api/worker/status
Trạng thái Chrome worker. Nên kiểm tra trước khi tạo link.
{ "ok": true, "mode": "puppeteer", "online": true,
"ready": true, "loggedIn": true, "headless": false }
online = ready && loggedIn. Nếu loggedIn:false → đăng nhập lại trong cửa sổ Chrome bot.
POST /api/link
Tạo affiliate link gắn theo user (cho cashback).
Body (JSON)| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
originalLink | string | ✅ | Link Shopee cần tạo aff |
userId | string | — | Mã user nhận cashback → gắn vào subId1 |
subIds | object | — | Ghi đè/bổ sung { subId1..subId5 } (userId thắng subId1) |
curl -X POST http://localhost:4000/api/link \
-H "Content-Type: application/json" \
-d '{"originalLink":"https://s.shopee.vn/xxxxx","userId":"u12345"}'
Response
{
"ok": true,
"userId": "u12345",
"subIds": { "subId1": "u12345", "subId2": "web", "subId3": "cashback" },
"shortLink": "https://s.shopee.vn/7fa7TmbGFn",
"longLink": "https://shopee.vn/universal-link/product/...",
"raw": { ... }
}
Lỗi thường gặp
| error | Nghĩa |
|---|---|
| Chưa đăng nhập Shopee | Đăng nhập lại trong cửa sổ Chrome bot |
| Shopee lỗi 90309999 (kèm captcha) | Thiết bị bị bắt captcha — tạo 1 link qua giao diện web để giải, xem Bảo trì |
GET /api/report
Lấy danh sách đơn chuyển đổi trong khoảng thời gian.
Query params| Param | Mặc định | Mô tả |
|---|---|---|
days | 7 | Số ngày gần nhất |
page | 1 | Trang |
size | 50 | Số đơn mỗi trang |
curl "http://localhost:4000/api/report?days=7&size=50"
{ "ok": true, "total": 12, "list": [ { "order_sn": "...", "commission": "...", "sub_ids": ["u12345","web","cashback"] } ] }
GET /api/report/by-subid
Lọc đơn theo SubID — dùng để lấy đơn của một user cụ thể (truyền userId vào subIds).
| Param | Mặc định | Mô tả |
|---|---|---|
subIds | — | Danh sách SubID cách nhau dấu phẩy (vd userId: u12345) |
days | 7 | Số ngày gần nhất |
curl "http://localhost:4000/api/report/by-subid?subIds=u12345&days=30"
{ "ok": true, "total": 40, "matchedCount": 3, "subIds": ["u12345"], "matched": [ ... đơn của user ... ] }
Xử lý lỗi
{ "ok": false, "error": "mô tả lỗi", "code": 90309999 }
| HTTP | Ý nghĩa |
|---|---|
| 400 | Thiếu tham số (vd không có originalLink) |
| 401 | Sai/thiếu x-api-key |
| 404 | Sai endpoint |
| 502 | Shopee từ chối (chưa login / captcha / lỗi Shopee) |
Thông báo khi cần giải captcha / đăng nhập
Server tự bắn thông báo (Telegram và/hoặc webhook) khi gặp CAPTCHA hoặc mất đăng nhập, để bạn vào giải. Không tự giải — chỉ gọi bạn vào.
Cấu hìnhconfig.notify
"notify": {
"enabled": true,
"cooldownSec": 300, // giãn cách chống spam
"telegram": { "botToken": "123:ABC", "chatId": "123456789" },
"webhook": "https://..." // tuỳ chọn: POST {text, reason}
}
Lấy Telegram botToken + chatId
- Chat với
@BotFather→/newbot→ lấy botToken. - Nhắn 1 tin cho bot vừa tạo, rồi mở
https://api.telegram.org/bot<token>/getUpdates→ lấy chat.id (hoặc hỏi@userinfobot). - Điền vào
config.notify.telegram.
curl http://localhost:4000/api/notify/test // gửi 1 tin test (kèm ảnh màn hình)
Khi có sự cố, bạn sẽ nhận tin kèm ảnh chụp trang → vào Chrome bot giải captcha / đăng nhập (xem Bảo trì).
Bảo trì (login / captcha)
- Chưa đăng nhập (
loggedIn:false): mở cửa sổ Chrome bot (chạystart-chrome.bat) → đăng nhập Shopee. ProfileC:\shopee-bot-profilesẽ nhớ. - Captcha (90309999): profile mới/lâu không dùng bị Shopee coi là thiết bị lạ. Vào trang
affiliate.shopee.vn/offer/custom_linktrong Chrome bot, tạo 1 link qua giao diện, giải captcha 1 lần → nhận cookie tin cậy → API chạy lại bình thường. - Xem màn hình từ xa:
GET /api/worker/screenshot.png; điều hướng tới trang login:GET /api/worker/open-login.