BƯỚC 4 — GỌI API GENERATE VIETQR CODE
Hướng dẫn thực hiện chi tiết bằng Postman + code mẫu (Node.js, Python, cURL)
1. Mục đích của Bước 4
Sau khi đã hoàn tất Bước 1–3 (kết nối kỹ thuật, lấy Access Token, đồng bộ thông tin tài khoản/điểm bán), Bước 4 thực hiện gọi API "Generate VietQR Code" để tạo mã QR thanh toán. Đây là API đối tác gọi mỗi khi cần sinh 1 mã QR mới để khách hàng quét và thanh toán trực tiếp vào tài khoản ngân hàng đã đăng ký.
• Input: thông tin tài khoản nhận tiền, số tiền (nếu có), nội dung, loại QR.
• Output: chuỗi mã QR (qrCode), link ảnh QR (qrLink) để hiển thị hoặc in ra cho khách quét.
2. Thông tin API
2.1. Endpoint
Môi trường Dev (Test/Kiểm thử):
POST https://dev.vietqr.org/vqr/api/qr/generate-customer
Môi trường Production (Golive/Vận hành):
POST https://api.vietqr.org/vqr/api/qr/generate-customer
Lưu ý: Luôn kiểm thử đầy đủ trên môi trường Dev trước khi chuyển sang gọi API trên Production.
2.2. Headers
Tên | Giá trị |
|---|---|
Content-Type | application/json |
Authorization | Bearer <token> — token lấy được khi gọi API Get Token của VietQR |
2.3. Ba loại mã QR (qrType)
qrType | Loại QR | Đặc điểm | Trường hợp dùng |
|---|---|---|---|
0 | VietQR động | Mã QR chỉ dùng được 1 lần, đã gắn sẵn số tiền + nội dung, hệ thống trả kết quả đối soát tự động qua orderId. | Thanh toán đơn hàng cụ thể (số tiền thay đổi theo đơn hàng). |
1 | VietQR tĩnh | Mã QR dùng lâu dài, không gắn số tiền cố định, khách tự nhập số tiền khi quét. | Bàn thu ngân, quầy dịch vụ dùng nhiều lần. |
3 | VietQR bán động | Mã QR gắn với 1 điểm bán + 1 sản phẩm/dịch vụ cụ thể, có số tiền cố định theo sản phẩm. | Bán sản phẩm/gói dịch vụ có giá niêm yết cố định. |
2.4. Tham số Body (Request)
Tham số | Kiểu dữ liệu | Bắt buộc | Mô tả | Điều kiện áp dụng |
|---|---|---|---|---|
bankCode | String | Bắt buộc | Mã ngân hàng của tài khoản nhận tiền (VD: MB, VCB, BIDV...). | Tất cả |
bankAccount | String | Bắt buộc | Số tài khoản ngân hàng dùng để tạo mã VietQR. | Tất cả |
userBankName | String | Bắt buộc | Họ tên chủ tài khoản, viết không dấu tiếng Việt. | Tất cả |
content | String | Bắt buộc | Nội dung chuyển tiền, tối đa 23 ký tự, không dấu, không ký tự đặc biệt. | Tất cả |
qrType | Integer | Bắt buộc | Loại mã QR cần tạo: 0 = QR động, 1 = QR tĩnh, 3 = QR bán động. | Tất cả |
amount | Long | Tuỳ loại | Số tiền cần thanh toán. | Bắt buộc nếu qrType = 0 hoặc 3 |
orderId | String | Tuỳ loại | Mã đơn hàng bên đối tác tự quản lý, tối đa 13 ký tự. Được trả về khi hệ thống nhận biến động số dư khớp với QR đã tạo. | Bắt buộc nếu qrType = 0 |
transType | String | Tuỳ loại | Loại giao dịch: "C" (ghi có) hoặc "D" (ghi nợ). Mặc định là "C". | Bắt buộc nếu qrType = 0 |
terminalCode | String | Tuỳ loại | Mã cửa hàng / điểm bán đã đồng bộ trên hệ thống VietQR. | Bắt buộc nếu qrType = 1 hoặc 3 |
serviceCode | String | Tuỳ loại | Mã sản phẩm / dịch vụ được thanh toán. | Bắt buộc nếu qrType = 3 |
subTerminalCode | String | Tuỳ chọn | Mã cửa hàng / điểm bán phụ (nếu có). | Tuỳ chọn |
sign | String | Tuỳ chọn | Chữ ký xác thực dữ liệu (nếu đối tác có cấu hình chữ ký). | Tuỳ chọn |
urlLink | String | Tuỳ chọn | Trang sẽ chuyển đến sau khi người dùng quét và thanh toán thành công. | Tuỳ chọn |
note | String | Tuỳ chọn | Ghi chú nội bộ cho giao dịch. | Tuỳ chọn |
additionalData | List<Object> | Tuỳ chọn | Danh sách tham số bổ sung do đối tác tự định nghĩa. | Tuỳ chọn |
3. Kết quả trả về (Response)
Nếu tạo thành công (HTTP 200), API trả về đối tượng JSON chứa mã QR. Cấu trúc trả về giống nhau cho cả 3 loại qrType, chỉ khác giá trị của một số trường tương ứng.
Ví dụ Response thành công (QR động):
{
"bankCode": "MB",
"bankName": "Ngân hàng TMCP Quân đội",
"bankAccount": "0852240768",
"userBankName": "HA TRUNG HIEU",
"amount": "6868",
"content": "Test VA Account",
"qrCode": "00020101021238570010A00000072701...BE01",
"imgId": "58b7190b-a294-4b14-968f-cd365593893e",
"existing": 1,
"transactionId": "",
"transactionRefId": "MGEzMDIzNjktYThiZi00ZTFhLTlmNGEt...",
"qrLink": "https://pro.vietqr.vn/qr-generated?token=...",
"terminalCode": null,
"subTerminalCode": "",
"serviceCode": "",
"orderId": "TESTVA",
"additionalData": [],
"vaAccount": "VQRQACYEK5606"
}
Các trường quan trọng cần lưu lại phía đối tác:
• qrCode — chuỗi dữ liệu QR (dùng để tự vẽ ảnh QR nếu cần).
• qrLink — link ảnh/trang QR có sẵn, dùng hiển thị hoặc gửi cho khách ngay.
• transactionRefId — mã định danh giao dịch QR, nên lưu lại để tra soát.
• orderId — dùng để đối chiếu khi hệ thống báo có biến động số dư (đối với QR động).
Response lỗi (HTTP 400):
{
"status": "FAILED",
"message": "mô tả lỗi"
}
4. Hướng dẫn thực hiện chi tiết bằng Postman
Postman là công cụ phổ biến để test API trước khi tích hợp vào hệ thống. Dưới đây là các bước thực hiện cụ thể, dễ làm theo cho cả người không chuyên kỹ thuật.
4.1. Chuẩn bị
Bước 1: Cài đặt Postman — tải và cài Postman tại postman.com/downloads (bản Desktop) hoặc dùng trực tiếp trên trình duyệt qua tài khoản Postman miễn phí.
Bước 2: Chuẩn bị Access Token — gọi API Get Token của VietQR trước (Bước trước đó) để lấy token, dùng cho toàn bộ các request bên dưới.
Bước 3: Import file mẫu đi kèm tài liệu này — gồm 1 file Collection và 2 file Environment (Dev/Production), giúp không phải tự tạo request từ đầu.
• VietQR_Generate_API.postman_collection.json — bộ 3 request mẫu (QR động / tĩnh / bán động).
• VietQR_Dev.postman_environment.json — môi trường Dev, base_url = https://dev.vietqr.org.
• VietQR_Production.postman_environment.json — môi trường Production, base_url = https://api.vietqr.org.
4.2. Cách Import file mẫu vào Postman
Bước 1: Mở Postman — vào menu File → Import (hoặc bấm nút "Import" ở góc trên trái).
Bước 2: Kéo thả cả 3 file .json — vào cửa sổ Import, bấm "Import" để xác nhận. Postman sẽ tự tạo 1 Collection và 2 Environment.
Bước 3: Chọn Environment — ở góc trên phải màn hình Postman, chọn "VietQR - Dev (Test/Kiểm thử)" để test trước.
Bước 4: Nhập Access Token — bấm biểu tượng con mắt cạnh ô chọn Environment → Edit → dán token vào biến "token" → Save.
4.3. Cách tạo request thủ công (nếu không dùng file mẫu)
Bước 1: Tạo request mới — bấm "New" → "HTTP Request".
Bước 2: Chọn method và nhập URL — chọn method POST, nhập URL: https://dev.vietqr.org/vqr/api/qr/generate-customer (môi trường Dev).
Bước 3: Khai báo Headers — sang tab Headers, thêm 2 dòng: Content-Type = application/json, và Authorization = Bearer <token>.
Bước 4: Khai báo Body — sang tab Body → chọn "raw" → chọn định dạng "JSON" → dán nội dung JSON tương ứng loại QR cần tạo (xem ví dụ mục 4.4).
Bước 5: Gửi request — bấm nút "Send". Kết quả trả về hiển thị ở khung phía dưới (tab Body).
Bước 6: Kiểm tra kết quả — nếu Status = 200 OK, lấy giá trị qrCode hoặc qrLink để hiển thị mã QR cho khách quét. Nếu lỗi, đọc trường "message" để xác định nguyên nhân.
4.4. Body JSON mẫu cho từng loại QR (dùng trong Postman)
QR động (qrType = 0):
{
"bankCode": "MB",
"bankAccount": "0852240768",
"userBankName": "NGUYEN VAN A",
"content": "Thanh toan don hang 001",
"qrType": 0,
"amount": 100000,
"orderId": "ORDER001",
"transType": "C"
}
QR tĩnh (qrType = 1):
{
"bankCode": "MB",
"bankAccount": "0852240768",
"userBankName": "NGUYEN VAN A",
"content": "Thanh toan cua hang ABC",
"qrType": 1,
"terminalCode": "TERM001"
}
QR bán động (qrType = 3):
{
"bankCode": "MB",
"bankAccount": "0852240768",
"userBankName": "NGUYEN VAN A",
"content": "Thanh toan san pham XYZ",
"qrType": 3,
"amount": 50000,
"terminalCode": "TERM001",
"serviceCode": "SP001"
}
5. Code mẫu tích hợp
Các hàm mẫu dưới đây có thể copy trực tiếp vào hệ thống để gọi API tạo mã QR. Chỉ cần thay BASE_URL, TOKEN và nội dung payload theo dữ liệu thực tế.
5.1. cURL
Tạo QR động:
curl --location 'https://dev.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"bankCode": "MB",
"bankAccount": "0852240768",
"userBankName": "NGUYEN VAN A",
"content": "Thanh toan don hang 001",
"qrType": 0,
"amount": 100000,
"orderId": "ORDER001",
"transType": "C"
}'
Tạo QR tĩnh:
curl --location 'https://dev.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"bankCode": "MB",
"bankAccount": "0852240768",
"userBankName": "NGUYEN VAN A",
"content": "Thanh toan cua hang ABC",
"qrType": 1,
"terminalCode": "TERM001"
}'
Tạo QR bán động:
curl --location 'https://dev.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"bankCode": "MB",
"bankAccount": "0852240768",
"userBankName": "NGUYEN VAN A",
"content": "Thanh toan san pham XYZ",
"qrType": 3,
"amount": 50000,
"terminalCode": "TERM001",
"serviceCode": "SP001"
}'
5.2. Node.js (axios) — hàm mẫu dùng chung cho cả 3 loại QR
const axios = require('axios');
// env: 'dev' hoặc 'prod'
const BASE_URL = {
dev: 'https://dev.vietqr.org',
prod: 'https://api.vietqr.org',
};
/**
* Gọi API Generate VietQR Code
* @param {object} payload - du lieu QR (bankCode, bankAccount, qrType, ...)
* @param {string} token - access token lay tu API Get Token
* @param {'dev'|'prod'} env
*/
async function generateVietQRCode(payload, token, env = 'dev') {
const url = ${BASE_URL[env]}/vqr/api/qr/generate-customer;
try {
const res = await axios.post(url, payload, {
headers: {
'Content-Type': 'application/json',
'Authorization': Bearer ${token},
},
});
return res.data; // { qrCode, qrLink, transactionRefId, ... }
} catch (err) {
const msg = err.response ? err.response.data : err.message;
throw new Error(Generate VietQR that bai: ${JSON.stringify(msg)});
}
}
// Vi du goi ham - tao QR dong
generateVietQRCode({
bankCode: 'MB',
bankAccount: '0852240768',
userBankName: 'NGUYEN VAN A',
content: 'Thanh toan don hang 001',
qrType: 0,
amount: 100000,
orderId: 'ORDER001',
transType: 'C',
}, '<token>', 'dev')
.then((data) => console.log('QR link:', data.qrLink))
.catch((e) => console.error(e.message));
5.3. Python (requests) — hàm mẫu dùng chung cho cả 3 loại QR
import requests
BASE_URL = {
'dev': 'https://dev.vietqr.org',
'prod': 'https://api.vietqr.org',
}
def generate_vietqr_code(payload: dict, token: str, env: str = 'dev') -> dict:
"""Goi API Generate VietQR Code, tra ve du lieu QR (qrCode, qrLink, ...)."""
url = f"{BASE_URL[env]}/vqr/api/qr/generate-customer"
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}',
}
resp = requests.post(url, json=payload, headers=headers, timeout=15)
if resp.status_code != 200:
raise Exception(f'Generate VietQR that bai: {resp.text}')
return resp.json()
# Vi du goi ham - tao QR ban dong
if name == '__main__':
payload = {
'bankCode': 'MB',
'bankAccount': '0852240768',
'userBankName': 'NGUYEN VAN A',
'content': 'Thanh toan san pham XYZ',
'qrType': 3,
'amount': 50000,
'terminalCode': 'TERM001',
'serviceCode': 'SP001',
}
data = generate_vietqr_code(payload, token='<token>', env='dev')
print('QR code string:', data['qrCode'])
print('QR link:', data['qrLink'])
6. Xử lý lỗi thường gặp
Tình huống | Nguyên nhân / Cách xử lý |
|---|---|
HTTP 401 | Token hết hạn hoặc sai — gọi lại API Get Token để lấy token mới. |
HTTP 400 — status FAILED | Thiếu tham số bắt buộc theo qrType, hoặc sai định dạng (VD: content quá 23 ký tự, có dấu tiếng Việt). Đọc trường "message" trong response để biết chi tiết. |
Không nhận được kết quả (timeout) | Kiểm tra kết nối mạng, kiểm tra đúng URL môi trường (dev/production), thử lại sau ít phút. |
Không đối soát được giao dịch | Chỉ áp dụng cho QR động: kiểm tra lại orderId đã truyền đúng và duy nhất, tối đa 13 ký tự. |
7. Tệp đính kèm hỗ trợ
• VietQR_Generate_API.postman_collection.json — import trực tiếp vào Postman để có sẵn 3 request mẫu.
• VietQR_Dev.postman_environment.json — biến môi trường cho Dev.
• VietQR_Production.postman_environment.json — biến môi trường cho Production.