API giao dịch: tra cứu tiền vào theo tài khoản ảo
Video hướng dẫn
Xem transcript video (9 phần)
Giao dịch không biến mất
Webhook đến chậm hoặc server từng bị lỗi không có nghĩa giao dịch biến mất. MONA Pay vẫn lưu bản ghi ACB đã báo và cho bạn kéo lại theo tài khoản ảo. Trong video này, mình gọi API danh sách, đọc cấu trúc phân trang, hiểu từng trường quan trọng, đối soát bằng transaction_code và gửi lại thông báo cho đúng một giao dịch.
Query theo số VA
Gọi GET /api/v1/acb/virtual-account/transactions với Bearer. Query bắt buộc virtual_account_number, chẳng hạn MONA0000010234. page là số trang từ một, mặc định một. limit nhận từ một đến một trăm, mặc định mười. API kiểm tra VA có thuộc tài khoản của bạn rồi mới trả dữ liệu. Lệnh đọc này không cần X-Client-Secret.
Đọc phần phân trang
Trong response, data.data là mảng giao dịch. Phần phân trang có current_page, per_page, total, last_page, start, end, has_next và has_prev. Muốn đọc tiếp, tăng page khi has_next là true. Danh sách được sắp xếp giao dịch mới trước. Đừng nhầm data bọc ngoài với mảng data bên trong; đây là nguyên nhân dễ làm code nghĩ response rỗng. per_page phản ánh giới hạn đang dùng, còn total là tổng số bản ghi tìm thấy.
Hiểu trạng thái giao dịch
Các trường trạng thái gồm transaction_status, trong đó SUCCESS nghĩa là tiền đã vào; transaction_channel là kênh ACB ghi nhận; transaction_date là thời điểm giao dịch và effective_date là ngày hiệu lực ghi sổ. debit_or_credit bằng credit là tiền vào, debit là tiền ra. Webhook hiện phát cho tiền vào, nên khi đối soát bạn lọc bản ghi credit.
Khớp đúng khoản tiền
Các trường khớp tiền gồm amount, số nguyên VND; transaction_content, nội dung khách gõ hoặc QR điền sẵn; và transaction_code, mã tham chiếu ổn định dùng làm khóa chống trùng. account_number là tài khoản ACB thật. va_prefix_cd và va_nbr là đầu số cùng số VA, có thể null nếu tiền vào thẳng tài khoản chính. attributes chứa thêm thông tin người chuyển và ngân hàng chuyển.
Đối soát từng trang
Đối soát theo từng VA, bắt đầu trang đầu với giới hạn một trăm. Mỗi bản ghi, tìm transaction_code trong bảng nội bộ. Mã đã có thì bỏ qua; mã mới thì ghi và chạy cùng hàm xử lý đơn như webhook. Đọc trang tiếp theo khi has_next là true. Hiện chưa có since_id, nên có thể dừng khi gặp dữ liệu đã có và cũ hơn mốc lần chạy trước.
Gửi lại thông báo
Muốn gửi lại thông báo, lấy trường id của bản ghi rồi gọi POST /api/v1/acb/virtual-account/transactions/{transaction_id}/retry. Request cần Bearer và X-Client-Secret. Body bắt buộc có target_type là WEBHOOK hoặc TELEGRAM; target_id có thể chỉ định một cấu hình. Nếu bỏ target_id, hệ thống gửi theo mọi cấu hình đang bật và khớp giao dịch. Payload gửi lại vẫn cùng transaction_code, nên server phải bỏ qua nếu giao dịch đã xử lý.
Sửa lỗi truy vấn
API trả bốn trăm khi số VA không tồn tại hoặc không thuộc tài khoản; lấy lại số từ endpoint danh sách VA. Bốn trăm lẻ một là token hết hạn, hãy đăng nhập lại lấy token mới. Bốn trăm hai mươi hai thường do thiếu virtual_account_number hoặc limit lớn hơn một trăm. Retry trả bốn trăm lẻ bốn thì transaction_id sai; phải dùng id của giao dịch, không dùng transaction_code.
Mở docs và đối chiếu
Response đầy đủ, bảng giải nghĩa và code đọc mọi trang nằm tại monapay.vn/docs/api/giao-dich. Bạn đăng ký tại my.monapay.vn, mở mục Giao dịch để so một bản ghi dashboard với kết quả API thực tế trước khi đặt tác vụ đối soát. Nếu còn nhầm ID, số VA hoặc phân trang, 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ợ.
Mọi giao dịch ACB báo về đều được MONA Pay lưu lại, kể cả khi webhook tới server bạn thất bại. Truy vấn bằng GET /api/v1/acb/virtual-account/transactions?virtual_account_number=<số VA>&page=1&limit=100 (Bearer token, limit tối đa 100). Mỗi bản ghi có transaction_code là mã tham chiếu ổn định của ngân hàng, dùng làm khoá chống trùng khi đối soát. Giao dịch nào lỡ không tới được server thì gọi endpoint retry để MONA Pay gửi lại webhook hoặc tin Telegram cho đúng giao dịch đó.
GET /api/v1/acb/virtual-account/transactions
Cần Bearer. Hệ thống tìm VA theo số, kiểm tra VA thuộc tài khoản của bạn rồi mới trả giao dịch.
| Tham số (query) | Kiểu | Bắt buộc | Ghi chú |
|---|---|---|---|
virtual_account_number |
string | có | Số VA, ví dụ MONA0000010234 |
page |
integer ≥1 | không | Mặc định 1 |
limit |
integer 1-100 | không | Mặc định 10 |
Response 200:
Ý nghĩa từng trường
| Trường | Ý nghĩa |
|---|---|
id |
ID giao dịch trong MONA Pay, dùng cho endpoint retry |
transaction_status |
Trạng thái ACB trả về (SUCCESS là tiền đã vào) |
transaction_channel |
Kênh giao dịch theo ACB (chuyển khoản nhanh, QR…) |
transaction_date |
Thời điểm giao dịch, giờ Việt Nam |
effective_date |
Ngày hiệu lực ghi sổ |
debit_or_credit |
credit = tiền vào, debit = tiền ra. Webhook hiện chỉ bắn cho tiền vào |
amount |
Số tiền VND, số nguyên |
transaction_content |
Nội dung chuyển khoản khách gõ (hoặc QR điền sẵn) |
transaction_code |
Mã tham chiếu ngân hàng, ổn định qua mọi lần gửi lại, khoá chống trùng |
account_number |
Số tài khoản ACB thật nhận tiền |
va_prefix_cd, va_nbr |
Đầu số và số VA khớp giao dịch, null nếu tiền vào thẳng tài khoản chính |
attributes |
Thông tin phụ ACB gửi kèm: tên và số tài khoản người chuyển, ngân hàng chuyển, số tham chiếu, các trường custom1..custom10 nếu có |
Ngoài ra, cùng bản ghi này là thứ webhook gửi sang bạn dưới dạng rút gọn (xem Định dạng payload).
Đối soát bằng API
Hiện chưa có tham số since_id; đối soát theo cách sau (cron mỗi 15-30 phút hoặc cuối ngày):
- Với mỗi VA đang dùng, gọi trang 1 với
limit=100, đọc tiếp khihas_nextlàtrue. - Với mỗi bản ghi, tra
transaction_codetrong bảng giao dịch của bạn. Có rồi thì bỏ qua, chưa có thì ghi thêm và xử lý đơn như khi nhận webhook. - Dừng khi gặp
transaction_codeđã có vàtransaction_datecũ hơn mốc đối soát lần trước (danh sách sắp xếp mới trước).
Chi tiết và code mẫu ở Đối soát giao dịch.
PHP: đọc hết các trang
Node
POST /api/v1/acb/virtual-account/transactions/{transaction_id}/retry
Gửi lại thông báo cho một giao dịch cụ thể (server bạn lúc đó bị lỗi, hoặc cấu hình webhook sai rồi sửa lại). Cần Bearer + X-Client-Secret. Gửi lại tự động theo lịch đang triển khai, hiện là thao tác chủ động này hoặc nút “Gửi lại” trong dashboard.
| Trường | Kiểu | Bắt buộc | Ghi chú |
|---|---|---|---|
target_type |
WEBHOOK / TELEGRAM |
có | Kênh cần gửi lại |
target_id |
uuid | không | ID cấu hình webhook hoặc Telegram cụ thể. Bỏ trống = gửi lại theo mọi cấu hình đang bật khớp giao dịch |
Payload gửi lại y hệt lần đầu, cùng transaction_code, nên server bạn phải chống trùng (xem Gửi lại và xử lý lỗi).
Lỗi thường gặp
| HTTP | Nguyên nhân | Cách xử lý |
|---|---|---|
| 400 | Số VA không tồn tại hoặc không thuộc tài khoản | Lấy đúng số VA từ GET /api/v1/acb/{bank_account_id}/virtual-account/retrieve |
| 401 | Token hết hạn | Login lại |
| 422 | limit > 100 hoặc thiếu virtual_account_number |
Sửa tham số |
| 404 (retry) | transaction_id không tồn tại |
Lấy id từ danh sách giao dịch |