# API Token (/vi/developers/api-token)





API Token là thông tin xác thực để hệ thống của bạn gọi API PayFS. Mỗi token thuộc về
một User Account và được cấp quyền trên từng Workspace cụ thể.

<Callout type="warn">
  Đừng nhầm API Token với **Webhook API Key**. API Token dùng khi *bạn gọi PayFS*.
  Webhook API Key dùng khi *PayFS gọi bạn*, gửi qua header `X-Client-API-Key`.
  Hai khóa hoàn toàn độc lập.
</Callout>

## Tạo API Token [#tạo-api-token]

1. Đăng nhập Client Portal
2. Mở mục **API Token**
3. Chọn **Tạo API Token**
4. Đặt tên, chọn thời điểm hết hạn
5. Chọn những Workspace mà token được phép truy cập
6. Chọn quyền cho từng Workspace
7. Sao chép token và lưu vào nơi an toàn

## Phân quyền [#phân-quyền]

Quyền được cấp theo từng cặp tài nguyên và hành động, trên từng Workspace.

| Tài nguyên          | Quyền                                                        |
| ------------------- | ------------------------------------------------------------ |
| Workspace           | Xem, Thay đổi, Xóa, Quản lý thành viên                       |
| Tài khoản ngân hàng | Xem, Thay đổi, Xóa                                           |
| Webhook             | Xem, Thay đổi, Xóa                                           |
| Liên kết thanh toán | Xem (`payment_links:read`), Thay đổi (`payment_links:write`) |

<Callout type="info">
  Quyền thực tế của token không bao giờ vượt quá quyền hiện tại của User Account đã tạo
  token. Nếu quyền của User Account trên một Workspace bị thu hẹp, quyền của token cũng
  bị thu hẹp theo.
</Callout>

## Gọi API [#gọi-api]

Gửi token trong header `Authorization` theo lược đồ `Bearer`.

```bash
curl https://api.payfs.vn/v1.1/transactions \
  -H "Authorization: Bearer $PAYFS_API_TOKEN" \
  -H "Content-Type: application/json"
```

```javascript
const response = await fetch('https://api.payfs.vn/v1.1/transactions', {
  headers: {
    'Authorization': `Bearer ${process.env.PAYFS_API_TOKEN}`,
    'Content-Type': 'application/json'
  }
});
```

## Phiên bản API [#phiên-bản-api]

Dùng `/v1.1`. Mọi ví dụ trong tài liệu này đều theo phiên bản đó.

```
https://api.payfs.vn/v1.1/...
```

Luôn ghi rõ phiên bản trong đường dẫn. Đừng dựa vào một phiên bản mặc định.

## Xoay vòng và thu hồi [#xoay-vòng-và-thu-hồi]

* **Xoay vòng**: sinh giá trị mới cho token. Giá trị cũ ngừng hoạt động ngay lập tức.
* **Thu hồi**: vô hiệu hóa token. Mọi yêu cầu dùng token này sẽ bị từ chối ngay.

Nên xoay vòng định kỳ, và thu hồi ngay khi nghi ngờ token bị lộ.

## Nguyên tắc nên theo [#nguyên-tắc-nên-theo]

1. Mỗi hệ thống dùng một token riêng, để thu hồi được từng cái mà không ảnh hưởng cái khác
2. Chỉ cấp quyền tối thiểu mà hệ thống đó thực sự cần
3. Lưu token trong biến môi trường, không commit vào Git
4. Không ghi token vào log
5. Đặt thời điểm hết hạn ngay khi tạo

## Lỗi thường gặp [#lỗi-thường-gặp]

Mọi lỗi đều trả về cùng cấu trúc. `error.code` cho biết loại lỗi, `error.traceId` giúp
bộ phận hỗ trợ tra đúng request của bạn.

```json
{
  "success": false,
  "error": {
    "code": "AUTHENTICATION_ERROR",
    "errorCode": 20001,
    "message": "Authentication failed",
    "traceId": "trace_01HK...",
    "messageKey": "auth/authentication-error"
  },
  "meta": { "timestamp": "2026-08-23T02:02:55.371Z" }
}
```

| Mã  | `error.code`               | Cách xử lý                                                                                         |
| --- | -------------------------- | -------------------------------------------------------------------------------------------------- |
| 401 | `AUTHENTICATION_ERROR`     | Token sai, hết hạn, hoặc đã bị thu hồi. Kiểm tra header đúng dạng `Authorization: Bearer <token>`. |
| 403 | `INSUFFICIENT_PERMISSIONS` | Token không có quyền trên Workspace bạn đang gọi. Sửa phạm vi quyền trong Client Portal.           |
| 429 | `RATE_LIMIT_ERROR`         | Gọi quá nhiều. Thử lại với khoảng chờ tăng dần, hoặc nâng gói dịch vụ.                             |
