Apinganhang API v1
REST API xác thực giao dịch ngân hàng, quản lý tài khoản, kết nối OTP, và tích hợp cổng thanh toán tự động.
| Thuộc tính | Giá trị |
|---|---|
| Base URL | https://client.apinganhang.net/api/v1 |
| Content-Type | application/json |
| Auth | Authorization: Bearer <token> |
| Encoding | UTF-8 |
GET /api/v1/ping.php — không cần token, trả {"ok":true}Xác thực
Tất cả endpoint (trừ ping.php) yêu cầu header Authorization: Bearer <token>.
Token nhận được từ endpoint POST /auth/login.php. Token không có thời hạn hết hạn — cookie được duy trì lâu dài trừ khi user đăng xuất hoặc admin reset token.
Mã lỗi & Response format
Mọi response đều là JSON với field success (boolean).
| HTTP | Ý nghĩa | Ví dụ |
|---|---|---|
200 | Thành công | {"success":true,"data":{...}} |
400 | Bad request / login bank thất bại | {"success":false,"message":"..."} |
401 | Chưa đăng nhập / token không hợp lệ | |
403 | Gói API hết hạn | |
404 | Không tìm thấy | |
405 | Method không hỗ trợ | |
422 | Thiếu / sai field | |
500 | Lỗi server |
Rate Limit
Chưa áp dụng rate limiting cứng. Khuyến nghị polling giao dịch tối đa mỗi 10–30 giây. Bank cron cập nhật mỗi 1 phút.
POST Login
Đăng nhập lấy token.
Request Body
| Field | Type | Required | Mô tả |
|---|---|---|---|
username | string | required | Tên đăng nhập |
password | string | required | Mật khẩu |
Response 200
| Field | Type | Mô tả |
|---|---|---|
success | boolean | true |
token | string | Bearer token |
user | object | { id, username, email, level, money, time_momo, id_telegram } |
GET Profile
Lấy thông tin user hiện tại. Có thể dùng để kiểm tra token còn hợp lệ.
Response 200
| Field | Type | Mô tả |
|---|---|---|
success | boolean | true |
data.id | integer | User ID |
data.username | string | Tên đăng nhập |
data.email | string | |
data.money | integer | Số dư tài khoản (VNĐ) |
data.time_momo | integer | Timestamp hết hạn gói API |
data.token | string | API Token hiện tại |
data.id_telegram | integer | Telegram chat ID nhận thông báo |
POST Logout
Hủy token hiện tại.
GET List accounts
Lấy danh sách tài khoản ngân hàng đã liên kết của user.
Query Parameters
| Param | Type | Mô tả |
|---|---|---|
bank | string | optional Lọc: MBBANK, BIDV, VIETCOMBANK, ACB, VIETTINBANK, SEABANK, VIETTEL |
Response 200
| Field | Type | Mô tả |
|---|---|---|
data[].id | integer | Account ID |
data[].bank_code | string | Mã ngân hàng |
data[].account_number | string | Số tài khoản |
data[].holder_name | string | Tên chủ TK |
data[].balance | number | Số dư (nếu lấy được) |
data[].active | integer | 1=đang hoạt động, 0=tạm dừng |
POST Add account
Thêm tài khoản ngân hàng mới.
Request Body
| Field | Type | Required | Mô tả |
|---|---|---|---|
bank_code | string | required | BIDV, MBBANK, ACB, VIETCOMBANK, VIETTINBANK, SEABANK, VIETTEL |
account_number | string | required | Số tài khoản (4-64 ký tự) |
holder_name | string | optional | Tên chủ TK |
login_id | string | optional | Username đăng nhập bank |
password | string | optional | Mật khẩu bank (mã hóa khi lưu) |
POST Connect account with OTP
Đăng nhập bank thực tế + xác thực OTP — không cần mở trang gốc ngân hàng.
Bước 1 — Request OTP
| Field | Type | Required | Mô tả |
|---|---|---|---|
action | string | required | "request_otp" |
bank_code | string | required | VD: "BIDV" |
login_id | string | required | Username SmartBanking |
password | string | required | Mật khẩu SmartBanking |
account_number | string | required | Số tài khoản |
Response — Cần OTP
{"success":true, "step":"otp_required", "message":"Mã OTP đã được gửi..."}
Bước 2 — Verify OTP
| Field | Type | Required | Mô tả |
|---|---|---|---|
action | string | required | "verify_otp" |
bank_code | string | required | Giống bước 1 |
login_id | string | required | Giống bước 1 |
password | string | required | Giống bước 1 |
account_number | string | required | Giống bước 1 |
otp | string | required | Mã OTP 6 số nhận qua SMS |
Response thành công
{"success":true, "step":"done", "data":{"id":68, "bank_code":"BIDV"}}
GET List transactions
Lấy danh sách giao dịch ngân hàng. Hỗ trợ phân trang, lọc, tìm kiếm.
Query Parameters
| Param | Type | Default | Mô tả |
|---|---|---|---|
page | integer | 1 | Trang hiện tại |
limit | integer | 20 | Số bản ghi/trang (max 100) |
bank | string | Lọc: MBBANK, BIDV, VIETCOMBANK, ACB, VIETTINBANK, SEABANK | |
type | string | INCOME (tiền vào) | EXPENSE (tiền ra) | |
date_from | string | Từ ngày: 2026-04-01 | |
date_to | string | Đến ngày: 2026-04-16 | |
search | string | Tìm nội dung / mã GD | |
account_id | integer | Lọc theo account ID |
Response 200
| Field | Type | Mô tả |
|---|---|---|
data[] | array | Danh sách giao dịch |
data[].id | integer | ID giao dịch |
data[].amount | number | Số tiền (dương = vào, âm = ra) |
data[].bank | string | Ngân hàng |
data[].ref_no | string | Mã giao dịch ngân hàng |
data[].description | string | Nội dung chuyển khoản |
data[].type | string | in | out |
data[].account | string | Số tài khoản |
data[].balance_after | number | Số dư sau giao dịch |
data[].transaction_time | string | Thời gian GD |
pagination | object | { page, limit, total, total_pages } |
totals | object | { total_in, total_out, net } |
GET Get transaction by ID
Lấy chi tiết 1 giao dịch.
GET Export CSV
Xuất file CSV giao dịch. Chấp nhận cùng query params như list.
GET Dashboard Summary
Tổng thu chi hôm nay, tuần, tháng, quý + 5 giao dịch mới nhất.
GET Dashboard Charts
Dữ liệu biểu đồ thu chi theo ngày (30 ngày gần nhất) + phân bổ danh mục.
GET Extension Info
Trạng thái gói API: ngày hết hạn, giá/tháng, còn bao nhiêu ngày.
POST Gia hạn gói
| Field | Type | Mô tả |
|---|---|---|
months | integer | Số tháng gia hạn (1-12) |
GET Deposit info
Thông tin nạp tiền: số dư, lịch sử nạp, min nạp.
GET Site Settings (logo, title)
Lấy cấu hình công khai: logo, title, description, hotline, link_facebook, link_zalo.
Response 200
| Field | Type | Mô tả |
|---|---|---|
data.title | string | Tên website |
data.description | string | Mô tả |
data.logo | string | URL logo |
data.hotline | string | Hotline |
data.link_facebook | string | Link Facebook |
data.link_zalo | string | Link Zalo |
GET Bank Packages
Danh sách gói ngân hàng admin đã cấu hình.
Response 200
| Field | Type | Mô tả |
|---|---|---|
data[].id | integer | ID gói |
data[].bank_code | string | Ngân hàng: MBBANK, BIDV, ... |
data[].name | string | Tên gói |
data[].price | integer | Giá (VNĐ/tháng) |
data[].features | string | Mô tả tính năng |
data[].active | integer | 1 = hiển thị, 0 = ẩn |
Payment Hub: Tich hop 1 lan, chay nhieu cong
Payment Hub gom SharkPay va WowPay theo mo hinh da tenant. Moi member tu cau hinh thong so rieng trong dashboard app.apinganhang.net, site doi tac chi goi 1 bo endpoint chung tai APInganhang.
Xem ban docs rieng cho doi tac thanh toan tai /api/v1/docs/payment-hub-docs.html.
- Cau hinh theo member: vao Tich hop API & Webhook, nhap thong tin gateway rieng (mch_id SharkPay, api_key WowPay, callback URL).
- Test ket noi: goi
POST /api/v1/payments/test.phpde check credential truoc khi mo live. - Tao lenh nap: goi
/payments/orders/create.phpvoigatewaylasharkpayhoacwowpay. - Doi soat trang thai: goi
/payments/orders/query.phpva cap nhat don hang noi bo. - Nhan callback: gateway callback ve APInganhang, he thong verify sign va IP roi moi forward xu ly.
GET Payment settings
Doc cau hinh gateway cua member hien tai. Secret key duoc mask, API khong tra plain-text secret.
Response 200
| Field | Type | Mo ta |
|---|---|---|
data.gateway | string | sharkpay hoac wowpay |
data.enabled | boolean | Trang thai bat/tat |
data.has_payin_secret_key | boolean | Da luu secret hay chua |
data.settings | object | Thong so public, secret duoc mask |
POST Save payment settings
Luu cau hinh gateway theo member. Neu gui secret rong, he thong giu nguyen secret cu.
Request Body (WowPay)
{
"gateway": "wowpay",
"enabled": true,
"settings": {
"merchant_no": "M123456",
"payin_secret_key": "wowpay-deposit-key",
"payout_secret_key": "wowpay-payout-key",
"notify_url": "https://your-site.com/payment/wowpay/callback",
"whitelist_ips": "1.2.3.4,5.6.7.8",
"callback_source_ips": "45.77.1.10,45.77.1.11"
}
}
api_key de map cho ca payin va payout, nhung khuyen nghi cau hinh tach 2 key de de xoay khoa va audit.Request Body (SharkPay)
{
"gateway": "sharkpay",
"enabled": true,
"settings": {
"mch_id": "SP998877",
"payin_secret_key": "secret-payin",
"payout_secret_key": "secret-payout",
"notify_url": "https://your-site.com/payment/sharkpay/callback",
"whitelist_ips": "1.2.3.4,5.6.7.8"
}
}
POST Test gateway connection
Kiem tra ket noi gateway bang cau hinh cua chinh member, dung cho QA truoc khi mo production.
| Field | Type | Required | Mo ta |
|---|---|---|---|
gateway | string | required | sharkpay hoac wowpay |
mode | string | optional | ap dung cho wowpay: payin hoac payout |
POST Create payin order
Tao lenh nap tien thong qua gateway da chon. Endpoint co kiem tra gateway bat/tat va whitelist IP runtime.
Request Body
| Field | Type | Required | Mo ta |
|---|---|---|---|
gateway | string | required | sharkpay hoac wowpay |
merchant_order_no | string | required | Ma don hang duy nhat phia doi tac |
amount | number | required | So tien can thu (VND, so nguyen). Co the gui 100000 hoac "100.000" (dau cham ngan cach hang nghin). |
subject | string | optional | SharkPay: tieu de don (mac dinh Pay + merchant_order_no) |
body | string | optional | SharkPay: mo ta don (mac dinh = subject) |
channel | string | optional | WowPay: momo, zalo, bankcard, bankcard_qr, bankcard_free |
device_ip | string | optional | IP client de doi soat whitelist |
POST Query payin order
Truy van trang thai lenh nap theo order_no hoac merchant_order_no tuy gateway.
POST Create payout order
Tao lenh chuyen tien/agentpay. Co ap dung whitelist IP tuong tu payin.
Callback endpoints
| Endpoint | Method | Mo ta |
|---|---|---|
/api/v1/payments/callbacks/sharkpay.php | GET, POST | Verify theo mch_id + sign roi forward noi bo. |
/api/v1/payments/callbacks/wowpay.php | POST | Verify sign va callback source IP truoc khi xu ly. |
OK nhanh khi xu ly thanh cong.GET Notifications
Lấy 100 thông báo gần nhất.
Use Case: Xác minh thanh toán tự động
Luồng xác minh giao dịch cho website bán hàng / SaaS / game topup.
- Tạo đơn hàng trên website với
order_codeduy nhất + số tiền. - Hiển thị QR / thông tin CK — yêu cầu khách ghi
order_codevào nội dung. - Polling API mỗi 10-30s:
GET /transactions/index.php?search={order_code}&type=INCOME&limit=5 - Khớp giao dịch: so
amount+descriptionchứaorder_code+type=in - Cập nhật đơn paid khi tìm thấy.
Use Case: Webhook Callback
Nhận push notification thay vì polling. Server gửi callback khi có giao dịch mới.
Payload mẫu
| Field | Type | Mô tả |
|---|---|---|
event | string | "transaction.confirmed" |
order_code | string | Mã đơn hàng |
amount | integer | Số tiền |
bank | string | Ngân hàng |
trans_id | string | Mã GD ngân hàng |
sign | string | HMAC-SHA256 chữ ký |
sign = hmac_sha256(secret, order_code|amount|trans_id|paid_at) trước khi xử lý.Use Case: OTP Flow — Kết nối BIDV trong app
- User nhập login_id + password + account_number BIDV SmartBanking.
- Gọi Step 1:
POST /accounts/connect.phpvớiaction: "request_otp". - Hệ thống login BIDV, BIDV gửi SMS OTP đến SĐT user.
- User nhập OTP vào ô trên app.
- Gọi Step 2:
POST /accounts/connect.phpvớiaction: "verify_otp"+otp: "123456". - Nếu đúng, tài khoản được lưu với session đã xác thực, cron tự động đồng bộ giao dịch.
Demo trực tiếp
Test API ngay từ trình duyệt.
Lấy thông tin tài khoản + token hiện tại.
* Giữ nguyên login_id/password/account từ Step 1
Lấy cấu hình site (logo, title, contact).
// Kết quả sẽ hiện ở đây...
Base URL
https://client.apinganhang.net/api/v1
Auth Header
Authorization: Bearer eyJhbGci...
Login
curl -X POST https://client.apinganhang.net/api/v1/auth/login.php \
-H "Content-Type: application/json" \
-d '{"username":"demo","password":"123456"}'
200 Response:
{
"success": true,
"token": "eyJhbGci...",
"user": {
"id": 5,
"username": "demo",
"email": "[email protected]",
"money": 150000,
"time_momo": 1788998400
}
}
Profile
curl https://client.apinganhang.net/api/v1/auth/profile.php \
-H "Authorization: Bearer <token>"
200 Response:
{
"success": true,
"data": {
"id": 5,
"username": "demo",
"email": "[email protected]",
"money": 150000,
"time_momo": 1788998400,
"token": "eyJhbGci...",
"id_telegram": 123456789
}
}
List Accounts
curl "https://client.apinganhang.net/api/v1/accounts/index.php?bank=MBBANK" \
-H "Authorization: Bearer <token>"
200 Response:
{
"success": true,
"data": [
{
"id": 268,
"bank_code": "MBBANK",
"account_number": "0368492618",
"holder_name": "NGUYEN VAN A",
"balance": 19437345,
"active": 1
}
]
}
Connect OTP — Step 1
curl -X POST https://client.apinganhang.net/api/v1/accounts/connect.php \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"action": "request_otp",
"bank_code": "BIDV",
"login_id": "bidv_user",
"password": "bidv_pass",
"account_number": "8877172056"
}'
200
{
"success": true,
"step": "otp_required",
"message": "Mã OTP đã được gửi đến SĐT"
}
Connect OTP — Step 2
curl -X POST https://client.apinganhang.net/api/v1/accounts/connect.php \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"action": "verify_otp",
"bank_code": "BIDV",
"login_id": "bidv_user",
"password": "bidv_pass",
"account_number": "8877172056",
"otp": "123456"
}'
200
{
"success": true,
"step": "done",
"message": "Xác thực OTP thành công",
"data": { "id": 68, "bank_code": "BIDV" }
}
Transactions
# 20 giao dịch mới nhất
curl "https://client.apinganhang.net/api/v1/transactions/index.php?limit=20" \
-H "Authorization: Bearer <token>"
# Lọc theo bank + ngày
curl "https://client.apinganhang.net/api/v1/transactions/index.php?\
bank=MBBANK&date_from=2026-04-01&date_to=2026-04-16" \
-H "Authorization: Bearer <token>"
# Tìm kiếm
curl "https://client.apinganhang.net/api/v1/transactions/index.php?\
search=INV2026001&type=INCOME" \
-H "Authorization: Bearer <token>"
200
{
"success": true,
"data": [
{
"id": 25533,
"amount": 1000000,
"bank": "MBBANK",
"ref_no": "FT26105370000088",
"description": "NGUYEN VAN A CK",
"type": "in",
"account": "0368492618",
"balance_after": 19437345,
"transaction_time": "15/04/2026 09:30:00",
"created_at": 1776395400
}
],
"pagination": {
"page": 1, "limit": 20,
"total": 150, "total_pages": 8
},
"totals": {
"total_in": 5000000,
"total_out": 2000000,
"net": 3000000
}
}
Payment Hub - Save WowPay settings
curl -X POST https://client.apinganhang.net/api/v1/payments/settings.php \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"gateway": "wowpay",
"enabled": true,
"settings": {
"merchant_no": "M123456",
"payin_secret_key": "wowpay-deposit-key",
"payout_secret_key": "wowpay-payout-key",
"notify_url": "https://your-site.com/payment/wowpay/callback",
"whitelist_ips": "1.2.3.4,5.6.7.8"
}
}'
Payment Hub - Test gateway
curl -X POST https://client.apinganhang.net/api/v1/payments/test.php \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"gateway": "wowpay",
"mode": "payin"
}'
Payment Hub - Create payin order
curl -X POST https://client.apinganhang.net/api/v1/payments/orders/create.php \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"gateway": "wowpay",
"merchant_order_no": "INV20260522001",
"amount": 500000,
"channel": "bankcard_qr",
"device_ip": "1.2.3.4",
"notify_url": "https://your-site.com/payment/callback"
}'
Xác minh thanh toán (PHP)
<?php
$token = 'YOUR_TOKEN';
$base = 'https://client.apinganhang.net/api/v1';
$order = 'INV20260416001';
$expect = 500000;
$url = "$base/transactions/index.php?" .
http_build_query([
'search' => $order,
'type' => 'INCOME',
'limit' => 10,
]);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token",
],
CURLOPT_TIMEOUT => 15,
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
foreach ($res['data'] ?? [] as $txn) {
if (
abs($txn['amount']) === $expect &&
stripos($txn['description'], $order) !== false
) {
echo "Paid! ref={$txn['ref_no']}\n";
break;
}
}
?>
Xác minh thanh toán (Node.js)
const axios = require('axios');
const TOKEN = 'YOUR_TOKEN';
const BASE = 'https://client.apinganhang.net/api/v1';
async function verify(order, amount, bank) {
const { data } = await axios.get(
`${BASE}/transactions/index.php`,
{
params: { search: order, type: 'INCOME', limit: 10, bank },
headers: { Authorization: `Bearer ${TOKEN}` },
}
);
return (data.data || []).find(t =>
Math.abs(t.amount) === amount &&
(t.description || '').toLowerCase()
.includes(order.toLowerCase())
);
}
verify('INV20260416001', 500000, 'MBBANK')
.then(m => console.log(m ? 'Paid' : 'Pending'));
Webhook Callback Payload
POST https://your-site.com/payment/callback
Content-Type: application/json
{
"event": "transaction.confirmed",
"order_code": "INV20260416001",
"amount": 500000,
"bank": "MBBANK",
"trans_id": "FT26105370000088",
"account": "0368492618",
"paid_at": 1776395400,
"sign": "hmac_sha256(secret, ...)"
}
Verify Webhook Signature (PHP)
<?php
$secret = 'YOUR_SECRET';
$body = json_decode(
file_get_contents('php://input'), true
);
$expected = hash_hmac('sha256',
implode('|', [
$body['order_code'],
$body['amount'],
$body['trans_id'],
$body['paid_at'],
]),
$secret
);
if (!hash_equals($expected, $body['sign'])) {
http_response_code(403);
die('Invalid signature');
}
echo json_encode(['received' => true]);
?>
Payment Hub Callback Verify - SharkPay (PHP)
<?php
$payload = $_POST ?: json_decode(file_get_contents('php://input'), true);
$secret = 'SHARKPAY_PAYIN_SECRET';
$check = [
'mch_id' => (string)($payload['mch_id'] ?? ''),
'mch_order_no' => (string)($payload['mch_order_no'] ?? ''),
'order_no' => (string)($payload['order_no'] ?? ''),
'amount' => (string)($payload['amount'] ?? ''),
'status' => (string)($payload['status'] ?? ''),
];
ksort($check);
$parts = [];
foreach ($check as $k => $v) {
if ($v !== '') {
$parts[] = $k . '=' . $v;
}
}
$signBase = implode('&', $parts) . '&key=' . $secret;
$expected = strtoupper(md5($signBase));
if (!hash_equals($expected, strtoupper((string)($payload['sign'] ?? '')))) {
http_response_code(403);
echo 'INVALID_SIGN';
exit;
}
// Process idempotent here, then ack gateway.
echo 'OK';
?>
Payment Hub Callback Verify - WowPay (PHP)
<?php
$payload = json_decode(file_get_contents('php://input'), true) ?: [];
$secret = 'WOWPAY_DEPOSIT_KEY';
$check = $payload;
unset($check['sign'], $check['sign_type']);
ksort($check);
$parts = [];
foreach ($check as $k => $v) {
if ($v !== '' && $v !== null) {
$parts[] = $k . '=' . $v;
}
}
$signBase = implode('&', $parts) . '&key=' . $secret;
$expected = strtoupper(md5($signBase));
if (!hash_equals($expected, strtoupper((string)($payload['sign'] ?? '')))) {
http_response_code(403);
echo 'INVALID_SIGN';
exit;
}
// Process idempotent here, then ack gateway.
echo 'OK';
?>
Site Settings
curl https://client.apinganhang.net/api/v1/services/site-settings.php \
-H "Authorization: Bearer <token>"
200
{
"success": true,
"data": {
"title": "API Ngân hàng",
"description": "Hệ thống API ngân hàng...",
"logo": "https://client.apinganhang.net/public/assets/img/logo.png",
"hotline": "0123456789",
"link_facebook": "https://...",
"link_zalo": ""
}
}
Bank Packages
curl https://client.apinganhang.net/api/v1/services/packages.php \
-H "Authorization: Bearer <token>"
200
{
"success": true,
"data": [
{
"id": 1,
"bank_code": "MBBANK",
"name": "MB Bank API",
"price": 50000,
"features": "Thông báo GD, lấy số dư",
"active": 1
}
]
}