API tra cứu mã số thuế Pay2S giúp backend lấy tên người nộp thuế, địa chỉ và trạng thái để hỗ trợ điền dữ liệu người mua cho hóa đơn tự động. API này không tạo và không phát hành hóa đơn. Do đó, ứng dụng phải xem kết quả như dữ liệu kiểm tra, hiển thị cho người dùng xác nhận và chỉ đưa sang bước lập hóa đơn khi các điều kiện nghiệp vụ đã đủ.
Bài viết trên hoadontudong.com.vn tập trung vào cách gọi đúng endpoint GET, tạo header pay2s-token bằng Base64 của Secret Key đúng một lần, giữ mã số thuế ở dạng chuỗi, đọc mã trạng thái 00 và xử lý 401, 403, 404, 422, 429, 502, 503. Những chi tiết nhỏ này quyết định việc hệ thống có tra cứu ổn định hay không.
Request, token và phạm vi mã được hỗ trợ
Request dùng GET tới https://api.pay2s.vn/userapi/tax-lookup?mst=…, gửi header pay2s-token và Accept application/json. Không gửi JSON body và không dùng POST cho đường dẫn này. Query mst phải là chuỗi, giữ số 0 đầu; API hỗ trợ mã doanh nghiệp 10 hoặc 13 chữ số và mã đơn vị phụ thuộc dạng 0123456789-001. Tra cứu mã định danh cá nhân 12 số cần tài khoản được Pay2S phê duyệt riêng.
pay2s-token được tạo bằng Base64 của nguyên chuỗi Secret Key UTF-8, đúng một lần. Đây không phải JWT, Access Key, token Dashboard hay Base64 của accessKey:secretKey. Không thêm Bearer hoặc Basic. Token có thể giải mã ngược nên phải được xem như Secret Key: chỉ đặt ở backend, không đưa vào frontend, URL, log hoặc tài liệu gửi cho khách hàng.
Đọc response và ánh xạ sang hóa đơn
Response thành công có status true ở cấp request, data.taxCode, data.companyName, data.address, data.status.code, data.status.name và data.canIssueInvoice. Trong đó, data.status.code là chuỗi và cần giữ nguyên “00”; không chuyển thành số vì có thể làm mất ý nghĩa của mã. meta.fresh cho biết kết quả là lần tra cứu mới theo cấu trúc hiện tại. Không dùng meta để quyết định thanh toán hoặc phát hành.
Khi đưa dữ liệu sang API hóa đơn tự động, taxCode có thể ánh xạ sang buyer_tax_code, companyName sang buyer_name và address sang buyer_address. Không tự đưa companyName vào buyer_contact_name. Sau khi ánh xạ, vẫn phải kiểm tra người mua, mẫu, hàng hóa và quyền phát hành. API hóa đơn tự động Pay2S dùng một cơ chế chữ ký khác, vì vậy không trộn pay2s-token của tax lookup với X-Signature của API einvoices.
Xử lý lỗi và thiết kế backend an toàn
HTTP 401 thường liên quan Secret Key sai, Base64 sai một lần hoặc header bị thêm tiền tố. HTTP 403 có thể do gói không đủ điều kiện hoặc chưa được cấp quyền tra cứu mã cá nhân. 404 là không tìm thấy mã số thuế, 422 là sai định dạng, còn 429 là vượt giới hạn tốc độ hoặc hạn mức ngày. 502, 503 và 504 có thể là lỗi hoặc timeout từ nguồn tra cứu, không nên tự kết luận mã số thuế sai.
Backend nên đặt timeout hợp lý, đọc Retry-After hoặc retry_after khi có 429, giới hạn số lần thử và ghi request_id để hỗ trợ đối soát. Không lưu token trong database nghiệp vụ, không log nguyên header và không gọi API lặp liên tục khi người dùng bấm nút nhiều lần. Khi API trả kết quả, hãy hiển thị rõ đó là dữ liệu tham khảo và yêu cầu người dùng kiểm tra trước khi chuyển sang quy trình lập hóa đơn.
Checklist vận hành nhanh
Dùng GET và truyền mst bằng query, không gửi body JSON.
Giữ mst ở dạng chuỗi và bảo toàn số 0 đầu hoặc dấu gạch của đơn vị phụ thuộc.
Tạo Base64 đúng một lần từ Secret Key UTF-8.
Không thêm Bearer, Basic hoặc dấu ngoặc kép vào pay2s-token.
Kiểm tra data.status.code là chuỗi 00 trước khi cho luồng tự động tiếp tục.
Retry có giãn cách và dùng request_id khi liên hệ hỗ trợ.
Câu hỏi thường gặp
Có thể gọi API tra cứu từ JavaScript frontend không?
Không nên. Secret Key và pay2s-token phải nằm ở backend; frontend chỉ nhận dữ liệu cần hiển thị sau khi server đã xác thực.
status true có nghĩa người nộp thuế đang hoạt động không?
Không. status true chỉ nói request thành công. Cần đọc data.status.code và chỉ mã chuỗi 00 mới là điều kiện tiếp tục luồng tự động theo tài liệu.
Base64 hai lần có được không?
Không. Base64 hai lần tạo token sai và thường dẫn tới 401. Hãy tạo trực tiếp từ nguyên Secret Key đúng một lần.
API tra cứu mã số thuế Pay2S hỗ trợ backend lấy tên, địa chỉ và trạng thái người nộp thuế để điền thông tin người mua. Hướng dẫn của hoadontudong.com.vn pay2s phân biệt cơ chế token của API này với HMAC của API hóa đơn; tra cứu không tạo hoặc phát hành hóa đơn.
Endpoint và điều kiện sử dụng
GET https://api.pay2s.vn/userapi/tax-lookup?mst=MA_SO_THUE
pay2s-token: BASE64_SECRET_KEY
Accept: application/json
Dùng GET, truyền mst trên query, không gửi JSON body. Giữ MST ở kiểu chuỗi để không mất số 0 đầu. Mã doanh nghiệp hỗ trợ 10 hoặc 13 chữ số, hoặc dạng đơn vị phụ thuộc có dấu gạch nối như 0123456789-001.
Tài khoản cần gói đang hoạt động từ Basic trở lên; Free35 không dùng được. Secret Key cửa hàng cũng được hỗ trợ khi khóa, cửa hàng đang hoạt động và tài khoản chủ đủ gói. Tra cứu định danh cá nhân 12 số cần Pay2S phê duyệt riêng; không mặc định mọi tài khoản đều có quyền.
Tạo pay2s-token đúng một lần
Lấy Secret Key trong Tích hợp → Website/Application. Mã hóa nguyên chuỗi UTF-8 bằng Base64 chuẩn, đúng một lần. Không lấy Access Key hoặc Partner Code để tạo token.
pay2s-token = Base64(UTF8(Secret Key))
// Ví dụ giả, không phải khóa thật:
example-secret → ZXhhbXBsZS1zZWNyZXQ=
Header chỉ chứa giá trị token, không có tiền tố Bearer hoặc Basic. Đây không phải JWT, token Dashboard hoặc Base64 của cặp Access Key:Secret Key. API tra cứu không dùng bộ header X-Signature của API hóa đơn điện tử.
Base64 giải mã ngược được. Vì vậy, bảo vệ token như Secret Key: giữ ở backend, không đặt vào URL, JavaScript công khai hoặc log. Với Postman, chọn No Auth và đặt token trong Headers bằng biến bí mật.
Ví dụ gọi từ Node.js backend
async function lookupTaxCode(mst) {
const secret = process.env.PAY2S_SECRET_KEY;
if (!secret) throw new Error('Thiếu Secret Key');
const url = new URL('https://api.pay2s.vn/userapi/tax-lookup');
url.searchParams.set('mst', mst);
const response = await fetch(url, {
headers: {
'pay2s-token': Buffer.from(secret, 'utf8').toString('base64'),
Accept: 'application/json'
}, signal: AbortSignal.timeout(30000)
});
const result = await response.json();
if (!response.ok || result.status !== true)
throw new Error(result.message || 'Tra cứu thất bại');
return result.data;
}
Backend nên trả về các trường cần hiển thị để người dùng xác nhận, không trả Secret Key hoặc token cho trình duyệt. Kiểm tra cả HTTP và status ngoài cùng của JSON.
Đọc kết quả và ánh xạ người mua
Trường
Ý nghĩa
data.taxCode
MST tìm được; giữ dạng chuỗi.
data.companyName
Tên người nộp thuế hoặc đơn vị.
data.address
Địa chỉ từ nguồn tra cứu.
data.status.code
Trạng thái thuế, giữ nguyên chuỗi “00”.
data.canIssueInvoice
Cờ từ nguồn tra cứu, không phải kết quả phát hành.
request_id
Mã đối soát khi cần hỗ trợ.
status: true ngoài cùng chỉ cho biết yêu cầu tra cứu thành công. Luồng tự động HĐĐT chỉ tiếp tục khi trạng thái thuế là "00" và đủ điều kiện khác. meta.fresh: true cho biết dữ liệu mới; không dùng metadata này quyết định thanh toán hoặc phát hành.
Sau khi người dùng xác nhận, dữ liệu doanh nghiệp ánh xạ vào buyer_tax_code, buyer_name, buyer_address của API tạo nháp. Kiểm tra riêng cá nhân/hộ kinh doanh theo quy tắc dữ liệu người mua.
Xử lý lỗi và giới hạn
401: kiểm tra khóa, Base64 đúng một lần và tiền tố header. 403: kiểm tra gói/quyền. 404: không tìm thấy thông tin. 422: MST sai định dạng. 429: đợi theo Retry-After hoặc retry_after. Với 502/504, nguồn tra cứu lỗi hoặc timeout; thử lại có giãn cách, không kết luận MST sai.
Đọc hạn mức từ X-RateLimit-Limit, X-RateLimit-Remaining và các header hạn mức ngày tương ứng; không áp dụng máy móc giới hạn 60 request/phút của API HĐĐT sang API tra cứu.