Hiển thị mã QR trên thiết bị
API này cho phép thiết bị TingeeBox hiển thị mã QR thanh toán trên màn hình. Chọn loại QR muốn hiển thị:
- 🔄 QR động
- 📄 QR tĩnh
POST
URLhttps://uat-open-api.tingee.vn/v1/device/show-dynamic-qr-code
Gửi mã QR động lên thiết bị TINGEEBOX để hiển thị cho khách hàng.
Lưu ý
Một số ngân hàng cho phép khách hàng tự ý chỉnh sửa số tiền khi quét QR động. Xem hướng dẫn xác thực giao dịch tại Lưu ý quan trọng — Giao dịch QR động.
Header Request
| Header | Bắt buộc | Mô tả |
|---|---|---|
Content-Type | ✓ | application/json |
x-client-id | ✓ | Mã định danh của đối tác do TINGEE cung cấp. |
x-signature | ✓ | Chữ ký xác thực HMAC SHA512. Xem thêm tại Cách sinh chữ ký. |
x-request-timestamp | ✓ | Thời gian gửi request (format: yyyyMMddHHmmssSSS, múi giờ UTC+7) |
Body Parameter
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
merchantId | number | ✕ | ID của Merchant (Bắt buộc nếu kết nối bằng tài khoản Master Merchant). |
uuid | string | ~ | Mã thiết bị. Bắt buộc nếu không truyền bankBin và vaAccountNumber. |
vaAccountNumber | string | ✕ | Số tài khoản VA hoặc tài khoản định danh. |
amount | number | ✓ | Số tiền cần thanh toán. |
qrCode | string | ✓ | Chuỗi QR Code động (Dynamic QR). |
bankBin | string | ✕ | Mã BIN ngân hàng. Xem tại Danh sách ngân hàng hỗ trợ. |
bankName | string | ✕ | Tên định danh ngân hàng (theo BankNameEnum). Dùng thay thế hoặc kết hợp với bankBin. |
deviceType | string | ✕ | Loại thiết bị. |
firstText | string | ✕ | Nội dung hiển thị kèm QR (dòng 1). |
secondText | string | ✕ | Nội dung hiển thị kèm QR (dòng 2). |
thirdText | string | ✕ | Nội dung hiển thị kèm QR (dòng 3). |
showTime | number | ✕ | Thời gian hiển thị QR trên màn hình (giây). |
isStaticQr | boolean | ✓ | Mặc định true — đánh dấu đây là QR động. |
playSound | boolean | ✕ | true để phát tiếng kêu khi hiển thị QR. |
Ví dụ mã nguồn
- cURL
- NestJS
- C#
- Java
- PHP
curl --location --request POST 'https://uat-open-api.tingee.vn/v1/device/show-dynamic-qr-code' \
--header 'accept: application/json' \
--header 'x-signature: YOUR_SIGNATURE' \
--header 'x-request-timestamp: 20251110175110111' \
--header 'x-client-id: YOUR_CLIENT_ID' \
--header 'Content-Type: application/json' \
--data '{
"vaAccountNumber": "V1T123456789",
"amount": 150000,
"qrCode": "00020101021138580010A000000727...",
"bankBin": "970422",
"isStaticQr": true
}'
import axios from "axios";
import { createHmac } from "crypto";
import { format } from 'date-fns';
async function showDynamicQrCode() {
const body = {
vaAccountNumber: "V1T123456789",
amount: 150000,
qrCode: "00020101021138580010A000000727...",
bankBin: "970422",
isStaticQr: true,
};
const timestamp = format(new Date(), "yyyyMMddHHmmssSSS");
const secretKey = "YOUR_SECRET_KEY";
const message = `${timestamp}:${JSON.stringify(body)}`;
const signature = createHmac('sha512', secretKey).update(message).digest('hex');
const res = await axios.post(
"https://uat-open-api.tingee.vn/v1/device/show-dynamic-qr-code",
body,
{
headers: {
"x-client-id": "YOUR_CLIENT_ID",
"x-request-timestamp": timestamp,
"x-signature": signature,
"Content-Type": "application/json",
},
}
);
console.log(res.data);
}
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Security.Cryptography;
using System.Threading.Tasks;
public class ShowDynamicQrCodeExample
{
private static readonly HttpClient client = new HttpClient();
public static async Task Main()
{
var body = new {
vaAccountNumber = "V1T123456789",
amount = 150000,
qrCode = "00020101021138580010A000000727...",
bankBin = "970422",
isStaticQr = true
};
var timestamp = DateTime.Now.ToString("yyyyMMddHHmmssfff");
var secretKey = "YOUR_SECRET_KEY";
var bodyJson = JsonSerializer.Serialize(body);
var message = $"{timestamp}:{bodyJson}";
var signature = CreateHmacSha512(secretKey, message);
var request = new HttpRequestMessage(HttpMethod.Post,
"https://uat-open-api.tingee.vn/v1/device/show-dynamic-qr-code");
request.Headers.Add("x-signature", signature);
request.Headers.Add("x-request-timestamp", timestamp);
request.Headers.Add("x-client-id", "YOUR_CLIENT_ID");
request.Content = new StringContent(bodyJson, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
private static string CreateHmacSha512(string key, string message)
{
using var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(key));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
}
import java.net.http.*;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class ShowDynamicQrCode {
public static void main(String[] args) throws Exception {
String bodyJson = "{\"vaAccountNumber\":\"V1T123456789\",\"amount\":150000,\"qrCode\":\"00020101021138580010A000000727...\",\"bankBin\":\"970422\",\"isStaticQr\":true}";
String secretKey = "YOUR_SECRET_KEY";
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
String message = timestamp + ":" + bodyJson;
String signature = hmacSha512(secretKey, message);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://uat-open-api.tingee.vn/v1/device/show-dynamic-qr-code"))
.header("accept", "application/json")
.header("x-signature", signature)
.header("x-request-timestamp", timestamp)
.header("x-client-id", "YOUR_CLIENT_ID")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(bodyJson))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
private static String hmacSha512(String key, String data) throws Exception {
Mac mac = Mac.getInstance("HmacSHA512");
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA512");
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
return toHex(hash);
}
private static String toHex(byte[] bytes) {
StringBuilder hex = new StringBuilder(bytes.length * 2);
for (byte b : bytes) {
hex.append(String.format("%02x", b));
}
return hex.toString();
}
}
function showDynamicQrCode() {
$body = [
'vaAccountNumber' => 'V1T123456789',
'amount' => 150000,
'qrCode' => '00020101021138580010A000000727...',
'bankBin' => '970422',
'isStaticQr' => true
];
$jsonBody = json_encode($body);
$timestamp = date("YmdHis") . substr((string)microtime(true), -3);
$secretKey = "YOUR_SECRET_KEY";
$message = $timestamp . ":" . $jsonBody;
$signature = hash_hmac("sha512", $message, $secretKey);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://uat-open-api.tingee.vn/v1/device/show-dynamic-qr-code",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $jsonBody,
CURLOPT_HTTPHEADER => [
"Accept: application/json",
"Content-Type: application/json",
"x-client-id: YOUR_CLIENT_ID",
"x-request-timestamp: " . $timestamp,
"x-signature: " . $signature
]
]);
$response = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
if ($err) {
echo "cURL Error: " . $err;
} else {
echo $response;
}
}
Response mẫu
{
"code": "00",
"message": "Success",
"data": {}
}
| Trường | Kiểu | Mô tả |
|---|---|---|
code | string | Mã kết quả (00 = Thành công). |
message | string | Thông điệp phản hồi. |
POST
URLhttps://uat-open-api.tingee.vn/v1/device/show-static-qr-code
Gửi mã QR tĩnh lên thiết bị TINGEEBOX để hiển thị cho khách hàng.
Header Request
| Header | Bắt buộc | Mô tả |
|---|---|---|
Content-Type | ✓ | application/json |
x-client-id | ✓ | Mã định danh của đối tác do TINGEE cung cấp. |
x-signature | ✓ | Chữ ký xác thực HMAC SHA512. Xem thêm tại Cách sinh chữ ký. |
x-request-timestamp | ✓ | Thời gian gửi request (format: yyyyMMddHHmmssSSS, múi giờ UTC+7) |
Body Parameter
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
merchantId | number | ✕ | ID của Merchant (Bắt buộc nếu kết nối bằng tài khoản Master Merchant). |
uuid | string | ~ | Mã thiết bị. Bắt buộc nếu không truyền bankBin và vaAccountNumber. |
vaAccountNumber | string | ✕ | Số tài khoản VA hoặc tài khoản định danh. |
amount | number | ✓ | Số tiền cần thanh toán. |
qrCode | string | ✓ | Chuỗi QR Code tĩnh (VietQR). |
bankBin | string | ✕ | Mã BIN ngân hàng. Xem tại Danh sách ngân hàng hỗ trợ. |
bankName | string | ✕ | Tên định danh ngân hàng (theo BankNameEnum). Dùng thay thế hoặc kết hợp với bankBin. |
deviceType | string | ✕ | Loại thiết bị. |
firstText | string | ✕ | Nội dung hiển thị kèm QR (dòng 1). |
secondText | string | ✕ | Nội dung hiển thị kèm QR (dòng 2). |
thirdText | string | ✕ | Nội dung hiển thị kèm QR (dòng 3). |
showTime | number | ✕ | Thời gian hiển thị QR trên màn hình (giây). |
playSound | boolean | ✕ | true để phát tiếng kêu khi hiển thị QR. |
Ví dụ mã nguồn
- cURL
- NestJS
- C#
- Java
- PHP
curl --location --request POST 'https://uat-open-api.tingee.vn/v1/device/show-static-qr-code' \
--header 'accept: application/json' \
--header 'x-signature: YOUR_SIGNATURE' \
--header 'x-request-timestamp: 20251110175110111' \
--header 'x-client-id: YOUR_CLIENT_ID' \
--header 'Content-Type: application/json' \
--data '{
"vaAccountNumber": "V1T123456789",
"amount": 150000,
"qrCode": "00020101021138580010A00000072701240006970422011001234567890208QRIBFTTA5204541153037045802VN62180814Thanh toan don6304CA68",
"bankBin": "970422"
}'
import axios from "axios";
import { createHmac } from "crypto";
import { format } from 'date-fns';
async function showStaticQrCode() {
const body = {
vaAccountNumber: "V1T123456789",
amount: 150000,
qrCode: "00020101021138580010A00000072701240006970422011001234567890208QRIBFTTA...",
bankBin: "970422",
};
const timestamp = format(new Date(), "yyyyMMddHHmmssSSS");
const secretKey = "YOUR_SECRET_KEY";
const message = `${timestamp}:${JSON.stringify(body)}`;
const signature = createHmac('sha512', secretKey).update(message).digest('hex');
const res = await axios.post(
"https://uat-open-api.tingee.vn/v1/device/show-static-qr-code",
body,
{
headers: {
"x-client-id": "YOUR_CLIENT_ID",
"x-request-timestamp": timestamp,
"x-signature": signature,
"Content-Type": "application/json",
},
}
);
console.log(res.data);
}
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Security.Cryptography;
using System.Threading.Tasks;
public class ShowStaticQrCodeExample
{
private static readonly HttpClient client = new HttpClient();
public static async Task Main()
{
var body = new {
vaAccountNumber = "V1T123456789",
amount = 150000,
qrCode = "00020101021138580010A00000072701240006970422...",
bankBin = "970422"
};
var timestamp = DateTime.Now.ToString("yyyyMMddHHmmssfff");
var secretKey = "YOUR_SECRET_KEY";
var bodyJson = JsonSerializer.Serialize(body);
var message = $"{timestamp}:{bodyJson}";
var signature = CreateHmacSha512(secretKey, message);
var request = new HttpRequestMessage(HttpMethod.Post,
"https://uat-open-api.tingee.vn/v1/device/show-static-qr-code");
request.Headers.Add("x-signature", signature);
request.Headers.Add("x-request-timestamp", timestamp);
request.Headers.Add("x-client-id", "YOUR_CLIENT_ID");
request.Content = new StringContent(bodyJson, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
private static string CreateHmacSha512(string key, string message)
{
using var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(key));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
}
import java.net.http.*;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class ShowStaticQrCode {
public static void main(String[] args) throws Exception {
String bodyJson = "{\"vaAccountNumber\":\"V1T123456789\",\"amount\":150000,\"qrCode\":\"00020101021138580010A000000727...\",\"bankBin\":\"970422\"}";
String secretKey = "YOUR_SECRET_KEY";
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
String message = timestamp + ":" + bodyJson;
String signature = hmacSha512(secretKey, message);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://uat-open-api.tingee.vn/v1/device/show-static-qr-code"))
.header("accept", "application/json")
.header("x-signature", signature)
.header("x-request-timestamp", timestamp)
.header("x-client-id", "YOUR_CLIENT_ID")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(bodyJson))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
private static String hmacSha512(String key, String data) throws Exception {
Mac mac = Mac.getInstance("HmacSHA512");
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA512");
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
return toHex(hash);
}
private static String toHex(byte[] bytes) {
StringBuilder hex = new StringBuilder(bytes.length * 2);
for (byte b : bytes) {
hex.append(String.format("%02x", b));
}
return hex.toString();
}
}
function showStaticQrCode() {
$body = [
'vaAccountNumber' => 'V1T123456789',
'amount' => 150000,
'qrCode' => '00020101021138580010A00000072701240006970422011001234567890208QRIBFTTA...',
'bankBin' => '970422'
];
$jsonBody = json_encode($body);
$timestamp = date("YmdHis") . substr((string)microtime(true), -3);
$secretKey = "YOUR_SECRET_KEY";
$message = $timestamp . ":" . $jsonBody;
$signature = hash_hmac("sha512", $message, $secretKey);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://uat-open-api.tingee.vn/v1/device/show-static-qr-code",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $jsonBody,
CURLOPT_HTTPHEADER => [
"Accept: application/json",
"Content-Type: application/json",
"x-client-id: YOUR_CLIENT_ID",
"x-request-timestamp: " . $timestamp,
"x-signature: " . $signature
]
]);
$response = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
if ($err) {
echo "cURL Error: " . $err;
} else {
echo $response;
}
}
Response mẫu
{
"code": "00",
"message": "Success",
"data": {}
}
| Trường | Kiểu | Mô tả |
|---|---|---|
code | string | Mã kết quả (00 = Thành công). |
message | string | Thông điệp phản hồi. |
Mã lỗi thường gặp
| Code | Mô tả | Hướng xử lý |
|---|---|---|
90 | Sai format timestamp | Kiểm tra format yyyyMMddHHmmssSSS. |
91 | Request quá hạn | Kiểm tra thời gian gửi request. |
97 | Sai chữ ký | Kiểm tra lại Secret Key và logic tạo Signature. |
Others | Lỗi khác | Xem Danh sách mã lỗi. |