SFI External API — Banner app SFI Trade
Bộ ảnh banner hiển thị trong app SFI Trade — không cần đăng nhập khách hàng, chỉ xác thực bằng X-Api-Key.
https://a.sfi.com.vn/ekyc/ex_apiChínhhttps://b.sfi.com.vn/ekyc/ex_apiDự phòngTổng quan
Toàn bộ endpoint trong tài liệu này nằm trong entry point /ekyc/ex_api, dùng chung quy ước
?cmd={tên_lệnh} và chung khung phản hồi JSON. Khác với nhóm API giao dịch
(open_position, account_status…), các API ở đây không cần JWT và không gắn với tài khoản khách hàng nào.
Phần Tổng quan → Mã lỗi chung dùng chung cho mọi nhóm API công khai của /ekyc/ex_api;
phần riêng của nhóm này (tham số, cấu trúc dữ liệu, lưu ý nghiệp vụ) nằm ở khối bên dưới.
Danh mục endpoint
| Nhóm | Endpoint | Mô tả | Xác thực |
|---|---|---|---|
| 3 · Banner app SFI Trade | GET ?cmd=banners | Toàn bộ banner của cả 4 vị trí trong app, kèm thứ tự hiển thị | X-Api-Key |
Danh mục này là nguồn tra cứu nhanh của nhóm Banner app SFI Trade — mỗi endpoint có một mục mô tả chi tiết bên dưới.
Xác thực bằng API Key
Mọi request phải gửi kèm header:
X-Api-Key: {api_key_được_SFI_cấp}
Nếu thiếu hoặc sai key, server trả về HTTP 401 với body
{"success": false, "message": "Unauthorized."}.
Key được cấp riêng cho từng ứng dụng đối tác; vui lòng lưu ở phía server, không nhúng vào ứng dụng client.
X-Api-Key dùng chung cho tất cả nhóm API trong tài liệu này, và cũng chính là key dùng
cho guestcmd=login_request ở luồng OOB Auth.
Định dạng phản hồi
Toàn bộ API dùng chung khung phản hồi JSON của hệ thống SFI:
{
"success": true,
"message": "Thành công!",
"data": [ ... ],
"svr": "srv-01"
}
| Trường | Kiểu | Mô tả |
|---|---|---|
| success | boolean | Kết quả xử lý |
| message | string | Thông điệp (tiếng Việt) |
| data | array / object | Dữ liệu trả về. Rỗng ([]) khi lỗi; vắng mặt ở phản hồi lỗi xác thực JWT — xem Mã lỗi chung |
| svr | string | Định danh máy chủ xử lý (dùng khi báo lỗi) |
Mã lỗi chung
| HTTP | message | Nguyên nhân |
|---|---|---|
| 401 | Unauthorized. | Thiếu header X-Api-Key hoặc key không hợp lệ |
| 200 | [IAH] Phiên làm việc đã hết hạn. Vui lòng đăng nhập lại! | cmd không thuộc nhóm API công khai, hoặc gọi bằng phương thức khác GET — request rơi vào nhánh yêu cầu JWT. Phản hồi này không có khóa data. |
| 200 | (tuỳ nghiệp vụ) | Lỗi nghiệp vụ — xem success: false và message |
200 với
success: false. Client luôn phải kiểm tra trường success, không
chỉ dựa vào HTTP status. Mã lỗi riêng của nhóm này được liệt kê ở cuối khối bên dưới.
API Banner cho app SFI Trade
Bộ ảnh banner hiển thị trong app SFI Trade, do bộ phận CSKH của SFI cấu hình. Cả nhóm chỉ có một endpoint duy nhất: một lần gọi trả đủ banner của mọi vị trí, kèm thứ tự hiển thị — app không cần gọi riêng từng khu vực.
1 · Toàn bộ banner
?cmd=banners
Không có tham số truy vấn. data là một object gồm đúng bốn khoá vị trí
(top, body, academy, expert); mỗi khoá là một mảng
banner đã sắp sẵn theo đúng thứ tự cần hiển thị.
Request
curl 'https://a.sfi.com.vn/ekyc/ex_api?cmd=banners' \
-H 'X-Api-Key: YOUR_API_KEY'
Response
{
"success": true,
"message": "Thành công!",
"data": {
"top": [
{ "order": 1, "image": "https://img.saigonfutures.com/uploads/ab12-banner-top-1.jpg" },
{ "order": 2, "image": "https://img.saigonfutures.com/uploads/cd34-banner-top-2.jpg" }
],
"body": [
{ "order": 1, "image": "https://img.saigonfutures.com/uploads/ef56-banner-body-1.jpg" }
],
"academy": [
{ "order": 1, "image": "https://img.saigonfutures.com/uploads/gh78-banner-academy-1.jpg" }
],
"expert": [
{ "order": 1, "image": "https://img.saigonfutures.com/uploads/ij90-banner-expert-1.jpg" }
]
},
"svr": "srv-01"
}
[]. App phải xử lý được trường hợp rỗng (ẩn hẳn khu vực banner) thay vì coi là lỗi.
Thử ngay — ?cmd=banners
Không có tham số — một lần gọi trả đủ bốn vị trí.
2 · Bốn vị trí banner
| Khoá | Vị trí trong app | Ghi chú hiển thị |
|---|---|---|
| top | Banner đầu app | Khu vực đầu trang chủ |
| body | Banners thân app | Khu vực giữa trang chủ |
| academy | Banners học viện hàng hoá | Trong mục Học viện hàng hoá |
| expert | Banner khu vực chuyên gia | Trong mục Khu vực chuyên gia — xem tài liệu Hồ sơ chuyên gia |
order. Mỗi vị trí tối đa 20 ảnh.
3 · Trường dữ liệu banner
| Trường | Kiểu | Mô tả |
|---|---|---|
| order | int | Thứ tự hiển thị, bắt đầu từ 1 và liên tục trong từng vị trí |
| image | string (URL) | URL ảnh đầy đủ, không hết hạn — dùng trực tiếp, không cần ghép tiền tố |
order chỉ để app đối chiếu / log; nếu app tự sắp lại thì sắp tăng dần theo
order.
Mã lỗi riêng của nhóm
Không có. Endpoint chỉ trả lỗi chung của tài liệu (xem Mã lỗi chung) — vị trí chưa có banner là mảng rỗng, không phải lỗi.
Khuyến nghị tích hợp
- Gọi API từ máy chủ của đối tác, không gọi trực tiếp từ trình duyệt / app để tránh lộ API Key.
- Luôn kiểm tra
successtrước khi đọcdata; ghi lạisvrkhi cần báo lỗi cho SFI. - Cache dữ liệu ít thay đổi (ví dụ
news_products) và đặt TTL tối thiểu 1–5 phút cho dữ liệu danh sách. - Đồng bộ tăng dần bằng cách lưu
idlớn nhất đã lấy và dừng khi gặp lạiidđó. - Tôn trọng giới hạn phân trang (
size≤ 100) thay vì kéo toàn bộ kho dữ liệu trong một lần. - Đặt timeout hợp lý (5–10s) và retry có backoff; nếu domain chính chậm > 5s, chuyển sang domain dự phòng.
Ví dụ code
Hàm gọi chung dưới đây dùng được cho mọi endpoint công khai của /ekyc/ex_api — chỉ thay
cmd và tham số.
JavaScript (server-side / Node.js)
const BASE = 'https://a.sfi.com.vn/ekyc/ex_api';
const HEADERS = { 'X-Api-Key': process.env.SFI_API_KEY };
async function call(params) {
const qs = new URLSearchParams(params);
const res = await fetch(`${BASE}?${qs}`, { headers: HEADERS });
const body = await res.json();
if (!body.success) throw new Error(body.message);
return body.data;
}
// Một lần gọi trả đủ banner của cả bốn vị trí
const banners = await call({ cmd: 'banners' });
renderCarousel(banners.top);
renderCarousel(banners.body);
PHP
function sfiCall(array $params) {
$url = 'https://a.sfi.com.vn/ekyc/ex_api?' . http_build_query($params);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-Api-Key: ' . getenv('SFI_API_KEY')],
CURLOPT_TIMEOUT => 10,
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
if (empty($body['success'])) {
throw new RuntimeException($body['message'] ?? 'SFI API error');
}
return $body['data'];
}
$banners = sfiCall(['cmd' => 'banners']);