Hướng dẫn sử dụng sau khi cài đặt Zalo sandbox
Back to zalo sandboxSau khi cài đặt Zalo Sandbox, bạn cần cấu hình thông tin OA giả lập, chuẩn bị người dùng thử và lấy access token trước khi gọi các API.
Trước khi bắt đầu
Hướng dẫn này giả định rằng bạn đã tải Zalo Sandbox từ chợ EzyPlatform, cài đặt thành công cả admin plugin và web plugin, sau đó khởi động lại EzyPlatform.
Plugin phụ thuộc vào EzyChat. Hãy bảo đảm EzyChat đã được cài đặt và hoạt động trước khi sử dụng Zalo Sandbox.
Trong các ví dụ bên dưới,
<WEB_URL> là địa chỉ web EzyPlatform của bạn, chẳng hạn http://localhost:8080 hoặc https://example.com. Khi thực hành, hãy thay toàn bộ <WEB_URL> bằng địa chỉ tương ứng và không thêm dấu / ở cuối.Kiểm tra sau khi cài đặt
Đăng nhập trang quản trị EzyPlatform và mở menu Zalo Sandbox. Plugin cung cấp ba khu vực chính:
- Messages: xem tin nhắn đã gửi vào sandbox và phát webhook thử nghiệm;
- Users: quản lý danh sách người dùng được xem là follower của OA sandbox;
- Settings: cấu hình App ID, secret, token, callback URL, webhook URL và lỗi giả lập.
Plugin phụ thuộc vào hệ thống chat của EzyPlatform. Khi khởi động thành công, một kênh chat OA và vai trò người dùng OA sandbox sẽ được tạo nếu chưa tồn tại.
Bạn cũng có thể mở trang Swagger tại:
<WEB_URL>/zalo-sandbox/swagger
Trang này cho phép xem nhanh những endpoint, request và response đang được sandbox hỗ trợ.
Cấu hình sandbox lần đầu
Mở Zalo Sandbox → Settings và điền các trường sau:
| Trường | Cách thiết lập |
|---|---|
| Zalo OA App ID | Nhập một chuỗi đại diện cho ứng dụng hoặc bấm Random |
| Zalo OA App Secret Key | Nhập application secret hoặc bấm Random |
| Zalo OA Webhook Secret Key | Secret dùng để ký webhook gửi từ sandbox |
| Zalo OA Access Token | Token sandbox sẽ trả về sau bước đổi authorization code |
| Zalo OA Refresh Token | Refresh token dùng cho luồng làm mới token |
| Token Expire In Seconds | Thời gian hiệu lực tính bằng giây; mặc định tương đương 7 ngày |
| Token Expired At | Mốc hết hạn hiện tại tính bằng milliseconds từ Unix epoch |
| Auth Code Challenge | Có thể để trống và truyền challenge khi bắt đầu OAuth |
| Auth Callback URLs | Danh sách callback URL được phép |
| OA Webhook URLs | Danh sách URL nhận webhook để chọn trên trang quản trị |
| Send Message Response Error | Mã lỗi muốn giả lập cho API gửi tin thường |
| Send Message Template Response Error | Mã lỗi muốn giả lập cho API gửi tin template |


Các trường App ID, App Secret Key, Access Token, Refresh Token, thời gian hiệu lực và callback URL là bắt buộc. Callback URL và webhook URL được nhập dưới dạng danh sách phân tách bằng dấu phẩy.
Nhấn Save để lưu. Bạn cũng có thể dùng
Ctrl+S trên Windows/Linux hoặc Command+S trên macOS khi con trỏ đang ở trong biểu mẫu.Callback URL phải khớp hoàn toàn với
redirect_uri gửi lên endpoint cấp quyền, bao gồm protocol, host, port, path và dấu gạch chéo cuối nếu có. Ví dụ:<WEB_URL>/oa/ZALO_SANDBOX/auth-callback
Chuẩn bị người dùng OA thử nghiệm
Người dùng OA sandbox là tài khoản EzyPlatform được gán thêm vai trò OA sandbox, không phải một loại tài khoản độc lập.
Để thêm người dùng:
- Tạo tài khoản trong khu vực quản lý người dùng của EzyPlatform nếu chưa có.
- Mở Zalo Sandbox → Users.
- Nhấn nút thêm mới.
- Tìm và chọn một tài khoản đã tồn tại.
- Kiểm tra tài khoản xuất hiện trong danh sách Users của Zalo Sandbox.
Nên bổ sung tên hiển thị, số điện thoại và ảnh đại diện cho tài khoản thử. API chi tiết người dùng sử dụng tên hiển thị và ảnh đại diện; API gửi template tìm người nhận theo số điện thoại.
Nhấn biểu tượng xem chi tiết để lấy UUID của người dùng. UUID này được dùng làm
user_id khi gọi API OA.Lấy access token bằng OAuth và PKCE
Bạn có thể dùng trực tiếp token đã cấu hình, nhưng thực hiện đầy đủ luồng OAuth sẽ giúp kiểm tra tích hợp sát thực tế hơn.
Tạo code verifier và code challenge
Tạo một
code_verifier, sau đó băm SHA-256 và mã hóa Base64 URL-safe không padding để thu được code_challenge.Ví dụ trên macOS hoặc Linux:
CODE_VERIFIER="zalo-sandbox-verifier-0123456789-abcdefghijklmnopqrstuvwxyz" CODE_CHALLENGE=$(printf '%s' "$CODE_VERIFIER" \ | openssl dgst -sha256 -binary \ | openssl base64 -A \ | tr '+/' '-_' \ | tr -d '=') printf '%sn' "$CODE_CHALLENGE"
Giữ lại
CODE_VERIFIER; giá trị này sẽ được dùng khi đổi authorization code lấy token.Bắt đầu luồng cấp quyền
Mở URL sau trên trình duyệt và thay các placeholder bằng cấu hình của bạn:
<WEB_URL>/zalo-sandbox/v4/oa/permission?app_id=<APP_ID>&redirect_uri=<CALLBACK_URL>&code_challenge=<CODE_CHALLENGE>
Nên URL-encode các query parameter khi tạo URL trong ứng dụng. Sandbox kiểm tra App ID và callback URL, lưu code challenge rồi chuyển hướng về callback theo dạng:
<CALLBACK_URL>?code_challenge=<CODE_CHALLENGE>&code=<AUTHORIZATION_CODE>
Lấy giá trị
code từ URL callback.Đổi authorization code lấy token
Gửi request sau:
curl --request POST \ '<WEB_URL>/zalo-sandbox/v4/oa/access_token' \ --header 'Content-Type: application/json' \ --header 'secret_key: <APP_SECRET_KEY>' \ --data '{ "app_id": "<APP_ID>", "code": "<AUTHORIZATION_CODE>", "grant_type": "authorization_code", "code_verifier": "<CODE_VERIFIER>" }'
Response thành công có dạng:
{
"access_token": "<ACCESS_TOKEN>",
"refresh_token": "<REFRESH_TOKEN>",
"expires_in": 604800
}
Thao tác cấp token cập nhật mốc hết hạn dựa trên thời gian hiện tại và
expires_in. Giá trị access token và refresh token được lấy từ cấu hình sandbox, không được tạo mới sau mỗi request.Làm mới token
Khi muốn thử luồng refresh token:
curl --request POST \ '<WEB_URL>/zalo-sandbox/v4/oa/access_token' \ --header 'Content-Type: application/json' \ --header 'secret_key: <APP_SECRET_KEY>' \ --data '{ "grant_type": "refresh_token", "refresh_token": "<REFRESH_TOKEN>" }'
Thử API người dùng
Lấy danh sách người dùng OA
Tham số
data là một chuỗi JSON chứa offset và count:curl --get \ '<WEB_URL>/zalo-sandbox/v3.0/oa/user/getlist' \ --header 'access_token: <ACCESS_TOKEN>' \ --data-urlencode 'data={"offset":0,"count":20}'
Danh sách chỉ chứa những tài khoản đã được thêm trong Zalo Sandbox → Users. Mỗi phần tử trả về
user_id, chính là UUID của tài khoản trong EzyPlatform.Lấy chi tiết người dùng
curl --get \ '<WEB_URL>/zalo-sandbox/v3.0/oa/user/detail' \ --header 'access_token: <ACCESS_TOKEN>' \ --data-urlencode 'data={"user_id":"<USER_UUID>"}'
Response thành công có thể chứa
user_id, display_name, user_alias và avatar. Nếu UUID không tồn tại, sandbox trả về lỗi tham số không hợp lệ kèm thông tin gỡ lỗi.Gửi tin nhắn chăm sóc khách hàng
Gửi một tin văn bản đến UUID của người dùng OA:
curl --request POST \ '<WEB_URL>/zalo-sandbox/v3.0/oa/message/cs' \ --header 'Content-Type: application/json' \ --header 'access_token: <ACCESS_TOKEN>' \ --data '{ "recipient": { "user_id": "<USER_UUID>" }, "message": { "text": "Xin chào từ Zalo Sandbox" } }'
Response thành công:
{
"error": 0,
"message": "success",
"debugMessage": null
}
Mở Zalo Sandbox → Messages để kiểm tra tin nhắn vừa được ghi vào kênh chat OA.
Nếu muốn gửi nội dung có attachment, thêm đối tượng
attachment vào message. Sandbox lưu nguyên cấu trúc này dưới dạng JSON để phục vụ kiểm thử; nó không xử lý toàn bộ vòng đời attachment giống Zalo thật.Upload ảnh và dùng attachment ID
Để upload ảnh:
curl --request POST \ '<WEB_URL>/zalo-sandbox/v2.0/oa/upload/image' \ --header 'access_token: <ACCESS_TOKEN>' \ --form 'file=@/duong-dan/toi/anh.png'
Response trả về tên file đã lưu dưới dạng attachment ID:
{
"data": {
"attachment_id": "<ATTACHMENT_ID>"
}
}
Ví dụ gửi tin nhắn có attachment:
curl --request POST \ '<WEB_URL>/zalo-sandbox/v3.0/oa/message/cs' \ --header 'Content-Type: application/json' \ --header 'access_token: <ACCESS_TOKEN>' \ --data '{ "recipient": { "user_id": "<USER_UUID>" }, "message": { "text": "Tin nhắn có ảnh", "attachment": { "type": "template", "payload": { "template_type": "media", "elements": [ { "media_type": "image", "attachment_id": "<ATTACHMENT_ID>" } ] } } } }'
Upload chỉ hoạt động khi tính năng upload tài nguyên đã được bật trong web runtime của EzyPlatform.
Gửi tin nhắn template
Người nhận được tìm theo số điện thoại. Vì vậy, tài khoản thử phải có số điện thoại trước khi gọi API này.
curl --request POST \ '<WEB_URL>/zalo-sandbox/message/template' \ --header 'Content-Type: application/json' \ --header 'access_token: <ACCESS_TOKEN>' \ --data '{ "phone": "0900000000", "template_id": "order-update", "template_data": { "customer_name": "Nguyen Van A", "order_code": "ORDER-001", "status": "Đang giao hàng" } }'
Sandbox cũng thử chuyển số bắt đầu bằng
84 sang dạng nội địa bắt đầu bằng 0 khi tìm người dùng. Tin template hợp lệ xuất hiện trong trang Messages cùng các tham số đã gửi.Phát webhook từ trang quản trị
Trước tiên, thêm ít nhất một URL vào trường OA Webhook URLs trong Settings, ví dụ:
<WEB_URL>/api/v1/oa/ZALO_SANDBOX/webhook
Có hai cách gửi webhook tin nhắn thử:
- Mở Users, chọn một người dùng, chọn webhook URL, nhập nội dung rồi nhấn Send.
- Mở Messages, cuộn tới biểu mẫu gửi, chọn webhook URL, nhập username và nội dung rồi nhấn Send.

Sandbox gửi một HTTP POST chứa
event_name, timestamp, sender và message. Với biểu mẫu tin nhắn, sự kiện được gửi là user_send_text.Request có header:
X-ZEvent-Signature: mac=<SHA256_HEX>
Chữ ký được tính từ chuỗi nối theo đúng thứ tự:
APP_ID + RAW_JSON_BODY + TIMESTAMP + WEBHOOK_SECRET_KEY
Ứng dụng nhận webhook nên tính lại SHA-256 ở dạng chữ thường rồi so sánh với phần sau
mac=. Giá trị timestamp vừa nằm trong body vừa tham gia tạo chữ ký.Giả lập các trường hợp lỗi
Trong Settings, chọn một mã tại Send Message Response Error hoặc Send Message Template Response Error, sau đó lưu cấu hình và gọi lại API tương ứng.
Với request hợp lệ, sandbox vẫn ghi tin nhắn vào kênh chat rồi trả mã lỗi đã chọn. Vì vậy chức năng này phù hợp để kiểm tra cách ứng dụng xử lý response lỗi, nhưng không mô phỏng transaction rollback hay việc Zalo từ chối lưu tin nhắn.
Sau khi thử xong, chọn None và lưu lại để API trở về response thành công.
Một số lỗi phổ biến khác có thể kiểm tra trực tiếp:
| Tình huống | Kết quả mong đợi |
|---|---|
| Thiếu hoặc sai access token | Lỗi access token không hợp lệ |
| Token đã quá hạn | Lỗi access token không hợp lệ, debug message cho biết token hết hạn |
| Sai App ID hoặc application secret | Request đổi token bị từ chối |
| Callback URL không nằm trong danh sách cho phép | Request permission bị từ chối |
code_verifier không khớp challenge | Request đổi token bị từ chối |
| UUID người nhận không tồn tại | Lỗi người dùng chưa theo dõi OA |
| Số điện thoại template không tìm thấy | Lỗi người dùng chưa theo dõi OA |
JSON trong tham số data không hợp lệ | Lỗi tham số không hợp lệ |
Xử lý sự cố
Access token vừa cấu hình nhưng vẫn báo hết hạn
Nhập token trong Settings chưa tự đặt lại thời điểm hết hạn. Hãy thực hiện request
POST /v4/oa/access_token để sandbox cập nhật mốc hết hạn, hoặc đặt Token Expired At thành một thời điểm milliseconds trong tương lai.Người dùng không xuất hiện trong API danh sách
Kiểm tra tài khoản đã được thêm qua Zalo Sandbox → Users. Việc chỉ tạo tài khoản trong EzyPlatform chưa đủ; tài khoản cần có vai trò OA sandbox.
Gửi template báo không tìm thấy người dùng
Kiểm tra số điện thoại trong hồ sơ tài khoản và giá trị
phone trong request. Sandbox chỉ thử hai dạng: chuỗi được gửi lên và dạng đổi tiền tố 84 thành 0.Không upload được ảnh
Kiểm tra upload tài nguyên đã được bật, kích thước file không vượt giới hạn và định dạng file được bộ kiểm tra media chấp nhận.
Không nhận được webhook
Kiểm tra URL đã được lưu trong Settings, môi trường sandbox có thể kết nối đến URL đó và endpoint đích chấp nhận HTTP POST. Nếu webhook nằm trên máy khác hoặc trong container khác,
localhost có thể trỏ sai máy.Checklist hoàn tất
Sau khi hoàn thành cấu hình, bạn nên xác nhận:
- trang Swagger mở được;
- Settings đã có App ID, secret, token và callback URL;
- ít nhất một người dùng đã xuất hiện trong danh sách OA sandbox;
- luồng OAuth trả về token và cập nhật thời hạn;
- API danh sách và chi tiết người dùng trả đúng dữ liệu;
- tin nhắn thường và template xuất hiện trong Messages;
- upload ảnh trả về attachment ID nếu dự án cần kiểm thử media;
- webhook đến được ứng dụng và chữ ký xác minh thành công;
- các mã lỗi giả lập đã được đưa về None sau khi kiểm thử.
Hoàn thành các bước trên nghĩa là Zalo Sandbox đã sẵn sàng thay thế endpoint Zalo OA trong môi trường phát triển và kiểm thử cục bộ.