# Luồng xác thực

Pay2S dùng Authorization Code với **PKCE S256 bắt buộc**. Khách đăng nhập và đồng ý quyền trên trang Pay2S; phần mềm đổi mã lấy token tại backend.

## Trước khi bắt đầu

[Tạo ứng dụng](/docs/oauth/register/) để nhận Client ID và Client Secret. Mỗi ứng dụng đăng ký một callback HTTPS chính xác; website khác tạo ứng dụng riêng. Giữ Secret tại máy chủ.

## 1. Tạo yêu cầu kết nối

Backend tạo `state` ngẫu nhiên (16–512 ký tự) và `code_verifier` (43–128 ký tự). Tính `code_challenge = BASE64URL(SHA256(code_verifier))`, bỏ dấu `=`. Lưu state và verifier gắn với phiên đăng nhập và lần kết nối; không tái sử dụng giữa các phiên.

Đưa người dùng đến [API yêu cầu cấp quyền](/docs/oauth/authorize/) với Client ID, callback, các scopes cần dùng, state và challenge. Đây là điều hướng trình duyệt, không phải gọi AJAX để cấp quyền.

## 2. Khách xác nhận trên Pay2S

Khách đăng nhập, đọc tên ứng dụng, quyền yêu cầu và chọn ngân hàng. App cá nhân chỉ dành cho chủ app. App đối tác chưa duyệt chỉ cho chủ app và tài khoản demo thử; khách thật khác cần app được duyệt.

Khách có thể từ chối. Không tự cấp quyền hoặc tự chọn ngân hàng thay khách.

## 3. Kiểm tra callback

Pay2S trả `code`, `state` và `iss` về callback; nếu từ chối sẽ có `error=access_denied`. Trước khi đổi token, backend phải kiểm tra state trùng phiên đã khởi tạo và `iss` bằng `https://api.pay2s.vn`. Không xử lý callback không hợp lệ. Không ghi code vào log; tiêu thụ state sau khi xử lý để tránh dùng lại.

## 4. Đổi code lấy token

Gọi [Đổi mã lấy token](/docs/oauth/token/) từ backend, dùng Client ID, Secret, callback, code và verifier tương ứng. Gửi **application/x-www-form-urlencoded**. Code chỉ dùng một lần và hết hạn sau **120 giây**.

Lưu an toàn cả access token và refresh token theo người dùng/kết nối. Không đưa Secret hoặc refresh token vào mã frontend.

## 5. Gọi API theo quyền

Gửi `Authorization: Bearer ACCESS_TOKEN`. Bắt đầu với [tài khoản ngân hàng](/docs/oauth/bank-accounts/), lấy `bank_id` để [đọc giao dịch](/docs/oauth/transactions/) hoặc [tạo webhook](/docs/oauth/webhooks/).

## 6. Gia hạn hoặc thu hồi

Đọc [Access Token](/docs/oauth/access-token/) để quản lý thời hạn và refresh. Khách có thể ngắt kết nối trong Pay2S; chủ app có thể khóa ứng dụng. Cả hai đều dừng quyền truy cập tương ứng.

[Thử từng bước trong Playground →](/docs/oauth/quickstart/)
