Nhận dự án mới tháng 11/2026 · phản hồi trong ngày làm việcZalo · GitHub

Zalo OA API cho lập trình viên: lấy token, gửi tin và webhook

Lập trình viên nối phần mềm của công ty với Zalo OA, điện thoại bên cạnh hiện tin nhắn khách gửi về

Muốn phần mềm nối Zalo OA qua API, cần OA gói Tăng trưởng hoặc Toàn diện và một ứng dụng trên Zalo for Developers. Rồi đi ba bước: lấy access token bằng OAuth v4, gửi tin qua API, nhận tin khách qua webhook. Access token sống 25 giờ, refresh token 3 tháng và chỉ dùng một lần.

Trên blog đã có bài Zalo OA là gì (khái niệm, khác Zalo cá nhân ở đâu) và bài Zalo OA có mất phí không (phí gói, phí tin, ZNS). Bài này viết cho người lập trình hoặc người đặt hàng phần mềm: luồng kỹ thuật để một hệ thống tự gửi và nhận tin qua OA. Thứ tự: tổng quan luồng, chuẩn bị gói và ứng dụng, lấy token, gửi tin, nhận webhook, cách giữ token sống, rồi các điểm bất lợi. Endpoint, tham số và thời hạn trong bài lấy từ tài liệu Zalo for Developers và trang bảng giá Zalo OA, kiểm ngày 09/11/2026.

Tổng quan luồng nối phần mềm với Zalo OA

Nhìn từ phía phần mềm, mọi tích hợp Zalo OA quy về ba khâu. Tôi tách riêng từng khâu khi thiết kế.

Ba bước nối phần mềm với Zalo OA: lấy access token, gửi tin qua API, nhận tin khách qua webhook
Ba bước nối phần mềm với Zalo OA: lấy access token, gửi tin qua API, nhận tin khách về qua webhook.
  1. Lấy access token. Quản trị viên OA bấm «Cho phép» trên trang cấp quyền, phần mềm nhận mã uỷ quyền rồi đổi lấy access token và refresh token.
  2. Gửi tin qua API. Phần mềm gọi Open API của Zalo, kèm access token ở header, để gửi tin cho người dùng đã tương tác với OA.
  3. Nhận tin khách qua webhook. Khi khách nhắn OA, Zalo gửi một yêu cầu POST tới địa chỉ webhook của ứng dụng. Từ đó phần mềm biết ID người gửi.

Thực tế khâu 3 thường chạy trước khâu 2: khách nhắn trước, phần mềm lấy ID người gửi từ webhook rồi mới trả lời.

Chuẩn bị: gói OA, ứng dụng Zalo và khoá bí mật

Trang bảng giá Zalo OA (kiểm 09/11/2026) ghi ở phần hỏi đáp: muốn liên kết ứng dụng với OA thông qua API thì cần gói Tăng trưởng hoặc gói Toàn diện. Hai gói thấp hơn (Cơ bản, Tiêu chuẩn) không có quyền gọi API.

GóiGiá (đã gồm VAT 10%)Giới hạn gọi APISố ứng dụng được uỷ quyền
Tăng trưởng2.500.000 đ/năm; 1.400.000 đ/6 tháng100 request/phút3
Toàn diện6.000.000 đ/năm; 3.400.000 đ/6 tháng2.000 request/phútKhông giới hạn

Giới hạn request không tính API gửi tin ZBS Template Message (ZNS).

Ngoài gói OA, anh chị cần:

  • Một ứng dụng trên Zalo for Developers. Tài liệu «Khởi tạo ứng dụng» ghi: muốn dùng hệ thống OpenAPI (OA, ZNS, Zalo Shop, Mini App…) thì phải tạo một Zalo App bằng tài khoản Zalo, điền thông tin và kích hoạt.
  • Khoá bí mật của ứng dụng (App Secret Key). Lấy ở mục Cài đặt của ứng dụng. Khoá này đi trong header khi đổi token, nên chỉ để ở máy chủ, không đưa vào ứng dụng điện thoại hay mã chạy trên trình duyệt.
  • Một địa chỉ HTTPS có tên miền. Dùng cho callback URL nhận mã uỷ quyền và cho webhook. Tài liệu webhook khuyên không dùng dạng host:port mà dùng tên miền có HTTPS.

Bước 1: Lấy access token bằng OAuth v4

Tài liệu Xác thực và uỷ quyền cho ứng dụng (kiểm 09/11/2026) đưa hai cách: giao thức OAuth v4 cho phần mềm, và công cụ API Explorer để quản trị viên lấy mã thủ công khi thử.

Ba loại mã và thời hạn

MãDùng để làm gìThời hạn
Authorization codeĐổi lấy access token và refresh token10 phút, chỉ dùng 1 lần
Access tokenCho ứng dụng đại diện OA gọi API25 giờ (trường expires_in trả về 90000 giây)
Refresh tokenTạo access token mới khi token cũ hết hạn3 tháng, chỉ dùng 1 lần

Tạo code verifier và code challenge (PKCE)

Zalo dùng phương thức PKCE. Phần mềm tạo một code_verifier dài 43 ký tự, có đủ chữ hoa, chữ thường và số, lưu lại ở máy chủ. Từ đó tính code_challenge theo công thức trong tài liệu: mã hoá ASCII, băm SHA-256, rồi mã hoá Base64 không có ký tự đệm. Mỗi yêu cầu cấp quyền dùng một code verifier khác nhau. Tài liệu gợi ý dùng biến state hoặc một tham số tự đặt trong callback URL để biết mã uỷ quyền nhận về ứng với verifier nào.

Thiết lập đường dẫn cấp quyền và nhận mã uỷ quyền

Trong trang quản lý ứng dụng trên Zalo for Developers, anh chị đặt callback URL, dán code challenge, chọn các nhóm quyền cần xin (gửi tin và thông báo qua OA, quản lý tin nhắn người dùng, quản lý thông tin OA, nhận sự kiện quản lý tin nhắn…) rồi lưu. Tài liệu không đưa mẫu URL để tự ghép; anh chị sao chép đường dẫn do trang quản lý tạo và gửi cho quản trị viên OA.

Quản trị viên mở đường dẫn, chọn OA và bấm «Cho phép». Trình duyệt chuyển về callback URL kèm hai tham số code và oa_id, dạng https://yourdomain.com/abc?code=<AUTHORIZATION_CODE>&oa_id=<OA_ID>.

Đổi mã uỷ quyền lấy token

Gọi POST https://oauth.zaloapp.com/v4/oa/access_token, kiểu nội dung application/x-www-form-urlencoded:

  • Header secret_key: <APP_SECRET_KEY>.
  • Body: code=<AUTHORIZATION_CODE>, app_id=<APP_ID>, grant_type=authorization_code, code_verifier=<CODE_VERIFIER> (bắt buộc nếu đã đặt code challenge).

Kết quả trả về access_token, refresh_token và expires_in. Mã uỷ quyền chỉ sống 10 phút, nên đổi mã ngay trong lúc xử lý callback.

Làm mới access token

Cùng endpoint đó, body đổi thành refresh_token=<REFRESH_TOKEN>, app_id=<APP_ID>, grant_type=refresh_token, header vẫn có secret_key. Tài liệu ghi ba điều cần nhớ: refresh token cũ bị vô hiệu ngay khi dùng thành công, hệ thống trả về refresh token mới cho lần sau, và access token cũ hết hiệu lực ngay khi access token mới được tạo.

Bước 2: Gửi tin tư vấn qua Open API

Tài liệu «Gửi tin Tư vấn dạng văn bản» (kiểm 09/11/2026) ghi endpoint POST https://openapi.zalo.me/v3.0/oa/message/cs, kiểu nội dung application/json, header access_token: <ACCESS_TOKEN>. Body gồm hai phần:

  • recipient.user_id: ID người nhận. ID này lấy từ webhook (trường sender.id) hoặc từ API truy xuất danh sách, chi tiết người dùng.
  • message.text: nội dung văn bản, tối đa 2.000 ký tự.

Phản hồi thành công có error bằng 0, kèm message_id và nguồn hạn mức đã dùng trong quota_type: reply (tin trong khung 48 giờ), welcome_msg (tin gửi người vừa quan tâm khi chưa tương tác), sub_quota (hạn mức miễn phí theo gói), purchase_quota, reward_quota, hoặc không có trường quota khi là tin tính phí. Nên lưu quota_type vào nhật ký gửi tin để cuối tháng đối chiếu tin nào bị tính tiền.

Hai điều kiện cần biết trước khi viết luồng gửi:

  • Người nhận phải tương tác với OA trong vòng 7 ngày. Đây là điều kiện gửi tin tư vấn ghi trong tài liệu. Quá 7 ngày, phần mềm phải dùng loại tin khác, thường là ZNS theo mẫu.
  • Trong khung 48 giờ thì không giới hạn. Tài liệu ghi từ ngày 1/1/2026, đối tác gửi tin tư vấn miễn phí không giới hạn trong khung 48 giờ. Ngoài khung 48 giờ nhưng còn trong 7 ngày thì trừ hạn mức gói hoặc tính phí, như bài phí đã nói.

Bước 3: Nhận tin khách về qua webhook

Theo trang Giới thiệu về Webhook (kiểm 09/11/2026), anh chị bật webhook trong trang cài đặt ứng dụng: bấm «Thay đổi», nhập Webhook URL, rồi bật từng loại sự kiện muốn nhận. OA phải đã cấp access token cho ứng dụng thì sự kiện mới về.

Sự kiện khách gửi tin trông thế nào

Khi khách nhắn OA, Zalo gửi POST dạng JSON với các trường chính: app_id, sender.id (ID khách), recipient.id (ID OA), event_name, message (gồm text và msg_id), timestamp. Giá trị event_name cho biết loại tin: user_send_text, user_send_image, user_send_link, user_send_audio, user_send_video, user_send_sticker, user_send_location, user_send_business_card, user_send_file. Tin đa phương tiện có thêm mảng attachments.

Kiểm chữ ký trước khi tin

Trang sự kiện «người dùng gửi tin nhắn» ghi header X-ZEvent-Signature với công thức mac = sha256(appId + data + timeStamp + OAsecretKey), trong đó data là chuỗi JSON nhận được. Phần mềm nên tính lại giá trị này và bỏ qua yêu cầu không khớp. Không kiểm chữ ký thì bất kỳ ai biết địa chỉ webhook cũng giả được tin khách.

Yêu cầu tốc độ và cơ chế gửi lại

  • Trả mã HTTP 200 cho mọi sự kiện, trong tối đa 2 giây.
  • Khi không mở được kết nối tới webhook, Zalo gửi lại sau 30 giây, 5 phút, 15 phút, 30 phút và 1 giờ, header có thêm trường num_retry.
  • Hết các lần gửi lại mà webhook vẫn hỏng, ứng dụng bị huỷ đăng ký nhận sự kiện. Sửa xong phải vào trang cài đặt ứng dụng xin lại quyền nhận sự kiện.

Giới hạn 2 giây nghĩa là webhook không được gọi AI hay ghi nhiều bảng rồi mới trả lời. Cách tôi làm: kiểm chữ ký, ghi sự kiện vào hàng đợi, trả 200 ngay, phần xử lý chạy sau. Vì có gửi lại, cùng một tin có thể đến hai lần; dùng msg_id để bỏ bản trùng.

Giữ token sống: phần dễ hỏng nhất

Gửi tin và nhận webhook thường chạy ngay ngày đầu. Phần hay làm tích hợp chết sau vài tuần là token. Ba quy tắc tôi rút ra từ cách tài liệu mô tả refresh token:

  1. Chỉ một nơi được làm mới token. Refresh token dùng một lần. Nếu hai tiến trình cùng làm mới, tiến trình thứ hai cầm refresh token đã chết, và access token của tiến trình thứ nhất cũng có thể bị thay. Đặt khoá (lock) quanh bước làm mới, hoặc giao hẳn việc này cho một dịch vụ riêng.
  2. Lưu refresh token mới trước khi dùng access token mới. Nếu ghi cơ sở dữ liệu thất bại sau khi đã làm mới, anh chị mất refresh token và phải nhờ quản trị viên OA cấp quyền lại.
  3. Làm mới chủ động, không chờ lỗi. Access token sống 25 giờ; làm mới theo lịch trước khi hết hạn, và đặt cảnh báo khi làm mới thất bại. Refresh token 3 tháng không tự gia hạn nếu phần mềm ngừng làm mới.

Khi làm ZCRM, nhóm tôi tách riêng phần giữ token khỏi phần gửi tin vì đúng lý do trên. Ai muốn xem cách một CRM dùng các khâu này cho đội bán hàng có thể đọc bài ZaloCRM tích hợp Zalo OA và bài chatbot Zalo OA nối ZaloCRM.

Điểm bất lợi khi tự nối Zalo OA API

  • Phải trả gói từ Tăng trưởng. OA đang ở gói Cơ bản hay Tiêu chuẩn thì không gọi được API; chi phí tối thiểu là 2.500.000 đ/năm (kiểm 09/11/2026).
  • Giới hạn 100 request/phút ở gói Tăng trưởng. Gửi hàng loạt hoặc đồng bộ danh sách người dùng lớn sẽ chạm trần.
  • Khung 7 ngày. Không nhắn tư vấn được cho khách đã im lặng quá 7 ngày; muốn nhắc khách cũ phải đi ZNS và trả phí theo mẫu.
  • Webhook khắt khe. Trả chậm quá 2 giây thì bị cảnh báo; máy chủ không nhận được sự kiện qua hết các lần gửi lại thì bị huỷ đăng ký, phải xin lại bằng tay.
  • Tài liệu thay đổi. API tin nhắn đã chuyển từ v2 sang v3; trường hạn mức trong phản hồi cũng đổi theo lộ trình 2026. Theo dõi mục lịch sử cập nhật của Zalo for Developers.

Câu hỏi thường gặp về Zalo OA API

Gói Zalo OA nào gọi được API?

Gói Tăng trưởng (2.500.000 đ/năm, 100 request/phút, 3 ứng dụng) và gói Toàn diện (6.000.000 đ/năm, 2.000 request/phút, không giới hạn ứng dụng), theo trang bảng giá Zalo OA kiểm 09/11/2026. Gói Cơ bản và Tiêu chuẩn không có API.

Access token Zalo OA hết hạn sau bao lâu?

25 giờ kể từ lúc cấp. Refresh token sống 3 tháng và chỉ dùng được một lần; mỗi lần làm mới, Zalo trả về cặp access token và refresh token mới.

Có gửi tin cho người chưa từng nhắn OA được không?

Tin tư vấn thì không: người nhận phải tương tác với OA trong 7 ngày, trừ số lượt giới hạn gửi người vừa quan tâm OA (welcome_msg). Muốn chủ động gửi theo số điện thoại thì xem ZNS, sản phẩm có bảng giá riêng.

Webhook có bắt buộc HTTPS không?

Tài liệu ghi Webhook URL nên dùng tên miền và phải cấu hình HTTPS, không dùng dạng host:port.

Nguồn: developers.zalo.me (Xác thực và uỷ quyền cho ứng dụng; Khởi tạo ứng dụng; Hướng dẫn lấy khoá bí mật của ứng dụng; Gửi tin Tư vấn dạng văn bản; Điều kiện gửi tin Tư vấn; Giới thiệu về Webhook; Sự kiện người dùng gửi tin nhắn); zalo.solutions/oa/pricing, kiểm ngày 09/11/2026.

Lộc Nguyễn

Dựng đội agent làm việc thật cho doanh nghiệp. Viết lại những gì đã làm, có số đo kèm theo.

Về tác giả →

Khoá Claude miễn phí cho người không rành kỹ thuật

8 bài, làm theo từng bước: từ lần đầu mở Claude đến nối Zalo, bảng tính và email. Để lại email, nhận bài 1 ngay.

Zalo OA API: lấy token, gửi tin và nhận webhook