curl \
-H "X-FH-APIKEY: $FINHAY_API_KEY" \
-H "X-FH-TIMESTAMP: $TIMESTAMP_MS" \
-H "X-FH-NONCE: $NONCE_UUID" \
-H "X-FH-SIGNATURE: $SIGNATURE_HEX" \
"https://open-api.fhsc.com.vn/trading/accounts/$SUB_ACCOUNT_NORMAL/summary"import requests
url = "https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary"
headers = {
"X-FH-APIKEY": "<api-key>",
"X-FH-TIMESTAMP": "<api-key>",
"X-FH-NONCE": "<api-key>",
"X-FH-SIGNATURE": "<api-key>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {
'X-FH-APIKEY': '<api-key>',
'X-FH-TIMESTAMP': '<api-key>',
'X-FH-NONCE': '<api-key>',
'X-FH-SIGNATURE': '<api-key>'
}
};
fetch('https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-FH-APIKEY: <api-key>",
"X-FH-NONCE: <api-key>",
"X-FH-SIGNATURE: <api-key>",
"X-FH-TIMESTAMP: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-FH-APIKEY", "<api-key>")
req.Header.Add("X-FH-TIMESTAMP", "<api-key>")
req.Header.Add("X-FH-NONCE", "<api-key>")
req.Header.Add("X-FH-SIGNATURE", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary")
.header("X-FH-APIKEY", "<api-key>")
.header("X-FH-TIMESTAMP", "<api-key>")
.header("X-FH-NONCE", "<api-key>")
.header("X-FH-SIGNATURE", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-FH-APIKEY"] = '<api-key>'
request["X-FH-TIMESTAMP"] = '<api-key>'
request["X-FH-NONCE"] = '<api-key>'
request["X-FH-SIGNATURE"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"error_code": "0",
"message": "success",
"result": {
"balance": 12500000,
"ci_balance": 10000000,
"td_balance": 2500000,
"interest_balance": 0,
"ca_receiving": 0,
"receiving_t1": 0,
"receiving_t2": 0,
"receiving_t3": 0,
"securities_amt": 150000000,
"total_debt_amt": 0,
"secure_amt": 0,
"trf_buy_amt": 0,
"margin_amt": 0,
"t0_debt_amt": 0,
"advanced_amt": 0,
"df_debt_amt": 0,
"td_debt_amt": 0,
"cidepo_fee_acr": 0,
"net_asset_value": 162500000,
"mrcr_limit": 0,
"debt_amt": 0,
"advance_max_amt_fee": 0,
"receiving_amt": 0,
"margin_rate": 0,
"sms_fee_amt": 0,
"ibroker_fee_amt": 0,
"hold_balance": 0,
"mri_rate": 0,
"mrm_rate": 0,
"cidepo_fee": 0,
"td_int_amt": 0,
"add_vnd": 0,
"add_vnd_1": 0,
"core_bank": "VCB",
"bankacct_no": "0123456789",
"bank_name": "Vietcombank",
"emk_amt": 0,
"baldefovd": "0",
"mrcr_limit_max": 0
}
}{
"error_code": "400",
"message": "Invalid parameter"
}{
"error_code": "401",
"message": "Invalid signature"
}{
"error_code": "429",
"message": "Too many requests"
}{
"error_code": "500",
"message": "Internal server error"
}Chi tiết số dư, margin, dư nợ của tiểu khoản
Thông tin chi tiết của tiểu khoản — số dư, dư nợ, margin, tài sản ròng và thông tin ngân hàng liên kết.
curl \
-H "X-FH-APIKEY: $FINHAY_API_KEY" \
-H "X-FH-TIMESTAMP: $TIMESTAMP_MS" \
-H "X-FH-NONCE: $NONCE_UUID" \
-H "X-FH-SIGNATURE: $SIGNATURE_HEX" \
"https://open-api.fhsc.com.vn/trading/accounts/$SUB_ACCOUNT_NORMAL/summary"import requests
url = "https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary"
headers = {
"X-FH-APIKEY": "<api-key>",
"X-FH-TIMESTAMP": "<api-key>",
"X-FH-NONCE": "<api-key>",
"X-FH-SIGNATURE": "<api-key>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {
'X-FH-APIKEY': '<api-key>',
'X-FH-TIMESTAMP': '<api-key>',
'X-FH-NONCE': '<api-key>',
'X-FH-SIGNATURE': '<api-key>'
}
};
fetch('https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-FH-APIKEY: <api-key>",
"X-FH-NONCE: <api-key>",
"X-FH-SIGNATURE: <api-key>",
"X-FH-TIMESTAMP: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-FH-APIKEY", "<api-key>")
req.Header.Add("X-FH-TIMESTAMP", "<api-key>")
req.Header.Add("X-FH-NONCE", "<api-key>")
req.Header.Add("X-FH-SIGNATURE", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary")
.header("X-FH-APIKEY", "<api-key>")
.header("X-FH-TIMESTAMP", "<api-key>")
.header("X-FH-NONCE", "<api-key>")
.header("X-FH-SIGNATURE", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://open-api.fhsc.com.vn/trading/accounts/{subAccountId}/summary")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-FH-APIKEY"] = '<api-key>'
request["X-FH-TIMESTAMP"] = '<api-key>'
request["X-FH-NONCE"] = '<api-key>'
request["X-FH-SIGNATURE"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"error_code": "0",
"message": "success",
"result": {
"balance": 12500000,
"ci_balance": 10000000,
"td_balance": 2500000,
"interest_balance": 0,
"ca_receiving": 0,
"receiving_t1": 0,
"receiving_t2": 0,
"receiving_t3": 0,
"securities_amt": 150000000,
"total_debt_amt": 0,
"secure_amt": 0,
"trf_buy_amt": 0,
"margin_amt": 0,
"t0_debt_amt": 0,
"advanced_amt": 0,
"df_debt_amt": 0,
"td_debt_amt": 0,
"cidepo_fee_acr": 0,
"net_asset_value": 162500000,
"mrcr_limit": 0,
"debt_amt": 0,
"advance_max_amt_fee": 0,
"receiving_amt": 0,
"margin_rate": 0,
"sms_fee_amt": 0,
"ibroker_fee_amt": 0,
"hold_balance": 0,
"mri_rate": 0,
"mrm_rate": 0,
"cidepo_fee": 0,
"td_int_amt": 0,
"add_vnd": 0,
"add_vnd_1": 0,
"core_bank": "VCB",
"bankacct_no": "0123456789",
"bank_name": "Vietcombank",
"emk_amt": 0,
"baldefovd": "0",
"mrcr_limit_max": 0
}
}{
"error_code": "400",
"message": "Invalid parameter"
}{
"error_code": "401",
"message": "Invalid signature"
}{
"error_code": "429",
"message": "Too many requests"
}{
"error_code": "500",
"message": "Internal server error"
}Authorizations
API key dài hạn của client. Cấu hình 1 lần lúc khởi tạo; có thể wire thẳng
vào static setter của SDK tự-gen. Đi kèm với FINHAY_API_SECRET — secret
này chỉ dùng ở phía client để tính X-FH-SIGNATURE, không bao giờ
gửi qua mạng.
Unix time hiện tại tính bằng milliseconds, đưới dạng chuỗi số thập phân.
Được tính per-request bởi signing middleware. Không set thủ công — dùng middleware mẫu trong README.
UUIDv4 duy nhất per-request (ví dụ crypto.randomUUID()). Server cache
cặp (apiKey, nonce) trong 5 phút; nếu nonce được reuse với cùng apiKey
trong window này, request sẽ bị từ chối với AUTH_NONCE_REUSED (401).
Server chấp nhận chuỗi opaque bất kỳ về mặt kỹ thuật, nhưng nên dùng UUIDv4 để đảm bảo tính unique.
Được tính per-request bởi signing middleware. Không set thủ công — xem middleware mẫu trong tài liệu Authentication.
HMAC-SHA256 của canonical signing payload, encode hex (lowercase).
Signing payload:
{X-FH-TIMESTAMP}\n{METHOD}\n{REQUEST_PATH}[?{QUERY}]\n{BODYHASH}
?{QUERY}chỉ nối vào path khi request có query string.{BODYHASH}là chuỗi rỗng khi body rỗng (vẫn không có newline sau đó).
Được tính per-request bởi signing middleware. Không set thủ công — dùng middleware mẫu trong README.
Path Parameters
subAccountId được lấy từ bootstrap flow
(GET /users/v1/users/{userId}/sub-accounts), chọn NORMAL hoặc MARGIN
tuỳ mục đích.
"0001234567"
Response
Trả về result chứa toàn bộ field tài chính của tiểu khoản — số dư, dư nợ, margin, tài sản ròng, ngân hàng liên kết.
Các field chung của envelope trong mọi response của Finhay API.
error_codelà"0"(string) khi thành công, mã khác"0"khi lỗi.messagelà thông điệp ngắn từ server.