In hoá đơn từ thiết bị
API này cho phép điều khiển thiết bị Tingee Box (dòng máy TINGEE MAX có hỗ trợ in) thực hiện in hoá đơn thanh toán hoặc hoá đơn biên nhận theo mẫu tuỳ chỉnh.
POST
URLhttps://uat-open-api.tingee.vn/v1/device/print-receipt
Gửi lệnh in hoá đơn xuống thiết bị Tingee Box MAX.
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ả |
|---|---|---|---|
uuid | string | ✓ | Mã định danh thiết bị. |
merchantId | number | ✕ | ID của Merchant (Bắt buộc nếu kết nối bằng tài khoản Master Merchant). |
copies | number | ✕ | Số bản in lặp lại (từ 1-9). Mặc định 1. |
logo | string | ✕ | Tên logo đã đăng ký trên thiết bị (VD: printer_receipt_logo). |
storeName | string | ✓ | Tên cửa hàng. |
address | string | ✕ | Địa chỉ cửa hàng. |
hotline | string | ✕ | Số hotline. |
orderCode | string | ✕ | Mã đơn hàng / Mã vận đơn. |
items | array | ✓ | Danh sách sản phẩm. |
totalAmount | number | ✓ | Tổng số tiền (VND). |
discount | number | ✕ | Giảm giá (VND). Mặc định 0. |
qrCode | string | ✕ | Nội dung mã QR. |
barcode | string | ✕ | Mã vạch Code128. |
footerNote | string | ✕ | Ghi chú / Lời cảm ơn cuối hoá đơn. |
voiceFile | number | ✕ | File âm thanh thông báo (1 đến 5: noti_voice1-5.mp3, 6: chỉ in không phát âm thanh). Mặc định 1. |
Cấu trúc phần tử items
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
name | string | ✓ | Tên sản phẩm. |
quantity | number | ✓ | Số lượng. |
unitPrice | number | ✓ | Đơn giá (VND). |
Ví dụ mã nguồn
- cURL
- NestJS
- C#
- Java
- PHP
curl --location --request POST 'https://uat-open-api.tingee.vn/v1/device/print-receipt' \
--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-001",
"copies": 1,
"storeName": "Cửa hàng tiện lợi",
"orderCode": "DH123456",
"totalAmount": 150000,
"items": [
{
"name": "Sản phẩm A",
"quantity": 1,
"unitPrice": 100000
},
{
"name": "Sản phẩm B",
"quantity": 1,
"unitPrice": 50000
}
],
"voiceFile": 6
}'
import axios from "axios";
import { createHmac } from "crypto";
import { format } from 'date-fns';
async function printReceipt() {
const body = {
uuid: 'DEVICE-001',
copies: 1,
storeName: "Cửa hàng tiện lợi",
orderCode: "DH123456",
totalAmount: 150000,
items: [
{ name: "Sản phẩm A", quantity: 1, unitPrice: 100000 },
{ name: "Sản phẩm B", quantity: 1, unitPrice: 50000 }
],
voiceFile: 6
};
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/print-receipt",
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 PrintReceiptExample
{
private static readonly HttpClient client = new HttpClient();
public static async Task Main()
{
var body = new {
uuid = "DEVICE-001",
copies = 1,
storeName = "Cửa hàng tiện lợi",
orderCode = "DH123456",
totalAmount = 150000,
items = new[] {
new { name = "Sản phẩm A", quantity = 1, unitPrice = 100000 },
new { name = "Sản phẩm B", quantity = 1, unitPrice = 50000 }
},
voiceFile = 6
};
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/print-receipt");
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 PrintReceipt {
public static void main(String[] args) throws Exception {
String bodyJson = "{\"uuid\":\"DEVICE-001\",\"copies\":1,\"storeName\":\"Cửa hàng tiện lợi\",\"orderCode\":\"DH123456\",\"totalAmount\":150000,\"items\":[{\"name\":\"Sản phẩm A\",\"quantity\":1,\"unitPrice\":100000},{\"name\":\"Sản phẩm B\",\"quantity\":1,\"unitPrice\":50000}],\"voiceFile\":6}";
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/print-receipt"))
.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 printReceipt() {
$body = [
'uuid' => 'DEVICE-001',
'copies' => 1,
'storeName' => 'Cửa hàng tiện lợi',
'orderCode' => 'DH123456',
'totalAmount' => 150000,
'items' => [
[ 'name' => 'Sản phẩm A', 'quantity' => 1, 'unitPrice' => 100000 ],
[ 'name' => 'Sản phẩm B', 'quantity' => 1, 'unitPrice' => 50000 ]
],
'voiceFile' => 6
];
$jsonBody = json_encode($body, JSON_UNESCAPED_UNICODE);
$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/print-receipt",
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. |