API tra cứu mã số thuế
✧ Mở bằng AI
Tra cứu tên người nộp thuế, địa chỉ và trạng thái để hỗ trợ điền thông tin người mua hóa đơn. API không tạo hoặc phát hành hóa đơn.
Request
GET https://api.pay2s.vn/userapi/tax-lookup?mst=0317646674
pay2s-token: BASE64_SECRET_KEY
Accept: application/json
| Thành phần | Bắt buộc | Ý nghĩa |
|---|---|---|
Query mst |
Có | Chuỗi mã số thuế; giữ số 0 đầu, không chuyển thành số |
Header pay2s-token |
Có | Base64 chuẩn của chuỗi Secret Key UTF-8, mã hóa đúng một lần |
API tra cứu dùng GET, không gửi JSON body. POST tới đường dẫn này không dùng để tra cứu.
Mã doanh nghiệp được hỗ trợ: 10 hoặc 13 chữ số, hoặc mã đơn vị phụ thuộc dạng 0123456789-001. Tra cứu mã định danh cá nhân 12 số chỉ dành cho tài khoản được Pay2S phê duyệt riêng; tài khoản chưa được cấp quyền nhận HTTP 403.
Tài khoản cần gói đang hoạt động, hỗ trợ từ Basic trở lên; gói Free35 không được dùng. Secret Key cửa hàng cũng được hỗ trợ khi khóa và cửa hàng đang hoạt động, kiểm tra gói của tài khoản chủ.
Lấy Secret Key ở đâu?
- Đăng nhập tài khoản Pay2S tại trang Tích hợp Website/Application.
- Nếu đi từ menu, chọn Tích hợp → Website/Application.
- Tìm dòng Secret key, bấm nút sao chép ở dòng đó. Không lấy Partner code hoặc Access key.
- Dán Secret Key vào công cụ bên dưới, bấm Tạo pay2s-token, rồi Sao chép token.
Nếu thấy thông báo “Khóa tích hợp đang được bảo vệ”, hãy dùng tài khoản chính hoặc nhờ chủ tài khoản cấp quyền xem và sao chép khóa tích hợp.
Chuyển Secret Key thành pay2s-token
pay2s-token được tạo bằng Base64 của nguyên chuỗi Secret Key, đúng một lần. Không cần đăng ký hoặc xin thêm token riêng.
Ví dụ minh họa (không dùng để gọi API thật):
Secret Key: example-secret
pay2s-token: ZXhhbXBsZS1zZWNyZXQ=
Công cụ trên trang tài liệu chuyển đổi ngay trong trình duyệt, không gửi khóa lên máy chủ và không lưu khóa vào bộ nhớ trình duyệt. Base64 có thể giải mã ngược: giữ kín cả Secret Key và token, không gửi cho AI hoặc đặt trong mã frontend công khai.
Dán token vào đâu?
Trong Postman → Headers, thêm dòng:
| Key | Value |
|---|---|
pay2s-token |
Dán token vừa sao chép |
Content-Type |
application/json nếu API gửi JSON body |
Ở tab Authorization, chọn No Auth. Giá trị header chỉ là token: không thêm Bearer, Basic hoặc dấu ngoặc kép.
Nếu tự viết backend, có thể tạo token trực tiếp:
// Node.js — Secret Key lấy từ biến môi trường của backend
const token = Buffer.from(process.env.PAY2S_SECRET_KEY, 'utf8').toString('base64');
// Gửi header: { 'pay2s-token': token }
// PHP — Secret Key lấy từ biến môi trường của backend
$token = base64_encode(getenv('PAY2S_SECRET_KEY'));
// Gửi header: 'pay2s-token: ' . $token
Lỗi thường gặp: sao chép nhầm Access key; dùng nguyên Secret Key chưa chuyển đổi; chuyển Base64 hai lần; dính khoảng trắng hoặc xuống dòng; dùng token cũ sau khi đã đổi Secret Key. Đây không phải JWT hoặc token đăng nhập Dashboard.
Chi tiết xác thực
pay2s-token = Base64(UTF8(Secret Key))
Đây không phải JWT, không phải Access Key, không phải token đăng nhập Dashboard và không phải Base64(accessKey:secretKey). Không thêm tiền tố Bearer hoặc Basic. Không dùng HMAC hay bộ header X-Signature của API tạo hóa đơn điện tử.
Ví dụ minh họa, không phải khóa dùng thật:
Secret Key: example-secret
pay2s-token: ZXhhbXBsZS1zZWNyZXQ=
Nếu đã có token Base64 đúng định dạng thì dùng trực tiếp, không mã hóa lần hai. Base64 có thể giải mã ngược nên token phải được bảo vệ như Secret Key: chỉ dùng trên backend, không đặt trong URL, frontend hoặc log.
Postman
Đặt pay2sSecretKey vào biến bí mật của môi trường Postman. Thêm Pre-request Script:
const secret = pm.environment.get('pay2sSecretKey');
if (!secret) throw new Error('Thiếu pay2sSecretKey');
pm.variables.set('pay2sToken', CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(secret)));
Trong Headers, đặt pay2s-token bằng {{pay2sToken}}. Phần Authorization chọn No Auth; không dùng đồng thời token đăng nhập hay Bearer tự sinh.
Ví dụ gọi API
cURL
PAY2S_TOKEN là token đã tạo từ Secret Key, lưu trong môi trường server:
curl --get 'https://api.pay2s.vn/userapi/tax-lookup' \
--data-urlencode 'mst=0317646674' \
--header "pay2s-token: $PAY2S_TOKEN" \
--header 'Accept: application/json'
Node.js (backend)
async function lookupTaxCode(mst) {
const secret = process.env.PAY2S_SECRET_KEY;
if (!secret) throw new Error('Thiếu PAY2S_SECRET_KEY');
const url = new URL('https://api.pay2s.vn/userapi/tax-lookup');
url.searchParams.set('mst', mst); // mst là chuỗi, giữ số 0 đầu
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(`${response.status}: ${result.message || 'Tra cứu thất bại'}`);
}
return result.data;
}
const taxpayer = await lookupTaxCode('0317646674');
// Hiển thị thông tin để người dùng kiểm tra; không tự phát hành hóa đơn ở đây.
PHP
$secret = getenv('PAY2S_SECRET_KEY');
if (!$secret) throw new RuntimeException('Thiếu PAY2S_SECRET_KEY');
$url = 'https://api.pay2s.vn/userapi/tax-lookup?' . http_build_query(['mst' => '0317646674']);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['pay2s-token: ' . base64_encode($secret), 'Accept: application/json'],
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($body === false) throw new RuntimeException($error);
$result = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if ($http !== 200 || ($result['status'] ?? false) !== true) {
throw new RuntimeException($result['message'] ?? 'Tra cứu thất bại');
}
$taxpayer = $result['data'];
Response thành công
HTTP 200, ví dụ theo cấu trúc hiện tại:
{
"status": true,
"message": "Tra cứu mã số thuế thành công.",
"data": {
"taxCode": "0317646674",
"companyName": "CÔNG TY TNHH CÔNG NGHỆ EZ",
"address": "Số 72, Đường số 6, KDC Cityland Park Hills, Phường Gò Vấp, Thành phố Hồ Chí Minh, Việt Nam",
"status": {
"code": "00",
"name": "NNT đã được cấp MST"
},
"canIssueInvoice": true
},
"meta": {
"fresh": true
},
"request_id": "TAX-20261010191943-ACF66C5E"
}
Tên/địa chỉ trong ví dụ là dữ liệu minh họa theo ảnh kết quả, không phải kết quả vừa tra cứu trực tiếp.
| Trường | Ý nghĩa |
|---|---|
status ngoài cùng |
Request tra cứu có thành công hay không |
data.taxCode |
Mã số thuế tìm được |
data.companyName |
Tên người nộp thuế/đơn vị |
data.address |
Địa chỉ do nguồn tra cứu trả về |
data.status.code |
Mã trạng thái người nộp thuế, chuỗi; giữ nguyên "00" |
data.status.name |
Mô tả trạng thái từ nguồn tra cứu |
data.canIssueInvoice |
Cờ khả năng xuất hóa đơn từ nguồn tra cứu; không có nghĩa đã phát hành hoặc đã được bật quyền Production trên Pay2S |
meta.fresh |
Bản hiện tại tra cứu mới, không dùng kết quả cache |
request_id |
Mã đối soát khi liên hệ hỗ trợ; cũng có ở header X-Request-ID khi vào bước tra cứu |
Bản phản hồi cũ có thể dùng meta.cached: false thay meta.fresh: true. Không dùng các trường meta để quyết định thanh toán hoặc phát hành hóa đơn.
Không nhầm status: true ngoài cùng với trạng thái thuế hợp lệ. Luồng tự động HĐĐT trên Pay2S chỉ tiếp tục với mã trạng thái thuế "00"; cần kiểm tra thông tin/mẫu và quyền phát hành như bình thường.
Lỗi và giới hạn
| HTTP | Cách xử lý |
|---|---|
| 401 | Thiếu/sai pay2s-token; kiểm tra Secret Key, Base64 đúng một lần, không thêm Bearer |
| 403 | Gói hết hạn/không đủ điều kiện hoặc chưa được cấp quyền tra cứu mã cá nhân |
| 404 | Không tìm thấy thông tin mã số thuế |
| 422 | MST sai định dạng |
| 429 | Vượt giới hạn tốc độ/ngày; đợi theo header Retry-After hoặc retry_after trong JSON |
| 502 / 504 | Nguồn tra cứu lỗi/timeout; thử lại có giãn cách, không tự kết luận MST sai |
| 503 | Dịch vụ phụ trợ chưa sẵn sàng; thử lại sau hoặc liên hệ hỗ trợ |
Giới hạn tốc độ được trả trong X-RateLimit-Limit, X-RateLimit-Remaining; hạn mức ngày trong X-Daily-RateLimit-Limit, X-Daily-RateLimit-Remaining. Đọc giá trị server trả về, không gọi lặp liên tục khi nhận 429.
Dùng với Collection Link V2 hoặc API HĐĐT
Sau khi người dùng kiểm tra kết quả:
| Kết quả tra cứu | Metadata Collection Link V2 | API tạo nháp HĐĐT |
|---|---|---|
taxCode |
customerInfo.taxCode |
buyer_tax_code |
companyName (đơn vị/doanh nghiệp) |
customerInfo.buyerCompanyName |
buyer_name |
address |
customerInfo.address |
buyer_address |
Không tự gán tên doanh nghiệp vào họ tên người liên hệ. Với cá nhân/hộ kinh doanh, kiểm tra đúng loại người mua trước khi ánh xạ.
Xem Collection Link V2, API hóa đơn điện tử và quy tắc dữ liệu người mua. Nếu Collection Link đã tự xử lý HĐĐT cho đơn, không đồng thời gọi tạo hóa đơn độc lập cho cùng đơn.
Request và response đối chiếu ngày 11/10/2026
Các mẫu dưới đây giữ cấu trúc trường và kiểu dữ liệu. Khóa, chữ ký, URL phiên đã được thay bằng placeholder; danh sách chỉ giữ tối đa hai phần tử và dữ liệu ảnh/PDF/XML dài được rút gọn. Không sao chép placeholder để gọi API thật.
Tra cứu mã số thuế
Đã gọi API demo/UAT.
GET /userapi/tax-lookup
Tham số path/query (không gửi JSON body):
{
"mst": "0317646674"
}
HTTP 200. Response:
{
"status": true,
"message": "Tra cứu mã số thuế thành công.",
"data": {
"taxCode": "0317646674",
"companyName": "CÔNG TY TNHH CÔNG NGHỆ EZ",
"address": "Số 72, Đường số 6, KDC Cityland Park Hills, Phường Gò Vấp, Thành phố Hồ Chí Minh, Việt Nam",
"status": {
"code": "00",
"name": "NNT đã được cấp MST"
},
"canIssueInvoice": true
},
"meta": {
"fresh": true
},
"request_id": "TAX-20261010191943-ACF66C5E"
}