Đồng bộ ví điện tử
API này dùng để đồng bộ thông tin ví điện tử của khách hàng với hệ thống Tingee trước khi thực hiện các dịch vụ liên kết tài khoản.
Sau khi gọi API thành công, hệ thống sẽ trả về đường dẫn redirectLink để khách hàng xác thực và cấp quyền cho Tingee.
POST
URLhttps://open-api.tingee.vn/v1/sync-wallet
API đồng bộ thông tin ví điện tử với hệ thống Tingee.
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). |
bankBin | string | ✓ | Mã BIN ví điện tử. Xem tại Danh sách ngân hàng/VĐT hỗ trợ. |
walletId | string | ✓ | ID ví điện tử/Số điện thoại đăng ký ví cần đồng bộ. |
fullName | string | ✓ | Họ và tên chủ ví điện tử. |
webhookUrl | string | ✕ | URL nhận thông báo kết quả giao dịch Chuyển tiền. Truyền nếu đối tác muốn sử dụng dịch vụ Chi hộ qua ví. |
Ví dụ mã nguồn
- cURL
- NestJS
- C#
- Java
- PHP
curl --location --request POST 'https://open-api.tingee.vn/v1/sync-wallet' \
--header 'accept: application/json' \
--header 'x-signature: YOUR_SIGNATURE' \
--header 'x-request-timestamp: 20250723142001111' \
--header 'x-client-id: YOUR_CLIENT_ID' \
--header 'Content-Type: application/json' \
--data '{
"bankBin": "BAOKIM",
"walletId": "0987654321",
"fullName": "NGUYEN VAN A",
"webhookUrl": "https://your-domain.com/webhook"
}'
import axios from "axios";
import { createHmac } from "crypto";
import { format } from 'date-fns';
async function syncWallet() {
const body = {
bankBin: 'BAOKIM',
walletId: '0987654321',
fullName: 'NGUYEN VAN A',
webhookUrl: 'https://your-domain.com/webhook'
};
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://open-api.tingee.vn/v1/sync-wallet', body, {
headers: {
accept: 'application/json',
'x-signature': signature,
'x-request-timestamp': timestamp,
'x-client-id': 'YOUR_CLIENT_ID',
'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 SyncWalletExample
{
private static readonly HttpClient client = new HttpClient();
public static async Task Main()
{
var body = new {
bankBin = "BAOKIM",
walletId = "0987654321",
fullName = "NGUYEN VAN A",
webhookUrl = "https://your-domain.com/webhook"
};
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://open-api.tingee.vn/v1/sync-wallet");
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 SyncWallet {
public static void main(String[] args) throws Exception {
String bodyJson = "{\"bankBin\":\"BAOKIM\",\"walletId\":\"0987654321\",\"fullName\":\"NGUYEN VAN A\",\"webhookUrl\":\"https://your-domain.com/webhook\"}";
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://open-api.tingee.vn/v1/sync-wallet"))
.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 syncWallet() {
$body = [
"bankBin" => "BAOKIM",
"walletId" => "0987654321",
"fullName" => "NGUYEN VAN A",
"webhookUrl" => "https://your-domain.com/webhook"
];
$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://open-api.tingee.vn/v1/sync-wallet",
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": {
"phoneNumber": "0987654321",
"name": "NGUYEN VAN A",
"walletId": "0987654321",
"redirectLink": "https://baokim.vn/authorize/..."
}
}
| 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.phoneNumber | string | Số điện thoại đăng ký ví. |
data.name | string | Tên khách hàng. |
data.walletId | string | ID ví điện tử. |
data.redirectLink | string | Link chuyển hướng yêu cầu khách hàng xác thực OTP để đồng bộ ví với Tingee. |
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. |