# Liên kết tài khoản ngân hàng qua API Pay2S: OpenAPI, RPA và OTP

- Link: https://mail.hoadontudong.com.vn/lien-ket-tai-khoan-ngan-hang-pay2s-api/
- Published: 2026-10-15T23:50:05+07:00
- Author: Hóa Đơn Tự Động

Liên kết tài khoản ngân hàng là nghiệp vụ trung tâm của BankHub. API thanh toán 
ngân hàng Pay2S cho phép backend đối tác thêm tài khoản, xử lý OTP khi cần, xem 
danh sách, bật tắt trạng thái và xóa liên kết. Sau khi tài khoản hoạt động, ID bản
ghi có thể được gắn với webhook để nhận giao dịch tiền vào hoặc tiền ra.

Tài liệu Pay2S phân biệt nhiều kiểu kết nối như `OpenAPI` và Internet Banking qua`
RPA`, đồng thời có mẫu khác nhau cho cá nhân, doanh nghiệp hoặc hộ kinh doanh. Vì
schema và bước OTP phụ thuộc ngân hàng, bài viết trên hoadontudong.com.vn tập trung
vào quy trình kiểm tra an toàn thay vì coi một request mẫu là cam kết cho mọi ngân
hàng.

## Chuẩn bị token và dữ liệu đầu vào

Trước khi gọi /v1/banks, backend phải lấy `Bearer Token` theo luồng xác thực Partner
API. Header chung gồm `Authorization: Bearer`  và `Content-Type` `application/json`
cho request có body. Số tài khoản, số điện thoại, CCCD, mã số thuế và OTP phải được
giữ dạng chuỗi để bảo toàn số 0 ở đầu. Không đưa mật khẩu Internet Banking hoặc 
OTP qua frontend của đối tác nếu có thể dùng Hosted Link.

Dữ liệu thêm tài khoản thường có type, `bankShortName`, `accountNumber` và các trường
bổ sung theo ngân hàng. `OpenAPI` có thể cần accName, accMobile, accEmail, cccd 
hoặc merchantId. `RPA` cá nhân và doanh nghiệp có username, password, còn ACB doanh
nghiệp có thể dùng username ACB OneBiz. Đây là các mẫu tài liệu; validation thật
cần đối chiếu với backend và đúng loại tài khoản.

## `OpenAPI` và `RPA` khác nhau thế nào

![Minh họa so sánh OpenAPI và RPA khi liên kết tài khoản ngân hàng](https://hoadontudong.
com.vn/wp-content/uploads/2026/10/bankhub-bank-inline-openapi-rpa-imagegen.png)

`OpenAPI` và `RPA` trong liên kết ngân hàng

`OpenAPI` là hướng kết nối mà Pay2S trao đổi với dịch vụ ngân hàng theo hồ sơ tích
hợp. Tài liệu minh họa ACB, MBBank và BIDV với các trường nhận diện chủ tài khoản,
số điện thoại, CCCD, mã số thuế hoặc merchantId. BIDV có mô tả tài khoản ảo và yêu
cầu giữ merchantId khi xác nhận. Khi dùng tài khoản ảo, hệ thống phải lấy giá trị
Pay2S hoặc ngân hàng trả về, không tự suy diễn.

`RPA` dùng thông tin đăng nhập Internet Banking cho một số ngân hàng và có thể có
OTP. Mật khẩu phải được xử lý trong vùng bảo mật, hạn chế lưu và không ghi vào log.
Không giả định mọi `RPA` đều có cùng màn hình, thời gian chờ hoặc bước OTP. Nếu 
doanh nghiệp không muốn thu thập credential ngân hàng, Hosted Link là hướng thay
thế phù hợp hơn vì khách nhập thông tin trên form do Pay2S cung cấp.

## Xử lý OTP và xác nhận tài khoản

![Minh họa OTP và xác nhận tài khoản ngân hàng an toàn](https://hoadontudong.com.
vn/wp-content/uploads/2026/10/bankhub-bank-inline-otp-imagegen.png)

OTP và xác nhận tài khoản

Sau request thêm tài khoản, nếu phản hồi báo OTP bằng giá trị OTP = 1, backend tiếp
tục gọi /v1/banks/confirm-otp với cùng type, `bankShortName` và `accountNumber`.
Với BIDV cần giữ merchantId; với `RPA` cá nhân có thể phải giữ username và password
theo mẫu. OTP phải là chuỗi và không được dùng lại cho một yêu cầu khác. Thời hạn
OTP, số lần thử và cách gửi lại cần xác nhận theo từng ngân hàng.

Không dùng riêng việc request trả status true hoặc thiếu trường OTP để kết luận 
tài khoản đã hoạt động. Sau xác nhận, gọi `GET /v1/banks` và đọc trạng thái bản 
ghi. Nếu vẫn có lỗi hoặc yêu cầu OTP tiếp tục xuất hiện, giữ trạng thái chờ xử lý.
Việc đánh dấu tài khoản hoạt động quá sớm có thể khiến webhook được tạo cho một 
liên kết chưa sẵn sàng và làm sai quy trình thanh toán.

## Đọc danh sách và phân biệt ID

`GET /v1/banks` trả danh sách tài khoản đã liên kết. Trường id là ID bản ghi trên
Pay2S, dùng cho bật tắt, xóa và gắn webhook. `accountNumber` là số tài khoản hoặc
giá trị do môi trường trả về; không dùng `accountNumber` thay cho id. Các trường
như bankName, shortBankName, status, statusText, vaNumber hoặc `customer_reference`
có thể hỗ trợ hiển thị và định tuyến nhưng cần xử lý theo schema thực tế.

Sau khi có id, backend có thể gọi `PATCH /v1/banks/{id}/status` để bật hoặc tắt.
Phản hồi có newStatus là trạng thái sau cập nhật; nên đọc lại danh sách để xác nhận.
Khi xóa, DELETE có thể yêu cầu OTP qua phản hồi OTP = 1; lúc đó gọi endpoint delete-
confirm với cùng id. Không coi response đầu tiên là xóa hoàn tất nếu còn bước xác
nhận.

## Gắn tài khoản vào webhook giao dịch

Khi tài khoản đã hoạt động, `POST /v1/webhooks` dùng `user_bank_id` để gắn URL nhận
giao dịch. Tên trường này nhắc lại rằng phải truyền ID bản ghi từ danh sách ngân
hàng, không truyền số tài khoản. type có thể là `IN`, `OUT` hoặc `ALL`. Nếu chỉ 
xử lý tiền vào, chọn `IN` để giảm dữ liệu không cần thiết; nếu hệ thống cần theo
dõi chi trả, chọn `OUT` hoặc `ALL` theo nghiệp vụ.

Mỗi webhook có token riêng. Receiver cần xác thực Authorization `Bearer` với token
của webhook, lưu payload, chống trùng theo id hoặc checksum và trả response đúng
quy ước. Nếu URL lỗi, lịch sử webhook cho phép kiểm tra `status_code` và gửi lại.
Chi tiết transaction payload, `paymentCode` và `extraData` nằm trong [bài webhook giao dịch ngân hàng Pay2S](https://hoadontudong.com.vn/webhook-giao-dich-ngan-hang-pay2s/).

## Kiểm thử và các điểm chưa nên tự suy luận

Một bộ test tối thiểu nên gồm thêm tài khoản hợp lệ, tài khoản cần OTP, OTP sai,
danh sách sau xác nhận, bật tắt, xóa cần OTP và request lặp khi chưa biết kết quả.
Mỗi test lưu request ID, thời điểm, ngân hàng, loại tài khoản, HTTP status và thông
báo đã che dữ liệu nhạy cảm. Kiểm thử `UAT` không thể thay cho `Production` vì URL,
dữ liệu mô phỏng và quyền có thể khác.

Trước khi triển khai từng ngân hàng, cần chốt schema response, thời hạn OTP, số 
lần thử, mặc định bank_type và cách xử lý request lặp với bên cung cấp API. Adapter
theo `bankShortName` nên chỉ nhận các trường đã xác nhận cho loại tài khoản đó; 
một mẫu request chưa đủ để suy ra toàn bộ validation. Phần [xác thực và quản lý token](https://hoadontudong.com.vn/xac-thuc-api-thanh-toan-ngan-hang-pay2s/)
giúp kiểm tra lỗi quyền trước khi tìm lỗi ở dữ liệu ngân hàng.

## Góc nhìn triển khai thực tế

Mô hình dữ liệu cho liên kết ngân hàng nên lưu tách thông tin hiển thị và định danh
kỹ thuật. Tên ngân hàng, tên chủ tài khoản và số tài khoản đã che có thể phục vụ
giao diện; còn bank record ID, `bankShortName`, `user_bank_id`, trạng thái và thời
điểm đồng bộ phục vụ API. Không dùng số tài khoản làm khóa duy nhất nếu tài khoản
có thể được liên kết lại hoặc có nhiều mapping. Khi người dùng thêm tài khoản lần
thứ hai, hệ thống cần phát hiện bản ghi đang chờ, đã hoạt động, bị vô hiệu hóa hay
đã xóa để tránh tạo các liên kết khó đối soát.

OTP làm cho luồng liên kết có trạng thái trung gian và thời hạn, vì vậy giao diện
phải nói rõ người dùng đang chờ xác nhận chứ chưa hoàn tất. Backend không nên lưu
OTP lâu hơn cần thiết, không log mã OTP và không cho một nút bấm gửi lại tạo nhiều
phiên song song. Nếu người dùng thoát giữa chừng, hãy cho phép tiếp tục hoặc hủy
theo trạng thái thực tế thay vì tự đoán đã thành công. Sau khi xác nhận, gọi lại
danh sách hoặc endpoint trạng thái để đồng bộ; đừng chỉ dựa vào thông báo từ trình
duyệt.

Adapter giúp cô lập khác biệt giữa `OpenAPI` và `RPA`. Sau khi xác định `bankShortName`,
backend chọn bộ validation và payload tương ứng rồi chuyển kết quả về trạng thái
nội bộ như pending, active, failed hoặc needs_action. Các tên trạng thái này là 
gợi ý thiết kế của ứng dụng, không phải enum bắt buộc của Pay2S. Khi schema thay
đổi, hãy cập nhật adapter cùng bộ test của ngân hàng liên quan trước khi mở lại 
tính năng.

## Kiểm soát chất lượng và vận hành

Khi một phiên liên kết bị bỏ dở, màn hình hỗ trợ cần trả lời được nó đang chờ ai
và chờ bước nào. Lưu dấu mốc bắt đầu, lần xác nhận gần nhất, trạng thái đọc lại 
từ Pay2S và lỗi đã che dữ liệu. Một lượt bấm xác nhận bị gửi hai lần không được 
sinh hai mapping nội bộ. Nếu ứng dụng không biết request trước đã hoàn tất hay chưa,
đọc trạng thái trước khi cho phép khởi tạo lại; lịch sử giao dịch vẫn cần giữ khi
liên kết bị tắt hoặc xóa.

Màn hình hỗ trợ có thể hiển thị ngân hàng, tên gợi nhớ, vài chữ số cuối và trạng
thái đồng bộ. Nhân viên không cần nhìn `Secret Key` hay OTP để tìm một phiên bị 
kẹt. Nhãn của `user_bank_id` và account.id cần tách khỏi nhãn số tài khoản để tránh
copy nhầm. Với khách có nhiều tài khoản cùng ngân hàng, thao tác bật tắt phải yêu
cầu chọn đúng bản ghi; sau đó hiển thị trạng thái đã đọc lại, thay vì chỉ hiện thông
báo request được gửi.

Lập ma trận kiểm thử theo `bankShortName` và phương thức thực sự được cấp quyền.
Với `RPA`, kiểm tra phiên đăng nhập hết hạn, timeout và lỗi bước xác minh; với `
OpenAPI`, kiểm tra lỗi mạng và response thiếu trường. Dùng dữ liệu được phép thử,
không lấy tài khoản của khách chạy tự động. Ghi rõ khi nào phải khóa nút tiếp tục,
khi nào cho nhập lại OTP và khi nào chuyển hỗ trợ. Nhờ vậy người vận hành có hành
động cụ thể khi kết nối chưa sẵn sàng.

## Quy trình triển khai API thanh toán ngân hàng Pay2S

 1. Lấy `Bearer Token` đúng môi trường.
 2. Xác định `bankShortName`, loại tài khoản và kiểu kết nối.
 3. Gửi request thêm tài khoản với trường dữ liệu phù hợp.
 4. Nếu có OTP, xác nhận bằng đúng bộ thông tin của request.
 5. Gọi `GET /v1/banks` để đọc id và trạng thái thực tế.
 6. Dùng id làm `user_bank_id` khi tạo webhook giao dịch.
 7. Đọc lại trạng thái sau bật tắt hoặc xóa.
 8. Lưu log an toàn và xử lý các response chưa rõ bằng hàng chờ.

## Câu hỏi thường gặp

### `user_bank_id` là gì?

Đó là ID bản ghi tài khoản ngân hàng trên Pay2S, lấy từ trường id trong danh sách/
v1/banks. Không thay bằng số tài khoản.

### Có phải ngân hàng nào cũng cần OTP không?

Không chắc. Bước xác minh phụ thuộc loại ngân hàng và phương thức kết nối; không
nên giả định cùng một luồng cho mọi ngân hàng.

### Có thể xóa ngay khi DELETE trả status true không?

Nếu phản hồi còn OTP = 1 thì chưa xóa hoàn tất. Phải gọi endpoint xác nhận xóa với
đúng ID.

### `RPA` có nên lưu mật khẩu ngân hàng không?

Nếu dùng `RPA`, credential phải được bảo vệ ở backend và không ghi log. Có thể cân
nhắc Hosted Link để khách nhập trên form Pay2S.

### Có thể tự ghép số tài khoản ảo không?

Không. Khi có vaNumber, dùng giá trị API trả về và giữ nguyên kiểu chuỗi.

## Đọc tiếp trong cụm BankHub Pay2S

 * [tổng quan API thanh toán ngân hàng Pay2S](https://hoadontudong.com.vn/api-thanh-toan-ngan-hang-pay2s/)
 * [xác thực và lấy Bearer Token](https://hoadontudong.com.vn/xac-thuc-api-thanh-toan-ngan-hang-pay2s/)
 * [Hosted Link giảm xử lý credential](https://hoadontudong.com.vn/pay2s-bankhub-hosted-link-sdk/)
 * [webhook giao dịch và chống trùng](https://hoadontudong.com.vn/webhook-giao-dich-ngan-hang-pay2s/)
 * [theo dõi lỗi và thời gian phản hồi](https://hoadontudong.com.vn/analytics-api-thanh-toan-ngan-hang-pay2s/)
