Tạo QR động và đồng thời hiển thị lên loa
API này cho phép tạo mã QR động và hiển thị trực tiếp lên màn hình thiết bị TINGEEBOX mà không cần phải gọi API hiển thị QR.
note
API này chỉ áp dụng cho các thiết bị không phải TingeeBox 3LS.
POST
URLhttps://uat-open-api.tingee.vn/v1/device/generate-and-show-dynamic-qr-code
Tạo QR Code động và hiển thị ngay lên thiết bị TINGEEBOX để khách hàng quét thanh toán.
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ị. |
qrCodeType | string | ✓ | Loại QR động: - dynamic-one-time-payment: QR thanh toán duy nhất 1 lần.- dynamic-recurring-payment: QR thanh toán nhiều lần. |
vaAccountNumber | string | ✓ | Số tài khoản ảo. |
amount | number | ✓ | Giá trị hóa đơn. |
purpose | string | ✕ | Nội dung thanh toán. |
bankBin | string | ✓ | Mã BIN ngân hàng. Xem tại Danh sách ngân hàng hỗ trợ. |
expireInMinute | number | ✕ | Thời gian hiệu lực của QR (phút). Mặc định là 30 ngày. |
extraInfo | string | ✕ | Thông tin thêm khi tạo QR (Đối tác có thể truyền mã Bill...). |
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 loa (giây). Mặc định là 15 giây. |
playSound | boolean | ✕ | Phát tiếng kêu khi hiển thị QR. - true: Có kèm tiếng kêu.- false/không truyền: Không kèm tiếng kêu. |
readAmountAfterPay | boolean | ✕ | Đọc số tiền sau thanh toán thành công. - true: Tự động đọc số tiền qua Loa.- false/không truyền: Đối tác gọi API đọc số tiền để phát qua Loa. |
Ví dụ mã nguồn
- cURL
- NestJS
- C#
- Java
- PHP
curl --location --request POST 'https://uat-open-api.tingee.vn/v1/device/generate-and-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 '{
"uuid": "DEVICE_UUID",
"qrCodeType": "dynamic-one-time-payment",
"vaAccountNumber": "V1T123456789",
"amount": 150000,
"purpose": "Thanh toan don hang #001",
"bankName": "970422",
"expireInMinute": 5,
"firstText": "Quan ABC",
"showTime": 30,
"playSound": true,
"readAmountAfterPay": true
}'
import axios from "axios";
import { createHmac } from "crypto";
import { format } from 'date-fns';
async function generateAndShowQR() {
const body = {
uuid: "DEVICE_UUID",
qrCodeType: "dynamic-one-time-payment",
vaAccountNumber: "V1T123456789",
amount: 150000,
purpose: "Thanh toan don hang #001",
bankName: "970422",
expireInMinute: 5,
firstText: "Quan ABC",
showTime: 30,
playSound: true,
readAmountAfterPay: 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/generate-and-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 GenerateAndShowQRExample
{
private static readonly HttpClient client = new HttpClient();
public static async Task Main()
{
var body = new {
uuid = "DEVICE_UUID",
qrCodeType = "dynamic-one-time-payment",
vaAccountNumber = "V1T123456789",
amount = 150000,
purpose = "Thanh toan don hang #001",
bankName = "970422",
expireInMinute = 5,
firstText = "Quan ABC",
showTime = 30,
playSound = true,
readAmountAfterPay = 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/generate-and-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 GenerateAndShowQR {
public static void main(String[] args) throws Exception {
String bodyJson = "{"uuid":"DEVICE_UUID","qrCodeType":"dynamic-one-time-payment","vaAccountNumber":"V1T123456789","amount":150000,"bankName":"970422","showTime":30,"playSound":true,"readAmountAfterPay":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/generate-and-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 generateAndShowQR() {
$body = [
'uuid' => 'DEVICE_UUID',
'qrCodeType' => 'dynamic-one-time-payment',
'vaAccountNumber' => 'V1T123456789',
'amount' => 150000,
'purpose' => 'Thanh toan don hang #001',
'bankName' => '970422',
'expireInMinute' => 5,
'firstText' => 'Quan ABC',
'showTime' => 30,
'playSound' => true,
'readAmountAfterPay' => 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/generate-and-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": {
"qrCode": "00020101021238570010A...",
"qrAccount": "V1T123456789",
"billId": "BILL_20251110_001"
}
}
| 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. |
data.qrCode | string | Chuỗi QR Code động để hiển thị / quét. |
data.qrAccount | string | Số tài khoản ảo gắn với QR. |
data.billId | string | Mã hóa đơn tương ứng. |
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. |