List devices (Merchant)
This API returns all TINGEEBOX devices linked to a Merchant. It supports keyword search and pagination.
POST
URLhttps://open-api.tingee.vn/v1/device/get-paging
Query a Merchant's devices with full details.
Header Request
| Header | Required | Description |
|---|---|---|
Content-Type | ✓ | application/json |
x-client-id | ✓ | Partner identifier issued by TINGEE. |
x-signature | ✓ | HMAC SHA512 authentication signature. See How to generate the signature. |
x-request-timestamp | ✓ | Time the request is sent (format: yyyyMMddHHmmssSSS, UTC+7) |
Body Parameter
| Field | Type | Required | Description |
|---|---|---|---|
filter | string | ✕ | Keyword for partial matching on device name, device code (uuid), Merchant phone number or employee name. |
skipCount | number | ✕ | Number of records to skip (pagination), minimum 0. |
maxResultCount | number | ✕ | Maximum number of records per page, from 1 to 2000 (larger values are capped at 2000). If omitted, all records are returned. |
sorting | string | ✕ | Not supported yet. The list is always sorted newest device first (id descending). |
merchantId | number | ✓ | ID of the sub-Merchant whose devices you want to list. This API is only for Master Merchant accounts. |
type | string | ✕ | Device type to filter by (per DeviceTypeEnum): app-tingee, tingee-box-f1, tingee-box-2a, tingee-box-2as, tingee-box-s1 (TingeeBox 3S), tingee-box-3ls, tingee-box-3pro, tingee-box-3vn, tingee-box-3vna, tingee-box-4ls, tingee-box-5s, tingee-box-5sa, tingee-box-6ls, tingee-box-6pro, tingee-box-6xs, vn-50, loa-pay, trusted-pay, pay-alert, tingee-box-3vn-mbb, tingee-box-3pro-mbb, tingee-box-3pro-x, tingee-box-max, tingee-box-8pro. |
Code samples
- cURL
- NestJS
- C#
- Java
- PHP
curl --location --request POST 'https://open-api.tingee.vn/v1/device/get-paging' \
--header 'accept: application/json' \
--header 'x-client-id: YOUR_CLIENT_ID' \
--header 'x-request-timestamp: 20240509154004003' \
--header 'x-signature: YOUR_SIGNATURE' \
--header 'Content-Type: application/json' \
--data '{
"skipCount": 0,
"maxResultCount": 10,
"merchantId": 123456
}'
import axios from "axios";
import { createHmac } from "crypto";
const CLIENT_ID = "YOUR_CLIENT_ID";
const SECRET_KEY = "YOUR_SECRET_KEY";
// Timestamp in UTC+7, format yyyyMMddHHmmssSSS
function getTimestamp() {
return new Date(Date.now() + 7 * 60 * 60 * 1000)
.toISOString()
.replace(/[-:TZ.]/g, "")
.slice(0, 17);
}
async function deviceGetPaging() {
const body = {
skipCount: 0,
maxResultCount: 10,
merchantId: 123456,
};
const bodyJson = JSON.stringify(body);
const timestamp = getTimestamp();
const signature = createHmac("sha512", SECRET_KEY)
.update(`${timestamp}:${bodyJson}`)
.digest("hex");
const res = await axios.request({
method: "POST",
url: "https://open-api.tingee.vn/v1/device/get-paging",
data: bodyJson,
headers: {
accept: "application/json",
"Content-Type": "application/json",
"x-client-id": CLIENT_ID,
"x-request-timestamp": timestamp,
"x-signature": signature,
},
});
console.log(res.data);
}
deviceGetPaging();
using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
public class Program
{
private const string ClientId = "YOUR_CLIENT_ID";
private const string SecretKey = "YOUR_SECRET_KEY";
private static readonly HttpClient Client = new HttpClient();
public static async Task Main()
{
var body = new
{
skipCount = 0,
maxResultCount = 10,
merchantId = 123456
};
// Do not escape non-ASCII / special characters so the JSON matches TINGEE's JSON.stringify
var jsonOptions = new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping };
var bodyJson = JsonSerializer.Serialize(body, jsonOptions);
// Timestamp in UTC+7, format yyyyMMddHHmmssSSS
var timestamp = DateTime.UtcNow.AddHours(7).ToString("yyyyMMddHHmmssfff");
var signature = HmacSha512(SecretKey, $"{timestamp}:{bodyJson}");
var request = new HttpRequestMessage(HttpMethod.Post, "https://open-api.tingee.vn/v1/device/get-paging");
request.Headers.Add("accept", "application/json");
request.Headers.Add("x-client-id", ClientId);
request.Headers.Add("x-request-timestamp", timestamp);
request.Headers.Add("x-signature", signature);
request.Content = new StringContent(bodyJson, Encoding.UTF8, "application/json");
var response = await Client.SendAsync(request);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
private static string HmacSha512(string key, string message)
{
using var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(key));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
return Convert.ToHexString(hash).ToLower();
}
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class Main {
private static final String CLIENT_ID = "YOUR_CLIENT_ID";
private static final String SECRET_KEY = "YOUR_SECRET_KEY";
public static void main(String[] args) throws Exception {
// Minified JSON, same as JSON.stringify()
String bodyJson = "{\"skipCount\":0,\"maxResultCount\":10,\"merchantId\":123456}";
// Timestamp in UTC+7, format yyyyMMddHHmmssSSS
String timestamp = ZonedDateTime.now(ZoneId.of("Asia/Ho_Chi_Minh"))
.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
String signature = hmacSha512(SECRET_KEY, timestamp + ":" + bodyJson);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://open-api.tingee.vn/v1/device/get-paging"))
.header("accept", "application/json")
.header("Content-Type", "application/json")
.header("x-client-id", CLIENT_ID)
.header("x-request-timestamp", timestamp)
.header("x-signature", signature)
.method("POST", HttpRequest.BodyPublishers.ofString(bodyJson, StandardCharsets.UTF_8))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.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");
mac.init(new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA512"));
byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
StringBuilder hex = new StringBuilder();
for (byte b : hash) hex.append(String.format("%02x", b));
return hex.toString();
}
}
<?php
$clientId = "YOUR_CLIENT_ID";
$secretKey = "YOUR_SECRET_KEY";
$body = [
"skipCount" => 0,
"maxResultCount" => 10,
"merchantId" => 123456,
];
// Do not escape "/" or non-ASCII characters so the JSON matches TINGEE's JSON.stringify
$bodyJson = json_encode($body, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
// Timestamp in UTC+7, format yyyyMMddHHmmssSSS
$now = new DateTime("now", new DateTimeZone("Asia/Ho_Chi_Minh"));
$timestamp = $now->format("YmdHisv");
$signature = hash_hmac("sha512", $timestamp . ":" . $bodyJson, $secretKey);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://open-api.tingee.vn/v1/device/get-paging",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $bodyJson,
CURLOPT_HTTPHEADER => [
"Accept: application/json",
"Content-Type: application/json",
"x-client-id: " . $clientId,
"x-request-timestamp: " . $timestamp,
"x-signature: " . $signature,
],
]);
$response = curl_exec($ch);
if ($response === false) {
echo "cURL Error: " . curl_error($ch);
} else {
echo $response;
}
curl_close($ch);
Sample Response
{
"code": "00",
"message": "Success",
"data": {
"totalCount": 1,
"items": [
{
"id": 1001,
"type": "tingee-box-3pro",
"uuid": "3PRO123456",
"name": "TINGEEBOX PRO 01",
"system": null,
"systemVersion": null,
"merchantId": 123456,
"masterMerchantId": 1000,
"merchantPhoneNumber": "0901234567",
"employeeName": null,
"status": "approved",
"useDate": "2025-01-01T10:00:00.000Z",
"expirationDate": "2026-01-01T10:00:00.000Z",
"warrantyDate": "2026-01-01T10:00:00.000Z",
"selectedBankNames": ["MBB"],
"securityCode": "123456",
"creationTime": "2024-12-20T08:00:00.000Z",
"assignedAgentId": null,
"simSerialNumber": null,
"simPhoneNumber": null,
"simProvider": null,
"simPlan": null,
"simExpirationDate": null,
"simActivationDate": null,
"shopDtos": [
{
"id": 101,
"name": "Cửa hàng ABC"
}
],
"merchantName": "Merchant ABC"
}
]
}
}
| Field | Type | Description |
|---|---|---|
code | string | Result code (00 = success). |
message | string | Response message. |
data.totalCount | number | Total number of records found. |
data.items | array | List of devices. |
data.items[].id | number | Device ID in the TINGEE system. |
data.items[].type | string | Device type (per DeviceTypeEnum). |
data.items[].uuid | string | Device UUID. |
data.items[].name | string | Device display name. |
data.items[].system | string | Device operating system (if any). |
data.items[].systemVersion | string | Operating system version (if any). |
data.items[].merchantId | number | ID of the Merchant that owns the device. |
data.items[].masterMerchantId | number | ID of the Master Merchant that manages the device. |
data.items[].merchantPhoneNumber | string | Merchant phone number associated with the device. |
data.items[].employeeName | string | Name of the employee in charge of the device. |
data.items[].status | string | Device status: waiting-progressing, approved, refuse. |
data.items[].useDate | string | Start-of-use date (date linked to the Merchant). |
data.items[].expirationDate | string | Device service expiration date. |
data.items[].warrantyDate | string | Warranty expiration date. |
data.items[].selectedBankNames | string[] | Banks the device is locked to (empty/null: not locked to any bank). |
data.items[].securityCode | string | Current device security code. |
data.items[].creationTime | string | Time the device was created in the system. |
data.items[].assignedAgentId | number | ID of the agent assigned to the device (if any). |
data.items[].agentName | string | Name of the agent assigned to the device (only returned when assignedAgentId is present). |
data.items[].simSerialNumber | string | Serial number of the SIM in the device (if any). |
data.items[].simPhoneNumber | string | SIM phone number (if any). |
data.items[].simProvider | string | SIM carrier (if any). |
data.items[].simPlan | string | SIM plan (if any). |
data.items[].simExpirationDate | string | SIM expiration date (if any). |
data.items[].simActivationDate | string | SIM activation date (if any). |
data.items[].shopDtos | array | Shops (belonging to the Master Merchant) linked to the device. |
data.items[].shopDtos[].id | number | Shop ID. |
data.items[].shopDtos[].name | string | Shop name. |
data.items[].merchantName | string | Name of the Merchant that owns the device. |
Common error codes
| Code | Description | How to handle |
|---|---|---|
1133 | Permission denied | This API is only for Master Merchant accounts; use the Master Merchant's API key. |
90, 91, 92, 97 | Request authentication error (timestamp, client-id, signature) | See System error codes. |
Others | Other errors | See Error codes. |