API MB Bank — Giải pháp MB Open API chính thức từ GPM Pay
GPM Pay kết nối trực tiếp MB Open API để đẩy biến động số dư MB Bank realtime về hệ thống của bạn qua webhook và REST API. Đăng ký bằng OTP trong 5 phút, không cần VA, hỗ trợ cả tài khoản cá nhân và doanh nghiệp. https://gpmpay.com/
Mỗi ngày bạn nhận hàng trăm lượt chuyển khoản. Mỗi lượt là một lần ai đó phải mở app ngân hàng, đọc nội dung chuyển khoản, dò lại mã đơn, rồi bấm xác nhận trên hệ thống bán hàng. Việc đó tốn người, chậm, và sai.
GPM Pay giải quyết đúng chỗ đau đó cho MB Bank — bằng MB Open API, kết nối đối tác chính thức với Ngân hàng TMCP Quân đội (MB). Khi có tiền vào tài khoản MB của bạn, MB đẩy thông báo biến động số dư (BĐSD) sang GPM Pay ngay lập tức; GPM Pay chuẩn hoá và bắn webhook về hệ thống của bạn trong vòng vài giây. Không cần người ngồi canh app.
Tóm tắt nhanh - Kênh dữ liệu chính thức của MB, không đọc SMS, không cào internet banking. - Đăng ký bằng OTP trong 5 phút, không cần viết code ở bước này. - Không cần tài khoản ảo (VA), không cần tiền tố trong nội dung chuyển khoản. - Tiền về thẳng tài khoản MB đứng tên bạn — GPM Pay không giữ tiền. - Có webhook, REST API, SDK Node.js, plugin WooCommerce và simulator để test.
Bài viết này mô tả đầy đủ giải pháp: cách kết nối hoạt động, quy trình đăng ký, cấu trúc dữ liệu webhook, REST API tra cứu giao dịch, và cách tự động đối soát đơn hàng.
MB Open API là gì và vì sao nó khác biệt
Trên thị trường Việt Nam hiện có ba cách để một hệ thống biết "tiền đã về tài khoản".
Cách làm · Nguyên lý · Điểm yếu
- Đọc SMS Banking — App Android đọc tin nhắn ngân hàng rồi forward — Phụ thuộc điện thoại phải luôn bật, SMS trễ hoặc mất, nội dung bị cắt
- Quét app / internet banking — Bot đăng nhập bằng tài khoản của bạn để cào giao dịch — Bạn phải giao mật khẩu ngân hàng cho bên thứ ba, dễ bị khoá phiên, vi phạm điều khoản
- Open API chính thức — Ngân hàng chủ động đẩy dữ liệu sang đối tác đã được cấp phép qua OAuth2 — Cần ký kết đối tác với ngân hàng — đây là phần GPM Pay đã làm xong
MB Open API là cách thứ ba. Bạn không đưa mật khẩu internet banking cho ai. Bạn không cần cắm một chiếc điện thoại Android chạy 24/7 trong góc phòng. Kênh dữ liệu là kênh chính thức của MB, đi thẳng từ hệ thống core của ngân hàng sang hạ tầng GPM Pay.
Kiến trúc kết nối

Hai chiều kết nối đều là kênh máy-với-máy có xác thực:
- GPM Pay → MB: xác thực OAuth2 client_credentials, dùng để đăng ký và huỷ đăng ký nhận BĐSD cho từng tài khoản.
- MB → GPM Pay: MB lấy Bearer JWT từ endpoint GPM Pay cấp riêng, rồi POST dữ liệu giao dịch sang. Token có TTL 3600 giây và được tự động làm mới.
Mỗi giao dịch MB gửi sang mang một transactionid duy nhất, được GPM Pay dùng làm khoá chống trùng lặp. Nếu đường truyền chập chờn và MB gửi lại cùng một giao dịch, hệ thống chỉ ghi nhận đúng một lần — bạn không bao giờ bị cộng tiền hai lần cho một đơn hàng.
Đăng ký nhận BĐSD MB Bank trong 5 phút
Toàn bộ quy trình nằm trong giao diện web của GPM Pay tại app.gpmpay.com — không cần lập trình gì ở bước này.

Bước 1 — Nhập thông tin tài khoản MB
Vào Tài khoản ngân hàng → Kết nối → MB Bank và điền:
- Số tài khoản MB — 6–20 chữ số
- Tên thụ hưởng — VIẾT HOA KHÔNG DẤU, đúng như trên sổ ngân hàng
- CCCD/Hộ chiếu hoặc MST — Cá nhân nhập CCCD, doanh nghiệp nhập Mã số thuế
- Số điện thoại — Đúng SĐT đã đăng ký tại MB để nhận OTP
MB đối chiếu tên tài khoản với dữ liệu core của họ, nên tên sai một ký tự sẽ bị từ chối ngay tại bước này với thông báo rõ ràng.
Bước 2 — Xác thực OTP
MB gửi mã OTP qua SMS tới số điện thoại bạn đã đăng ký với ngân hàng. Mã có hiệu lực 5 phút. Nhập mã, GPM Pay gọi tiếp subscribe/confirm sang MB để hoàn tất đăng ký.
Đây là điểm mấu chốt về mặt pháp lý và bảo mật: chính chủ tài khoản phải cầm điện thoại và nhập OTP. Không ai có thể gắn tài khoản MB của người khác vào hệ thống.
Bước 3 — Xong
Tài khoản chuyển sang trạng thái ACTIVE và bắt đầu nhận BĐSD. Một vài điểm đáng chú ý riêng của MB Bank:
- Không bắt buộc tài khoản ảo (VA). Khách chuyển thẳng vào số tài khoản MB thật của bạn. Khác với một số ngân hàng yêu cầu mọi giao dịch phải đi qua VA có tiền tố cố định.
- Không cần từ khoá đặc biệt trong nội dung chuyển khoản. Một số ngân hàng bắt nội dung phải bắt đầu bằng một tiền tố nhất định thì hệ thống mới nhận được thông báo; MB thì không.
- Hỗ trợ cả tài khoản cá nhân và tài khoản doanh nghiệp.
- Nhận cả tiền vào và tiền ra (transType: DC) — hữu ích khi bạn muốn dựng sổ quỹ đầy đủ chứ không chỉ theo dõi doanh thu.
Muốn ngắt kết nối? Bấm huỷ đăng ký, xác thực OTP thêm một lần nữa, MB ngừng đẩy dữ liệu. Bạn kiểm soát hoàn toàn.
Nhận giao dịch realtime bằng webhook
Đây là phần dành cho lập trình viên. Khi MB đẩy BĐSD sang, GPM Pay chuẩn hoá dữ liệu và POST về URL của bạn.
Cấu trúc payload
{
"id": "f68120ba-c60a-433a-a7af-3746a4eec807",
"gateway": "MB",
"transactionDate": "2026-08-12T03:35:50.306Z",
"accountNumber": "0123456789",
"subAccount": null,
"content": "DH1024 thanh toan don hang",
"description": "DH1024 thanh toan don hang",
"transferType": "in",
"transferAmount": 250000,
"accumulated": null,
"referenceCode": "FT26139000077",
"source": "REAL"
}
Trường · Kiểu · Mô tả
- id — UUID — ID giao dịch trong hệ thống GPM Pay
- gateway — string — Mã ngân hàng — MB
- transactionDate — ISO 8601 — Thời điểm giao dịch, chuẩn UTC
- accountNumber — string — Số tài khoản nhận tiền
- subAccount — string | null — Tài khoản ảo, null với MB
- content — string — Nội dung chuyển khoản — nơi bạn dò mã đơn
- transferType — "in" | "out" — Tiền vào hay tiền ra
- transferAmount — number — Số tiền (VND, số nguyên dương)
- accumulated — number | null — Số dư sau giao dịch, nếu ngân hàng cung cấp
- referenceCode — string — Mã tham chiếu (mã FT) do MB sinh
- source — "REAL" | "SIMULATED" — Giao dịch thật hay giao dịch mô phỏng để test
Xác thực chữ ký HMAC
Webhook là một endpoint công khai trên Internet — bất kỳ ai cũng có thể POST vào đó. Vì vậy GPM Pay ký mọi payload bằng HMAC-SHA256:
X-GPMPay-Signature: t=1786417750,v1=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
Cách kiểm tra ở phía bạn:
v1 = HMAC_SHA256(secret,{rawBody}) // hex
Trong đó rawBody là đúng chuỗi JSON thô nhận được, chưa qua parse lại. So sánh digest bằng hàm so sánh chống timing attack. GPM Pay từ chối request lệch quá 300 giây so với t, nên kể cả khi ai đó bắt được một payload hợp lệ thì cũng không replay lại được sau đó.
Ngoài HMAC, bạn có thể chọn xác thực bằng API Key trên một header tự đặt, hoặc không xác thực cho môi trường nội bộ.
Cơ chế thử lại
Server của bạn có lúc sập, deploy, hoặc timeout. GPM Pay không bỏ giao dịch — hệ thống thử lại theo lịch tăng dần.

Cơ chế thử lại webhook của GPM Pay: 6 lần trong hơn 7 giờ, sau 10 giây, 30 giây, 2 phút, 10 phút, 1 giờ và 6 giờ
- Lần 1 — sau 10 giây
- Lần 2 — sau 30 giây
- Lần 3 — sau 2 phút
- Lần 4 — sau 10 phút
- Lần 5 — sau 1 giờ
- Lần 6 — sau 6 giờ
Tổng cộng 6 lần trong hơn 7 giờ. Mọi lần gửi đều được ghi lại kèm mã HTTP và nội dung phản hồi, tra cứu được trong mục Lịch sử webhook — khi có tranh chấp "hệ thống không nhận được đơn", bạn có bằng chứng chính xác.
Không chỉ có HTTP
Một điểm khác biệt của GPM Pay: webhook không nhất thiết phải trỏ về server của bạn. Hệ thống hỗ trợ bốn kiểu đích đến.

Bốn kiểu đích đến của webhook GPM Pay: HTTP endpoint, Telegram, WordPress WooCommerce và Google Sheets
- HTTP — POST JSON về endpoint của bạn.
- Telegram — bắn thông báo giao dịch vào nhóm chat. Chủ shop không cần lập trình vẫn theo dõi được tiền về theo thời gian thực.
- WordPress / WooCommerce — dùng cùng plugin chính thức của GPM Pay để tự động cập nhật trạng thái đơn hàng.
- Google Sheets — mỗi giao dịch là một dòng trong bảng tính, phục vụ kế toán đối soát.
Bạn cũng chọn được phạm vi: webhook nhận tất cả tài khoản ngân hàng, hoặc chỉ một số tài khoản cụ thể.
REST API tra cứu giao dịch
Webhook lo phần realtime. REST API lo phần đối chiếu lịch sử, dựng báo cáo, và chạy job đối soát cuối ngày.
Xác thực Tạo API token tại app.gpmpay.com/api-tokens, rồi gắn vào header:
curl -H "Authorization: Bearer gpm_abcd1234_xyz..." \
https://api.gpmpay.com/api/v1/transactions
Token hoạt động theo scope — cấp đúng quyền tối thiểu cho từng ứng dụng:
- transactions:read — Đọc danh sách và chi tiết giao dịch, dùng simulator
- bank-accounts:read — Đọc danh sách tài khoản ngân hàng đã kết nối
- webhooks:manage — Tạo, sửa, xoá webhook và tra cứu lịch sử gửi
Lấy danh sách giao dịch
GET /api/v1/transactions
Tham số · Kiểu · Mô tả
- page — number — Trang, mặc định 1
- limit — number — Số bản ghi mỗi trang, mặc định 10
- sortBy — string — Trường sắp xếp, mặc định createdAt
- sortOrder — asc | desc — Thứ tự, mặc định desc
- search — string — Tìm theo nội dung chuyển khoản
- startDate / endDate — string — Khoảng thời gian
- bankAccountId — UUID — Lọc theo một tài khoản ngân hàng
- type — IN | OUT — Tiền vào / tiền ra
- source — REAL | SIMULATED — Loại trừ giao dịch test khỏi báo cáo
- filters — JSON — Bộ lọc nâng cao: equals, in, gte, lte, contains…
Ví dụ — lấy toàn bộ tiền vào tài khoản MB trong tháng 8:
curl -G https://api.gpmpay.com/api/v1/transactions \
-H "Authorization: Bearer $GPMPAY_API_TOKEN" \
--data-urlencode "type=IN" \
--data-urlencode "source=REAL" \
--data-urlencode "startDate=2026-08-01" \
--data-urlencode "endDate=2026-08-31" \
--data-urlencode "limit=100"
Lọc nâng cao theo số tiền:
--data-urlencode 'filters={"amount":{"gte":100000,"lte":5000000}}'
Lấy chi tiết một giao dịch
GET /api/v1/transactions/{id}
Tự động đối soát đơn hàng
Cần nói thẳng một điều: GPM Pay không giữ tiền của bạn. Khách chuyển khoản trực tiếp vào tài khoản MB đứng tên bạn, tiền về thẳng ngân hàng, không qua ví trung gian, không có chu kỳ giải ngân T+1 hay T+3. GPM Pay là đường ống dữ liệu, không phải nơi giữ tiền.
Đổi lại, việc khớp đơn là của hệ thống bạn — và đó cũng là điều làm nó linh hoạt.

Luồng đối soát đơn hàng tự động: dựng VietQR có sẵn mã đơn và số tiền, dò mã khi webhook về, so khớp số tiền tuyệt đối trước khi giao hàng
Mô hình chuẩn gồm ba bước:
1. Sinh mã đơn và dựng VietQR. SDK Node.js chính thức dựng sẵn mã QR đúng chuẩn VietQR, có số tiền và nội dung điền sẵn:
import { GpmPay } from "@gpmpay/sdk";
import { buildPaymentInstructions } from "@gpmpay/sdk/vietqr";
const client = GpmPay.fromEnv();
const account = (await client.bankAccounts.list({ status: "ACTIVE" })).data[0]!;
const code = `DH${order.id}`; // mã đơn của bạn
const { qrImageUrl, transferContent } = buildPaymentInstructions({
bankAccount: account,
amount: Math.round(order.total), // VND, số nguyên
transferContent: code,
});
Khách quét QR bằng bất kỳ app ngân hàng nào, số tiền và nội dung đã điền sẵn — không gõ tay, không sai chính tả, tỷ lệ đối soát tự động gần như tuyệt đối.
2. Dò mã khi webhook về.
onEvent: async (event) => {
const code = /DH(\d+)/.exec(event.payload.content)?.[0];
const order = code && (await db.orders.findByCode(code));
if (order && order.total === event.payload.transferAmount) {
await giaoHang(order);
}
};
3. So khớp số tiền tuyệt đối trước khi giao hàng. Đây là lớp phòng vệ cuối: đúng mã nhưng sai số tiền thì không được tính là đã thanh toán.
Công cụ có sẵn
- SDK Node.js @gpmpay/sdk — zero dependency, có sẵn TypeScript types, hỗ trợ cả ESM lẫn CommonJS, kèm CLI để kiểm tra kết nối: npx gpmpay ping.
- Plugin WordPress / WooCommerce — cài đặt là chạy, không cần viết dòng code nào.
- Simulator — bắn giao dịch giả (source: "SIMULATED") để test toàn bộ luồng webhook trước khi lên production, không cần chuyển tiền thật. Lọc source=REAL khi làm báo cáo là dữ liệu test không lẫn vào sổ sách.
Bảo mật
- Quyền truy cập tài khoản — Đăng ký BĐSD bắt buộc OTP gửi tới SĐT chính chủ tại MB — không ai gắn được tài khoản của người khác
- Mật khẩu ngân hàng — Không bao giờ được yêu cầu. GPM Pay không có, không lưu, không cần
- Token nội bộ — Token đối tác với MB được mã hoá AES-GCM trước khi lưu
- Dữ liệu định danh — CCCD/MST và số điện thoại được mã hoá trong cơ sở dữ liệu
- Webhook — Ký HMAC-SHA256 kèm timestamp, cửa sổ hợp lệ 300 giây
- API token — Phân quyền theo scope; SDK không bao giờ in token ra log
- Dòng tiền — Tiền đi thẳng vào tài khoản MB của bạn — GPM Pay không đụng tới
All Rights Reserved