Xác thực API ngân hàng MONA Pay: Bearer token và X-Client-Secret

Cập nhật 03/09/2026Bản Markdownllms.txtopenapi.json

Video hướng dẫn

Xác thực API MONA Pay: Bearer token và X-Client-Secret · Xem trên YouTube
Xem transcript video (9 phần)

Gỡ lỗi xác thực API

API trả bốn trăm lẻ một dù token vừa lấy thường là do bạn đang trộn hai luồng xác thực hoặc thiếu X-Client-Secret. Trong video này, mình phân biệt token cho máy chủ với token đăng nhập, chỉ rõ request nào cần lớp bí mật thứ hai và cách đọc khung response. Cuối cùng, bạn sẽ biết xử lý token hết hạn, lỗi header và lỗi dữ liệu đầu vào.

Chọn base URL và token

Base URL production là https://api.monapay.vn; alias cũ https://ipn.mona.host vẫn chạy cho tích hợp trước năm hai nghìn không trăm hai mươi sáu. Mọi request, trừ đăng ký và đăng nhập, cần Authorization: Bearer <access_token>. Token có thể đến từ POST /api/v1/oauth/token dành cho máy chủ, hoặc POST /api/v1/client/login dành cho phiên người dùng trên dashboard.

Token cho máy chủ

Với máy chủ và AI agent, tạo khóa API để có client_id và client_secret, rồi gọi /api/v1/oauth/token bằng grant_type=client_credentials. Response trả access_token, token_type, expires_in và scope. Token này hết hạn sau ba nghìn sáu trăm giây; khi hết hạn chỉ cần gọi lại, không có refresh token. Hãy lưu hai thông tin gốc trong biến môi trường, không đưa username hay mật khẩu cho máy.

Token đăng nhập

Với đăng nhập bằng mật khẩu, gọi POST /api/v1/client/login cùng username và password. Response trả token có expires_in là tám mươi sáu nghìn bốn trăm giây, tương đương hai mươi bốn giờ. Hết hạn thì đăng nhập lại. Tài khoản bật xác thực hai lớp sẽ hỏi OTP trên web; tài liệu khuyên API trực tiếp dùng tài khoản chưa bật hai lớp hoặc liên hệ đội hỗ trợ.

Hai lớp xác thực

Quy tắc quan trọng nằm ở lệnh ghi. Token từ client/login bắt buộc kèm X-Client-Secret cho POST, PUT, PATCH và DELETE; thiếu sẽ trả bốn trăm lẻ một với thông báo Thiếu X-Client-Secret. Token từ oauth/token đã kiểm client_secret lúc cấp nên không bắt buộc gửi lại. Tuy vậy, SDK, MCP và tài liệu vẫn khuyến nghị luôn gửi để tăng thêm một lớp bảo vệ.

Đọc khung response

Mọi response thông thường được bọc trong ba trường. success là boolean cho biết nghiệp vụ hoàn tất hay lỗi. message là thông điệp ngắn để ghi log. data là object, array hoặc null chứa kết quả. Đừng chỉ nhìn mã HTTP rồi giả định thành công; hãy đọc cả success và message. Riêng lỗi kiểm tra dữ liệu trả HTTP bốn trăm hai mươi hai với detail[] liệt kê từng trường sai.

Kiểm token và đổi mật khẩu

Để tự kiểm tra token, gọi GET /api/v1/client/me với Bearer. Response cho biết tài khoản hiện tại, tên, trạng thái và thời điểm tạo. Nếu cần đổi mật khẩu, gọi PUT /api/v1/client/change-password với old_password, new_password, Bearer và X-Client-Secret. Token cũ vẫn chạy đến khi hết hạn; muốn cắt quyền sớm, bạn cần đăng nhập lại và thu hồi khóa trong mục API Keys.

Sửa lỗi 401 và 422

Lỗi phổ biến nhất là viết sai header Bearer hoặc quên khoảng trắng sau chữ Bearer. Bốn trăm lẻ một cũng có thể do token hết hạn hoặc sai thông tin đăng nhập. Bốn trăm hai mươi hai nghĩa là thiếu trường hay sai kiểu, hãy đọc detail[] thay vì thử ngẫu nhiên. Mã năm trăm là lỗi phía dịch vụ; thử lại sau vài giây và giữ nguyên message để báo khi lỗi lặp lại.

Mở docs và lấy khóa

Hai luồng lấy token, lệnh cURL, PHP và Node nằm tại monapay.vn/docs/api/xac-thuc. Bạn đăng ký tại my.monapay.vn, tạo khóa riêng cho từng hệ thống rồi thử client/me trước khi gọi endpoint nghiệp vụ. Nếu vẫn gặp lỗi xác thực, gọi tổng đài một chín không không, sáu ba sáu, sáu bốn tám để đội MONA hỗ trợ đối chiếu header.

Mọi lệnh gọi API MONA Pay cần header Authorization: Bearer <access_token>. Máy chủ và AI agent lấy token từ POST /api/v1/oauth/token; phiên dashboard lấy token từ POST /api/v1/client/login. Với token đăng nhập bằng mật khẩu, mọi lệnh ghi POST, PUT, PATCH và DELETE bắt buộc gửi thêm X-Client-Secret. Token client credentials không bắt buộc gửi lại header này, nhưng MONA Pay vẫn khuyến nghị luôn gửi. Mọi response đều bọc trong một khung chung {"success": true, "message": "...", "data": ...}.

Base URL

Môi trường URL
Production https://api.monapay.vn
Alias cũ (vẫn chạy, cho tích hợp trước 2026) https://ipn.mona.host

Tài khoản đăng ký xong dùng được ngay: đăng nhập, tạo API key, không cần ai duyệt. Muốn thử không tốn tiền: POST /api/v1/sandbox/transactions (Bearer + X-Client-Secret) với amount, description và tuỳ chọn số tài khoản, transaction_code → hệ tạo một giao dịch giả, bắn các kênh thông báo như tiền thật, không tính hạn mức. Chưa nối ngân hàng vẫn chạy được vì MONA Pay tự cấp VA SBX…; xem Sandbox.

Cách dành cho máy chủ và AI agent: client credentials

Không đưa username hay mật khẩu cho máy. Tạo API key ở dashboard (API Keys → Tạo key) để có client_id và client_secret, rồi đổi ra Bearer token:

Terminal
curl -X POST https://api.monapay.vn/api/v1/oauth/token \
  -d "grant_type=client_credentials&client_id=client_xxx&client_secret=xxx"
JSON
{ "success": true, "message": "Cấp access token thành công", "data": { "access_token": "…", "token_type": "Bearer", "expires_in": 3600, "scope": "*" } }

Token hạn 3.600 giây; hết hạn thì gọi lại, không cần refresh token. Máy chủ đã kiểm client_secret khi cấp token nên không bắt buộc gửi lại X-Client-Secret ở từng lệnh ghi. SDK và MCP chính thức vẫn gửi kèm, và MONA Pay khuyến nghị làm vậy để một token lộ qua log hoặc proxy cũng không thể tự ý đổi cấu hình. Tài khoản bật xác thực 2 lớp vẫn dùng cách này bình thường, vì OTP chỉ áp cho đăng nhập bằng mật khẩu. SDK và MCP của MONA Pay đọc MONAPAY_CLIENT_ID và MONAPAY_CLIENT_SECRET từ biến môi trường và tự làm bước cấp token.

Khung response chung

Mọi endpoint trả về cùng một khung, kể cả khi lỗi:

JSON
{
  "success": true,
  "message": "Success",
  "data": { }
}
Trường Kiểu Ý nghĩa
success boolean true khi xử lý xong, false khi lỗi nghiệp vụ
message string Thông điệp ngắn để log
data object / array / null Dữ liệu trả về, null nếu không có

Lỗi validate (thiếu trường, sai kiểu) trả HTTP 422 theo chuẩn FastAPI với detail[] liệt kê từng trường sai.

Hai lớp xác thực

Lớp Header Dùng khi Lấy ở đâu
Bearer token Authorization: Bearer <access_token> Mọi request (trừ đăng ký, đăng nhập) POST /api/v1/oauth/token (máy chủ, AI agent) hoặc POST /api/v1/client/login (dashboard)
Client secret X-Client-Secret: <client_secret> Bắt buộc cho POST, PUT, PATCH, DELETE với token từ client/login; khuyến nghị với token từ oauth/token POST /api/v1/client-keys/generate

Giữ token và secret ở biến môi trường, không ghi cứng trong code, không commit lên git.

  • Token từ POST /api/v1/client/login: mọi lệnh ghi POST, PUT, PATCH và DELETE bắt buộc kèm X-Client-Secret; thiếu header này, MONA Pay trả 401 Thiếu X-Client-Secret.
  • Token từ POST /api/v1/oauth/token: MONA Pay đã kiểm client_secret khi cấp token nên không đòi lại header ở từng lệnh ghi. SDK và MCP chính thức vẫn gửi kèm.

MONA Pay khuyến nghị luôn gửi X-Client-Secret để token lộ qua log hoặc proxy cũng không thể tự ý đổi cấu hình.

POST /api/v1/client/register-client

Tạo tài khoản mới. Không cần xác thực. Tài khoản tạo xong dùng được ngay, đăng nhập liền không cần duyệt. Đăng ký qua form tại my.monapay.vn/auth (tab Đăng ký) cũng đi qua đúng endpoint này.

Trường Kiểu Bắt buộc Ghi chú
username string (1-255) có Tên đăng nhập, dùng để login
password string (1-255) có Mật khẩu
name string (1-255) có Tên doanh nghiệp / tên hiển thị
Terminal
curl -X POST https://api.monapay.vn/api/v1/client/register-client \
  -H 'Content-Type: application/json' \
  -d '{"username":"shopabc","password":"MatKhauManh#2026","name":"Shop ABC"}'

Response 200/201:

JSON
{ "success": true, "message": "Client registered successfully", "data": {} }

POST /api/v1/client/login

Đổi username + mật khẩu lấy access_token. Không cần xác thực.

Trường Kiểu Bắt buộc
username string có
password string có

Response 200:

JSON
{
  "success": true,
  "message": "Login successful",
  "data": {
    "access_token": "Zx9...64-ky-tu-url-safe",
    "expires_in": 86400,
    "token_type": "Bearer"
  }
}

expires_in tính bằng giây. Hết hạn thì gọi login lại, không có refresh token. Nếu tài khoản bật 2FA trong dashboard, bước đăng nhập trên web sẽ hỏi thêm mã OTP; gọi API trực tiếp thì dùng tài khoản chưa bật 2FA hoặc liên hệ đội MONA.

cURL

Terminal
curl -X POST https://api.monapay.vn/api/v1/client/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"shopabc","password":"MatKhauManh#2026"}'

PHP

PHP
<?php
$res = json_decode(file_get_contents('https://api.monapay.vn/api/v1/client/login', false, stream_context_create([
    'http' => [
        'method'  => 'POST',
        'header'  => "Content-Type: application/json\r\n",
        'content' => json_encode(['username' => getenv('MONA_USER'), 'password' => getenv('MONA_PASS')]),
    ],
])), true);

if (empty($res['success'])) {
    throw new RuntimeException('Đăng nhập MONA Pay thất bại: ' . ($res['message'] ?? 'không rõ'));
}
$accessToken = $res['data']['access_token']; // lưu lại, dùng 24 giờ

Node

JavaScript
const res = await fetch('https://api.monapay.vn/api/v1/client/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ username: process.env.MONA_USER, password: process.env.MONA_PASS }),
});
const json = await res.json();
if (!json.success) throw new Error('Đăng nhập MONA Pay thất bại: ' + json.message);
const accessToken = json.data.access_token; // lưu lại, dùng 24 giờ

GET /api/v1/client/me

Thông tin tài khoản đang đăng nhập. Cần Bearer.

Terminal
curl https://api.monapay.vn/api/v1/client/me \
  -H "Authorization: Bearer $MONA_TOKEN"

Response: data gồm thông tin client (id, username, name, trạng thái kích hoạt, thời điểm tạo).

PUT /api/v1/client/change-password

Đổi mật khẩu của chính mình. Cần Bearer + X-Client-Secret.

Trường Kiểu Bắt buộc
old_password string có
new_password string có
Terminal
curl -X PUT https://api.monapay.vn/api/v1/client/change-password \
  -H "Authorization: Bearer $MONA_TOKEN" \
  -H "X-Client-Secret: $MONA_SECRET" \
  -H 'Content-Type: application/json' \
  -d '{"old_password":"MatKhauManh#2026","new_password":"MatKhauMoi#2026"}'

Đổi mật khẩu xong thì token cũ vẫn dùng được tới khi hết hạn; muốn cắt ngay thì đăng nhập lại và thu hồi key ở mục API keys.

Lỗi thường gặp

HTTP Nguyên nhân Cách xử lý
401 Sai username/mật khẩu hoặc token hết hạn Kiểm tra lại thông tin (tài khoản mới đăng nhập được ngay, không có bước chờ duyệt); token hết hạn thì login lại
401 Authorization scheme must be Bearer Header sai định dạng Đúng dạng Authorization: Bearer <token>, có khoảng trắng sau chữ Bearer
422 Thiếu trường bắt buộc hoặc sai kiểu Đọc detail[] trong body, sửa đúng tên trường
500 Lỗi phía MONA Pay Thử lại sau vài giây; lặp lại thì báo đội MONA kèm message

Bước tiếp theo

  1. Tạo API key để có X-Client-Secret.
  2. Nối tài khoản ACB, tạo tài khoản ảo.
  3. Cấu hình webhook để nhận thông báo tiền vào.