Xác thực là bước đầu tiên khi triển khai API thanh toán ngân hàng Pay2S. Partner API không dùng cách đăng nhập Dashboard cho từng request; backend đối tác lấy Access Key và Secret Key trong khu vực Bankhub, sau đó đổi cặp khóa này lấy Bearer Token tạm thời. Token mới được dùng để gọi các API ngân hàng, webhook quản lý và Analytics.
Cách hiểu đúng luồng xác thực giúp tránh nhiều lỗi phổ biến: dùng nhầm token của API hóa đơn điện tử, thêm Bearer vào Basic Auth, mã hóa sai chuỗi Access Key và Secret Key, lưu Secret Key ở frontend hoặc tiếp tục dùng token đã hết hạn. Bài viết này trên hoadontudong.com.vn tập trung riêng vào mô hình bảo mật của Partner API để đội kỹ thuật có thể triển khai và kiểm thử có kiểm soát.
Access Key và Secret Key lấy ở đâu
Theo tài liệu Pay2S, đối tác đăng nhập merchant.pay2s.vn, mở Bankhub rồi vào phần thiết lập để lấy Access Key và Secret Key. Hai giá trị này thuộc bộ thông tin xác thực của ứng dụng hoặc tài khoản Partner, không phải mật khẩu đăng nhập người dùng cuối. Trước khi lấy khóa, cần xác định đúng môi trường và ứng dụng vì UAT và Production có thể dùng thông tin riêng.
Secret Key phải được xem là bí mật dài hạn. Chỉ server có nhiệm vụ gọi Pay2S mới được đọc khóa; frontend chỉ gọi backend của doanh nghiệp và không biết khóa. Không gửi khóa qua chat, email, ticket hoặc ảnh chụp. Khi nghi ngờ lộ khóa, quy trình nên có bước vô hiệu hóa hoặc cấp lại theo quyền quản trị, đồng thời rà soát log để biết khóa đã được sử dụng ở đâu.
Basic Authentication để lấy Bearer Token

Basic Authentication và Bearer TokenEndpoint cấp token là POST https://api-partner.pay2s.vn/v1/auth/authorize. Header Authorization có dạng Basic base64(access_key:secret_key), trong đó chuỗi trước khi mã hóa là Access Key, dấu hai chấm và Secret Key. Content-Type là application/json. Đây là Basic Auth dùng riêng ở bước đổi khóa lấy token; không dùng pay2s-token của API tra cứu mã số thuế và không dùng chữ ký HMAC của API hóa đơn.
Phản hồi thành công trả token_type Bearer, access_token và expires_in. Backend cần lưu token trong bộ nhớ an toàn hoặc cache có thời hạn ngắn hơn expires_in, chẳng hạn chủ động làm mới trước khi hết hạn. Không ghi token đầy đủ vào log request hoặc analytics. Nếu nhiều worker cùng gọi authorize, nên có cơ chế khóa ngắn để tránh tạo quá nhiều token đồng thời.
Gọi API BankHub bằng Bearer Token
Sau khi nhận token, các request bảo vệ gửi Authorization: Bearer
Một request có thể thành công ở tầng HTTP nhưng vẫn cần kiểm tra cấu trúc JSON và ý nghĩa nghiệp vụ. Ví dụ, việc gọi tạo liên kết trả về phản hồi hợp lệ không có nghĩa tài khoản đã hoàn tất xác minh; có thể còn OTP hoặc trạng thái đang xử lý. Vì vậy sau các thao tác quan trọng, hãy gọi danh sách hoặc endpoint trạng thái theo tài liệu. Bài quản lý tài khoản ngân hàng qua API Pay2S trình bày cụ thể các bước này.
Xử lý token hết hạn và lỗi 401
Khi Bearer Token hết hạn, API có thể trả 401 Unauthorized. Backend không nên retry vô hạn cùng token vì điều đó chỉ tạo log lỗi và làm chậm luồng thanh toán. Cách xử lý phù hợp là xác định 401 thuộc token hay dữ liệu quyền, lấy token mới một lần, lặp lại request có kiểm soát và nếu vẫn lỗi thì chuyển sang hàng chờ. Cần giữ request ID hoặc thời điểm để hỗ trợ điều tra.
Nếu authorize trả lỗi thông tin xác thực, kiểm tra Access Key, Secret Key, chuỗi trước Base64 và môi trường. Không lấy khóa của cửa hàng hoặc khóa của nhóm API khác để thử ngẫu nhiên. UAT và Production phải được cấu hình tách biệt. Khi thay khóa, cập nhật secret manager và worker cùng một quy trình để tránh một số máy dùng khóa cũ còn máy khác dùng khóa mới.
Bảo vệ khóa trong CI/CD và vận hành

Trong CI/CD, khóa nên nằm trong secret của môi trường triển khai, không nằm trong repository hoặc file log của pipeline. Mỗi môi trường có biến riêng và quyền đọc giới hạn. Khi chạy Postman ở máy cá nhân, dùng biến bí mật của Environment, không đặt Secret Key trong collection chia sẻ. Khi chạy local, có thể dùng file .env nhưng phải bảo đảm file không bị commit và không gửi cho người khác.
Nhật ký xác thực nên chỉ lưu endpoint, HTTP status, thời gian phản hồi và request ID; có thể che một phần client identity nhưng không lưu Authorization. Với webhook, token nhận từ Pay2S cũng cần bảo vệ tương tự. Khi kiểm tra lỗi, ưu tiên dùng mã lỗi và timestamp thay vì gửi toàn bộ header. Bài test API thanh toán ngân hàng Pay2S bằng Postman sẽ đưa các nguyên tắc này vào một quy trình kiểm thử thực tế.
Phân biệt Partner API với các cơ chế khác của Pay2S
Pay2S có nhiều nhóm tài liệu nên tên token dễ gây nhầm. Partner API dùng Access Key và Secret Key để lấy Bearer Token. Webhook giao dịch dùng webhook token riêng để Pay2S xác thực khi đẩy dữ liệu. Hosted Link dùng session và SDK để khách thực hiện liên kết trên form Pay2S. API hóa đơn điện tử dùng một bộ header khác và chuỗi ký HMAC. Mỗi token chỉ có ý nghĩa trong đúng luồng của nó.
Nếu một hệ thống vừa nhận tiền ngân hàng vừa xuất hóa đơn, có thể triển khai hai nhóm API cạnh nhau nhưng phải tách credential, bảng log và trạng thái. Không dùng thành công của bước authorize để kết luận API hóa đơn đã sẵn sàng, cũng không dùng trạng thái webhook ngân hàng thay cho trạng thái hóa đơn. Cách tách lớp này giúp dễ kiểm toán và tránh phát hành hoặc xác nhận sai khi một dịch vụ tạm thời gặp lỗi.
Góc nhìn triển khai thực tế
Trong backend, token manager nên là một thành phần dùng chung thay vì để từng service tự gọi authorize. Thành phần này giữ thời điểm hết hạn, làm mới sớm một khoảng an toàn, khóa các request làm mới đồng thời và trả token đã che khỏi log. Nếu nhiều worker cùng khởi động, một khóa phân tán hoặc cơ chế single-flight sẽ tránh việc tất cả cùng đổi Access Key và Secret Key trong một giây. Khi nhận 401, chỉ retry một lần sau khi xác thực lại; nếu vẫn lỗi, đưa request vào trạng thái cần kiểm tra thay vì retry vô hạn. Cách này bảo vệ hạn mức và làm cho nguyên nhân sự cố dễ quan sát hơn.
Cần phân biệt lỗi credential với lỗi nghiệp vụ. 401 thường hướng đội kỹ thuật kiểm tra Basic Auth, chuỗi base64, môi trường, token hết hạn hoặc header Bearer; còn 4xx khác có thể liên quan body, ID tài khoản, OTP hay quyền của endpoint. Dữ liệu lỗi nên được chuẩn hóa thành mã nội bộ, nhưng giữ lại status gốc và correlation ID. Không đưa Secret Key, Authorization, OTP hoặc toàn bộ request body vào hệ thống giám sát. Với tài liệu hướng dẫn trên hoadontudong.com.vn, ví dụ có thể dùng biến môi trường giả và che giá trị nhạy cảm để người đọc học được quy trình mà không sao chép nhầm khóa thật.
Trước khi bàn giao cơ chế xác thực, hãy lập bảng kiểm cho từng môi trường. Bảng cần ghi base URL, cách cấp khóa, thời hạn token, nơi lưu secret, người được quyền rotate và cách thu hồi khi nghi ngờ lộ khóa. Kiểm thử cả đồng hồ máy chủ lệch, response không có access_token, JSON sai schema và mất mạng giữa lúc lấy token. Nếu service restart, token trong bộ nhớ phải được tạo lại an toàn. Các quyết định này làm cho API thanh toán ngân hàng Pay2S trở thành một phần có thể vận hành và kiểm toán, thay vì một đoạn mã đặt trực tiếp trong controller.
Kiểm soát chất lượng và vận hành
Một token manager đáng tin cậy nên có trạng thái rõ ràng: chưa có token, đang làm mới, đang hoạt động, sắp hết hạn và bị thu hồi. Khi request đầu tiên đến lúc chưa có token, chỉ một luồng được gọi authorize; các luồng khác chờ kết quả trong thời gian ngắn. Nếu authorize thất bại, hàng đợi nhận cùng một lỗi có mã nội bộ và không tự gọi lại liên tục. Sau khi có token, thời điểm hết hạn nên được tính từ response thực tế, có khoảng đệm để tránh request rơi đúng ranh giới. Khi service chạy nhiều replica, bộ nhớ cục bộ chỉ phù hợp cho cache ngắn; khóa và secret vẫn phải nằm trong kho bí mật được phân quyền.
Bộ kiểm thử xác thực không nên dừng ở một request thành công. Hãy kiểm tra Access Key đúng và Secret Key sai, chuỗi Basic có ký tự đặc biệt, header Content-Type bị thiếu, body không đúng định dạng, token rỗng, token đã hết hạn và token của UAT được gửi nhầm vào Production. Mỗi case cần ghi status, mã lỗi, thời gian và hành động tiếp theo. Kiểm tra retry cũng quan trọng: lỗi 401 có thể yêu cầu làm mới một lần, nhưng lỗi cấu hình phải dừng sớm để không tạo vòng lặp. Những test này giúp nhóm triển khai API thanh toán ngân hàng Pay2S biết một lỗi thuộc credential hay thuộc request nghiệp vụ.
Khi rotate khóa, quy trình nên cho phép chuyển đổi có kiểm soát: tạo cặp khóa mới, cập nhật secret manager, triển khai theo từng worker, xác nhận authorize thành công, rồi thu hồi khóa cũ theo chính sách. Không gửi khóa qua chat, issue hoặc file collection. Nếu nghi ngờ lộ Secret Key, ưu tiên thu hồi và xem lại log truy cập thay vì chỉ thay giá trị trong file cấu hình. Tài liệu vận hành của hoadontudong.com.vn nên ghi ai được phép rotate, ai duyệt Production và cách kiểm tra sau thay đổi, nhưng không ghi giá trị bí mật.
Quy trình triển khai API thanh toán ngân hàng Pay2S
- Xác định đúng tài khoản, ứng dụng và môi trường
UAThoặcProduction. - Lấy
Access KeyvàSecret Keytừ Merchant Bankhub. - Mã hóa một lần chuỗi access_key:secret_key bằng Base64.
- Gọi
POST /v1/auth/authorizequa backend. - Lưu
Bearer Tokentheoexpires_invà không ghi token vào log. - Gọi API bằng
Authorization: Bearer, kiểm tra cả HTTP và JSON. - Làm mới token có khóa đồng thời khi nhận
401. - Rà soát quyền và luân chuyển khóa theo quy trình bảo mật.
Câu hỏi thường gặp
Partner API có dùng HMAC không?
Luồng lấy Bearer Token của Partner API dùng Basic Auth. HMAC là cơ chế khác, có thể xuất hiện ở webhook sự kiện hoặc API khác, không trộn vào bước authorize.
Bearer Token sống bao lâu?
Tài liệu minh họa expires_in là 3600 giây. Backend phải đọc giá trị trả về thay vì mã hóa cứng thời gian.
Có thể gọi authorize ở frontend không?
Không nên. Access Key và đặc biệt Secret Key phải nằm ở backend, frontend chỉ gọi API do hệ thống đối tác kiểm soát.
401 có phải luôn do sai khóa không?
Không luôn luôn. Có thể do token hết hạn, sai môi trường, quyền không đủ hoặc header bị tạo sai. Cần kiểm tra theo từng lớp.
Có dùng token API hóa đơn điện tử ở đây không?
Không. Partner API, webhook, Hosted Link và API hóa đơn điện tử có cơ chế credential khác nhau.