Create payment order
POST
URLhttps://open-api.tingee.vn/v1/direct-link/create-transfer
Create a straight-through disbursement payment order (for the VietinBank and BaoKim flows)
💡 Note on transaction processing (VietinBank)
With VietinBank, a single disbursement order is processed by the bank immediately after the order is created successfully. For batch disbursement transactions, however, the initial order status is
PENDINGand the bank continues posting afterwards. You need to call the transaction inquiry API to get the final processing result.
Header Request
| Header | Required | Description |
|---|---|---|
Content-Type | ✓ | application/json |
x-client-id | ✓ | Partner identifier issued by TINGEE. |
x-signature | ✓ | HMAC SHA512 authentication signature. |
x-request-timestamp | ✓ | Time the request is sent (format: yyyyMMddHHmmssSSS, UTC+7) |
Body Parameter
- VietinBank (Single)
- VietinBank (Batch)
- BaoKim (Single)
| Field | Type | Required | Description |
|---|---|---|---|
bankBin | string | ✓ | Bank BIN. Always pass 970415 (VietinBank's BIN) |
debitAccountNumber | string | ✓ | Payment (debit) account number. |
debitAccountName | string | ✕ | Payment account holder name. |
transactionType | string | ✓ | Transaction type, applied to all transactions in the order (VietinBank does not support transactionType at the records level): - in-bank: Within the bank - fast-out: NAPAS 247 fast transfer - regular-out: Standard interbank transfer |
feeMethod | string | ✕ | Fee method, applied to all transactions in the order: - O: The payment account pays the fee (default) - B: The receiving account pays the fee |
currency | string | ✕ | Posting currency of the payment account (default: VND) |
records | array | ✓ | Array with 1 item containing the transaction to disburse. |
Items in records
| Field | Type | Required | Description |
|---|---|---|---|
requestId | string | ✓ | Transaction reference generated by the partner, used to match results. Must be unique per transaction (no duplicates within the same request or with previously sent transactions), up to 50 characters. |
creditAccountNumber | string | ✓ | Recipient account number. |
creditAccountName | string | ✓ | Recipient account holder name (without diacritics, in UPPERCASE). |
amount | number | ✓ | Transaction amount (minimum 2,000 VND) |
creditBankBin | string | ✓ | Recipient bank BIN. See Supported banks. |
creditBranchCode | string | ✕ | Recipient bank branch code (if any). |
remark | string | ✓ | Transfer description / transaction details |
| Field | Type | Required | Description |
|---|---|---|---|
bankBin | string | ✓ | Bank BIN. Always pass 970415 (VietinBank's BIN) |
debitAccountNumber | string | ✓ | Payment (debit) account number. |
debitAccountName | string | ✕ | Payment account holder name. |
transactionType | string | ✓ | Transaction type, applied to all transactions in the order (VietinBank does not support transactionType at the records level): - in-bank: Within the bank - fast-out: NAPAS 247 fast transfer - regular-out: Standard interbank transfer |
feeMethod | string | ✕ | Fee method, applied to all transactions in the order: - O: The payment account pays the fee (default) - B: The receiving account pays the fee |
currency | string | ✕ | Posting currency of the payment account (default: VND) |
records | array | ✓ | Array with multiple items containing the transactions to disburse in the batch. |
Items in records
| Field | Type | Required | Description |
|---|---|---|---|
requestId | string | ✓ | Transaction reference generated by the partner, used to match results. Must be unique per transaction (no duplicates within the same request or with previously sent transactions), up to 50 characters. |
creditAccountNumber | string | ✓ | Recipient account number. |
creditAccountName | string | ✓ | Recipient account holder name (without diacritics, in UPPERCASE). |
amount | number | ✓ | Transaction amount (minimum 2,000 VND) |
creditBankBin | string | ✓ | Recipient bank BIN. See Supported banks. |
creditBranchCode | string | ✕ | Recipient bank branch code (if any). |
remark | string | ✓ | Transfer description / transaction details |
| Field | Type | Required | Description |
|---|---|---|---|
bankBin | string | ✓ | Bank BIN. Always pass BAOKIM |
currency | string | ✕ | Posting currency (default: VND) |
debitAccountNumber | string | ✓ | BaoKim account number / wallet ID to debit (a wallet linked to TINGEE). |
debitAccountName | string | ✕ | Debit wallet holder name (stored with the transaction for reconciliation). |
transactionType | string | ✕ | Transaction type: - withdrawal: Withdrawal from the wallet - Omitted or any other value ( fast-out, in-bank, regular-out): Transfer from the wallet (default fast-out) |
records | array | ✓ | Array with 1 item containing the transaction to disburse (BaoKim does not yet support multiple transactions in one request). |
Items in records
| Field | Type | Required | Description |
|---|---|---|---|
requestId | string | ✓ | Transaction reference generated by the partner, used to match results and for inquiries (transactionId). Must be unique per transaction, up to 50 characters. |
amount | number | ✓ | Transaction amount (minimum 2,000 VND) |
creditAccountNumber | string | ✓ | Recipient account number / card number / wallet number |
creditAccountName | string | ✕ | Recipient name (stored with the transaction and returned in the result). |
creditBankBin | string | ~ | Recipient bank BIN. See Supported banks. Not needed when creditAccountType = WALLET. |
creditAccountType | string | ✓ | Receiving account type - ACCOUNT : Receive to an account - CARD: Receive to a card number - WALLET: Receive to an e-wallet |
remark | string | ✓ | Transfer description / transaction details |
Sample Request Payload
Below are sample payloads for single and batch disbursement orders. Click any tab below — all the Code samples and Sample Response sections further down sync automatically to the scenario you pick!
- Single
- Batch
- BaoKim (Single)
{
"bankBin": "970415",
"debitAccountNumber": "117000107563",
"debitAccountName": "Customer Title 1",
"transactionType": "in-bank",
"feeMethod": "O",
"records": [
{
"requestId": "TRANS_0611_A03",
"creditAccountNumber": "103000614434",
"creditAccountName": "CUSTOMER TITLE 1",
"amount": 100000,
"creditBankBin": "970415",
"remark": "thanh toán"
}
]
}
{
"bankBin": "970415",
"debitAccountNumber": "117000107563",
"debitAccountName": "Customer Title 1",
"transactionType": "in-bank",
"feeMethod": "O",
"records": [
{
"requestId": "TRANS_0611_A01",
"creditAccountNumber": "103000614434",
"creditAccountName": "CUSTOMER TITLE 1",
"amount": 100000,
"creditBankBin": "970415",
"remark": "thanh toán"
},
{
"requestId": "TRANS_0611_A02",
"creditAccountNumber": "115000070017",
"creditAccountName": "Cty Huyen Trang Sua ten",
"amount": 100000,
"creditBankBin": "970415",
"remark": "thanh toán"
}
]
}
{
"bankBin": "BAOKIM",
"currency": "VND",
"debitAccountNumber": "84850000108",
"records": [
{
"requestId": "REQ31012",
"amount": 55666,
"creditAccountNumber": "100100132450",
"creditBankBin": "970432",
"creditAccountType": "ACCOUNT",
"remark": "test rút tiền về ví"
}
]
}
Code samples
- cURL
- NestJS
- C#
- Java
- PHP
curl --location --request POST 'https://open-api.tingee.vn/v1/direct-link/create-transfer' \
--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 '{
"bankBin": "970415",
"debitAccountNumber": "117000107563",
"debitAccountName": "Customer Title 1",
"transactionType": "in-bank",
"feeMethod": "O",
"records": [
{
"requestId": "TRANS_0611_A03",
"creditAccountNumber": "103000614434",
"creditAccountName": "CUSTOMER TITLE 1",
"amount": 100000,
"creditBankBin": "970415",
"remark": "thanh toán"
}
]
}'
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 directLinkCreateTransfer() {
const body = {
bankBin: "970415",
debitAccountNumber: "117000107563",
debitAccountName: "Customer Title 1",
transactionType: "in-bank",
feeMethod: "O",
records: [
{
requestId: "TRANS_0611_A03",
creditAccountNumber: "103000614434",
creditAccountName: "CUSTOMER TITLE 1",
amount: 100000,
creditBankBin: "970415",
remark: "thanh toán",
},
],
};
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/direct-link/create-transfer",
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);
}
directLinkCreateTransfer();
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
{
bankBin = "970415",
debitAccountNumber = "117000107563",
debitAccountName = "Customer Title 1",
transactionType = "in-bank",
feeMethod = "O",
records = new object[]
{
new
{
requestId = "TRANS_0611_A03",
creditAccountNumber = "103000614434",
creditAccountName = "CUSTOMER TITLE 1",
amount = 100000,
creditBankBin = "970415",
remark = "thanh toán"
}
}
};
// 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/direct-link/create-transfer");
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 = "{\"bankBin\":\"970415\",\"debitAccountNumber\":\"117000107563\",\"debitAccountName\":\"Customer Title 1\",\"transactionType\":\"in-bank\",\"feeMethod\":\"O\",\"records\":[{\"requestId\":\"TRANS_0611_A03\",\"creditAccountNumber\":\"103000614434\",\"creditAccountName\":\"CUSTOMER TITLE 1\",\"amount\":100000,\"creditBankBin\":\"970415\",\"remark\":\"thanh toán\"}]}";
// 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/direct-link/create-transfer"))
.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 = [
"bankBin" => "970415",
"debitAccountNumber" => "117000107563",
"debitAccountName" => "Customer Title 1",
"transactionType" => "in-bank",
"feeMethod" => "O",
"records" => [
[
"requestId" => "TRANS_0611_A03",
"creditAccountNumber" => "103000614434",
"creditAccountName" => "CUSTOMER TITLE 1",
"amount" => 100000,
"creditBankBin" => "970415",
"remark" => "thanh toán",
],
],
];
// 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/direct-link/create-transfer",
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);
- cURL
- NestJS
- C#
- Java
- PHP
curl --location --request POST 'https://open-api.tingee.vn/v1/direct-link/create-transfer' \
--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 '{
"bankBin": "970415",
"debitAccountNumber": "117000107563",
"debitAccountName": "Customer Title 1",
"transactionType": "in-bank",
"feeMethod": "O",
"records": [
{
"requestId": "TRANS_0611_A01",
"creditAccountNumber": "103000614434",
"creditAccountName": "CUSTOMER TITLE 1",
"amount": 100000,
"creditBankBin": "970415",
"remark": "thanh toán"
},
{
"requestId": "TRANS_0611_A02",
"creditAccountNumber": "115000070017",
"creditAccountName": "Cty Huyen Trang Sua ten",
"amount": 100000,
"creditBankBin": "970415",
"remark": "thanh toán"
}
]
}'
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 directLinkCreateTransfer() {
const body = {
bankBin: "970415",
debitAccountNumber: "117000107563",
debitAccountName: "Customer Title 1",
transactionType: "in-bank",
feeMethod: "O",
records: [
{
requestId: "TRANS_0611_A01",
creditAccountNumber: "103000614434",
creditAccountName: "CUSTOMER TITLE 1",
amount: 100000,
creditBankBin: "970415",
remark: "thanh toán",
},
{
requestId: "TRANS_0611_A02",
creditAccountNumber: "115000070017",
creditAccountName: "Cty Huyen Trang Sua ten",
amount: 100000,
creditBankBin: "970415",
remark: "thanh toán",
},
],
};
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/direct-link/create-transfer",
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);
}
directLinkCreateTransfer();
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
{
bankBin = "970415",
debitAccountNumber = "117000107563",
debitAccountName = "Customer Title 1",
transactionType = "in-bank",
feeMethod = "O",
records = new object[]
{
new
{
requestId = "TRANS_0611_A01",
creditAccountNumber = "103000614434",
creditAccountName = "CUSTOMER TITLE 1",
amount = 100000,
creditBankBin = "970415",
remark = "thanh toán"
},
new
{
requestId = "TRANS_0611_A02",
creditAccountNumber = "115000070017",
creditAccountName = "Cty Huyen Trang Sua ten",
amount = 100000,
creditBankBin = "970415",
remark = "thanh toán"
}
}
};
// 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/direct-link/create-transfer");
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 = "{\"bankBin\":\"970415\",\"debitAccountNumber\":\"117000107563\",\"debitAccountName\":\"Customer Title 1\",\"transactionType\":\"in-bank\",\"feeMethod\":\"O\",\"records\":[{\"requestId\":\"TRANS_0611_A01\",\"creditAccountNumber\":\"103000614434\",\"creditAccountName\":\"CUSTOMER TITLE 1\",\"amount\":100000,\"creditBankBin\":\"970415\",\"remark\":\"thanh toán\"},{\"requestId\":\"TRANS_0611_A02\",\"creditAccountNumber\":\"115000070017\",\"creditAccountName\":\"Cty Huyen Trang Sua ten\",\"amount\":100000,\"creditBankBin\":\"970415\",\"remark\":\"thanh toán\"}]}";
// 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/direct-link/create-transfer"))
.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 = [
"bankBin" => "970415",
"debitAccountNumber" => "117000107563",
"debitAccountName" => "Customer Title 1",
"transactionType" => "in-bank",
"feeMethod" => "O",
"records" => [
[
"requestId" => "TRANS_0611_A01",
"creditAccountNumber" => "103000614434",
"creditAccountName" => "CUSTOMER TITLE 1",
"amount" => 100000,
"creditBankBin" => "970415",
"remark" => "thanh toán",
],
[
"requestId" => "TRANS_0611_A02",
"creditAccountNumber" => "115000070017",
"creditAccountName" => "Cty Huyen Trang Sua ten",
"amount" => 100000,
"creditBankBin" => "970415",
"remark" => "thanh toán",
],
],
];
// 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/direct-link/create-transfer",
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);
- cURL
- NestJS
- C#
- Java
- PHP
curl --location --request POST 'https://open-api.tingee.vn/v1/direct-link/create-transfer' \
--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 '{
"bankBin": "BAOKIM",
"currency": "VND",
"debitAccountNumber": "84850000108",
"records": [
{
"requestId": "REQ31012",
"amount": 55666,
"creditAccountNumber": "100100132450",
"creditBankBin": "970432",
"creditAccountType": "ACCOUNT",
"remark": "test rút tiền về ví"
}
]
}'
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 directLinkCreateTransfer() {
const body = {
bankBin: "BAOKIM",
currency: "VND",
debitAccountNumber: "84850000108",
records: [
{
requestId: "REQ31012",
amount: 55666,
creditAccountNumber: "100100132450",
creditBankBin: "970432",
creditAccountType: "ACCOUNT",
remark: "test rút tiền về ví",
},
],
};
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/direct-link/create-transfer",
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);
}
directLinkCreateTransfer();
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
{
bankBin = "BAOKIM",
currency = "VND",
debitAccountNumber = "84850000108",
records = new object[]
{
new
{
requestId = "REQ31012",
amount = 55666,
creditAccountNumber = "100100132450",
creditBankBin = "970432",
creditAccountType = "ACCOUNT",
remark = "test rút tiền về ví"
}
}
};
// 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/direct-link/create-transfer");
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 = "{\"bankBin\":\"BAOKIM\",\"currency\":\"VND\",\"debitAccountNumber\":\"84850000108\",\"records\":[{\"requestId\":\"REQ31012\",\"amount\":55666,\"creditAccountNumber\":\"100100132450\",\"creditBankBin\":\"970432\",\"creditAccountType\":\"ACCOUNT\",\"remark\":\"test rút tiền về ví\"}]}";
// 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/direct-link/create-transfer"))
.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 = [
"bankBin" => "BAOKIM",
"currency" => "VND",
"debitAccountNumber" => "84850000108",
"records" => [
[
"requestId" => "REQ31012",
"amount" => 55666,
"creditAccountNumber" => "100100132450",
"creditBankBin" => "970432",
"creditAccountType" => "ACCOUNT",
"remark" => "test rút tiền về ví",
],
],
];
// 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/direct-link/create-transfer",
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
- Single
- Batch
- BaoKim (Single)
{
"code": "00",
"message": "Success",
"data": {
"totalRecords": 1,
"processedRecords": 1,
"batchId": null,
"records": [
{
"status": "SUCCESS",
"requestId": "TRANS_0611_A03",
"transactionId": "3NGiS-89m8nkbW5",
"message": "Giao dich hach toan thanh cong"
}
]
}
}
{
"code": "00",
"message": "Success",
"data": {
"totalRecords": 2,
"processedRecords": 0,
"batchId": "7CB875795D6B2F3374D3B489B09CAA92",
"records": [
{
"status": "PENDING",
"requestId": "TRANS_0611_A01",
"transactionId": null,
"message": "Dang pending cho xu ly hach toan"
},
{
"status": "PENDING",
"requestId": "TRANS_0611_A02",
"transactionId": null,
"message": "Dang pending cho xu ly hach toan"
}
]
}
}
{
"code": "00",
"message": "Success",
"data": {
"status": "SUCCESS",
"batchId": "eb3c9bb6-1c4c-4245-87c7-2d3640f72558",
"totalRecords": 1,
"records": [
{
"requestId": "REQ31012",
"status": "SUCCESS",
"amount": 55666,
"feeAmount": 0,
"creditAccountNumber": "100100132450",
"creditAccountName": null,
"transactionId": "REQ31012"
}
]
}
}
Response data structure
| Field | Type | Description |
|---|---|---|
status | string | Overall order status (BaoKim only): SUCCESS (accepted/processed) or FAILED (transaction failed). |
batchId | string | VietinBank: Transaction batch ID (only set for batch orders; single orders return null) — used to Query transactions. BaoKim: Disbursement order ID in the TINGEE system — use it as batchId when querying with inquiryType = BATCH_DETAIL. |
totalRecords | number | Total number of transactions in the disbursement order. |
processedRecords | number | Number of transactions already processed (VietinBank only). |
records | array | Detailed result of each transaction. |
Items in data.records
| Field | Type | Description |
|---|---|---|
requestId | string | The transaction reference you sent. |
status | string | Transaction status: - SUCCESS: Successful - PENDING: Pending (call the Query transactions API to get the final result) - FAILED: Failed |
transactionId | string | VietinBank: Transaction ID in the bank's system (null if not yet posted). BaoKim: Equal to requestId (used to query TRANSFER_DETAIL); null if the transaction failed. |
message | string | Detailed message or status explanation (VietinBank only). |
amount | number | Transaction amount (BaoKim only). |
feeAmount | number | Transaction fee charged by BaoKim (BaoKim only). |
creditAccountNumber | string | Recipient account number / card number / wallet number (BaoKim only). |
creditAccountName | string | Recipient name you sent (BaoKim only; null if not provided). |
error | object | Error information (BaoKim only, when status = FAILED), including code (error code) and message (error description). |
Common error codes
| Code | Description | How to handle |
|---|---|---|
1116 | The transaction reference (requestId) has already been used | Generate a new, unique requestId for each transaction. Look up the earlier transaction before resending to avoid a duplicate disbursement. |
1124 | requestId already exists (BAOKIM) | Use a new requestId; check the status of the earlier transaction with Query transactions before resending. |
1115 | The recipient bank could not be determined | Pass a valid creditBankBin for each record (see Banks). |
1117 | The BAOKIM wallet does not yet support multiple transactions in one request | Send only one record in records per request. |
1086, 1087, 1088 | The BAOKIM wallet has not been configured, has no wallet ID set up, or has not been synchronized | Complete linking and synchronizing the BAOKIM wallet with TINGEE before disbursing. |
1021 | The bank is not supported | Check bankBin; the automatic disbursement flow supports VietinBank (970415) and BAOKIM. |
90, 91, 92, 97 | Request authentication error (timestamp, client-id, signature) | See System error codes. |
Others | Other errors | See Error codes. |