# Kết nối ACB (/vi/bank-accounts/acb) Kết nối tài khoản ACB (mã `ACB`) với Workspace của bạn qua Open Banking. ## Trước khi bắt đầu [#trước-khi-bắt-đầu] * Có một Workspace dùng Banking Mode Open Banking. Xem [Tạo Workspace](/vi/workspace/create). * Tài khoản ACB đang hoạt động và đã đăng ký dịch vụ ngân hàng điện tử. * Có thể nhận mã OTP trên số điện thoại đã đăng ký với ngân hàng. * Bạn có vai trò Owner hoặc Admin trong Workspace. ## Các bước kết nối [#các-bước-kết-nối] 1. Mở Workspace rồi vào mục **Tài khoản ngân hàng** 2. Chọn **Thêm tài khoản ngân hàng** 3. Chọn ACB trong danh sách 4. Chọn loại tài khoản cần kết nối: Main Bank Account hoặc Main Bank Account kèm Virtual Account 5. Nhập số tài khoản, tên chủ tài khoản và số điện thoại đăng ký với ngân hàng. Nhập CCCD hoặc mã số thuế nếu form yêu cầu. Shop and Bank Setup không yêu cầu trường này. 6. Nhập mã OTP mà ngân hàng gửi tới Với ACB, mã OTP có thể là mã SafeKey sinh trên ứng dụng ACB ONE, hoặc mã gửi qua tin nhắn. 7. Chờ trạng thái chuyển sang **Đã kết nối** ## Trạng thái kết nối [#trạng-thái-kết-nối] | Trạng thái | Ý nghĩa | | ---------------- | ------------------------------------------------------------- | | Đang chờ kết nối | Ngân hàng chưa xác nhận xong, có thể cần thêm thao tác từ bạn | | Đã kết nối | Kết nối hoạt động, giao dịch sẽ được ghi nhận | | Đã ngắt kết nối | Kết nối không còn hiệu lực | ## Sau khi kết nối [#sau-khi-kết-nối] [Thiết lập webhook](/vi/developers/webhooks) để nhận thông báo mỗi khi có giao dịch trên tài khoản này. ## Sự cố thường gặp [#sự-cố-thường-gặp] **Thông tin không chính xác hoặc tài khoản đã tồn tại** Kiểm tra lại số tài khoản và giấy tờ. Nếu tài khoản đã được kết nối ở nơi khác, hãy ngắt kết nối cũ trước. **Không nhận được OTP** Kiểm tra sóng điện thoại và số điện thoại đã đăng ký với ngân hàng. Yêu cầu gửi lại mã. **ACB đang bảo trì** Khi ngân hàng ở trạng thái bảo trì, bạn chưa tạo kết nối mới được. Các kết nối đang có vẫn tiếp tục nhận giao dịch. # Kết nối KienLong Bank (/vi/bank-accounts/kienlong) Trang này **tạm ẩn**. KienLong Bank chưa được công bố trong tài liệu. Liên hệ [support@payfs.vn](mailto:support@payfs.vn) nếu bạn cần dùng. Nội dung sẽ được công bố khi ngân hàng này sẵn sàng. # Kết nối MBBank (/vi/bank-accounts/mbbank) Kết nối tài khoản MBBank (mã `MB`) với Workspace của bạn qua Open Banking. ## Trước khi bắt đầu [#trước-khi-bắt-đầu] * Có một Workspace dùng Banking Mode Open Banking. Xem [Tạo Workspace](/vi/workspace/create). * Tài khoản MBBank đang hoạt động và đã đăng ký dịch vụ ngân hàng điện tử. * Có thể nhận mã OTP trên số điện thoại đã đăng ký với ngân hàng. * Bạn có vai trò Owner hoặc Admin trong Workspace. ## Các bước kết nối [#các-bước-kết-nối] 1. Mở Workspace rồi vào mục **Tài khoản ngân hàng** 2. Chọn **Thêm tài khoản ngân hàng** 3. Chọn MBBank trong danh sách 4. Chọn loại tài khoản cần kết nối: Main Bank Account hoặc Main Bank Account kèm Virtual Account 5. Nhập số tài khoản, tên chủ tài khoản và số điện thoại đăng ký với ngân hàng. Nhập CCCD hoặc mã số thuế nếu form yêu cầu. Shop and Bank Setup không yêu cầu trường này. 6. Nhập mã OTP mà ngân hàng gửi tới 7. Chờ trạng thái chuyển sang **Đã kết nối** ## Trạng thái kết nối [#trạng-thái-kết-nối] | Trạng thái | Ý nghĩa | | ---------------- | ------------------------------------------------------------- | | Đang chờ kết nối | Ngân hàng chưa xác nhận xong, có thể cần thêm thao tác từ bạn | | Đã kết nối | Kết nối hoạt động, giao dịch sẽ được ghi nhận | | Đã ngắt kết nối | Kết nối không còn hiệu lực | ## Sau khi kết nối [#sau-khi-kết-nối] [Thiết lập webhook](/vi/developers/webhooks) để nhận thông báo mỗi khi có giao dịch trên tài khoản này. ## Sự cố thường gặp [#sự-cố-thường-gặp] **Thông tin không chính xác hoặc tài khoản đã tồn tại** Kiểm tra lại số tài khoản và giấy tờ. Nếu tài khoản đã được kết nối ở nơi khác, hãy ngắt kết nối cũ trước. **Không nhận được OTP** Kiểm tra sóng điện thoại và số điện thoại đã đăng ký với ngân hàng. Yêu cầu gửi lại mã. **MBBank đang bảo trì** Khi ngân hàng ở trạng thái bảo trì, bạn chưa tạo kết nối mới được. Các kết nối đang có vẫn tiếp tục nhận giao dịch. # Kết nối OCB (/vi/bank-accounts/ocb) Kết nối tài khoản OCB (mã `OCB`) với Workspace của bạn qua Open Banking. ## Trước khi bắt đầu [#trước-khi-bắt-đầu] * Có một Workspace dùng Banking Mode Open Banking. Xem [Tạo Workspace](/vi/workspace/create). * Tài khoản OCB đang hoạt động và đã đăng ký dịch vụ ngân hàng điện tử. * Có thể nhận mã OTP trên số điện thoại đã đăng ký với ngân hàng. * Bạn có vai trò Owner hoặc Admin trong Workspace. ## Các bước kết nối [#các-bước-kết-nối] 1. Mở Workspace rồi vào mục **Tài khoản ngân hàng** 2. Chọn **Thêm tài khoản ngân hàng** 3. Chọn OCB trong danh sách 4. Chọn loại tài khoản cần kết nối: Main Bank Account hoặc Main Bank Account kèm Virtual Account 5. Nhập số tài khoản, tên chủ tài khoản và số điện thoại đăng ký với ngân hàng. Nhập CCCD hoặc mã số thuế nếu form yêu cầu. Shop and Bank Setup không yêu cầu trường này. 6. Nhập mã OTP mà ngân hàng gửi tới Với OCB, mã OTP có thể được tạo trên ứng dụng OCB OMNI. Ở màn hình chính chọn **Xem tất cả**, rồi tìm mục **Lấy OTP**. Hoặc dùng mã gửi qua tin nhắn. 7. Chờ trạng thái chuyển sang **Đã kết nối** ## Trạng thái kết nối [#trạng-thái-kết-nối] | Trạng thái | Ý nghĩa | | ---------------- | ------------------------------------------------------------- | | Đang chờ kết nối | Ngân hàng chưa xác nhận xong, có thể cần thêm thao tác từ bạn | | Đã kết nối | Kết nối hoạt động, giao dịch sẽ được ghi nhận | | Đã ngắt kết nối | Kết nối không còn hiệu lực | ## Sau khi kết nối [#sau-khi-kết-nối] [Thiết lập webhook](/vi/developers/webhooks) để nhận thông báo mỗi khi có giao dịch trên tài khoản này. ## Sự cố thường gặp [#sự-cố-thường-gặp] **Thông tin không chính xác hoặc tài khoản đã tồn tại** Kiểm tra lại số tài khoản và giấy tờ. Nếu tài khoản đã được kết nối ở nơi khác, hãy ngắt kết nối cũ trước. **Không nhận được OTP** Kiểm tra sóng điện thoại và số điện thoại đã đăng ký với ngân hàng. Yêu cầu gửi lại mã. **OCB đang bảo trì** Khi ngân hàng ở trạng thái bảo trì, bạn chưa tạo kết nối mới được. Các kết nối đang có vẫn tiếp tục nhận giao dịch. # Cơ chế tổ chức tài khoản ngân hàng (/vi/bank-accounts/organization) PayFS có hai Bank Setup Path. Banking Mode của Workspace quyết định bạn có thể dùng Bank Setup Path nào. ## Hai cách kết nối [#hai-cách-kết-nối] ### Open Banking [#open-banking] Kết nối trực tiếp với API của ngân hàng. Hiện hỗ trợ ba ngân hàng: | Ngân hàng | Mã | | --------- | ----- | | MBBank | `MB` | | ACB | `ACB` | | OCB | `OCB` | ### NAPAS [#napas] Kết nối qua hệ thống chuyển mạch quốc gia, phủ tất cả ngân hàng tại Việt Nam. ## Chọn cách nào [#chọn-cách-nào] | Bạn cần | Nên chọn | | ----------------------------------------- | ----------- | | Khách hàng tập trung ở ba ngân hàng trên | OpenBanking | | Khách hàng dùng nhiều ngân hàng khác nhau | NAPAS | Banking Mode gắn với **Banking Entity Type** của Workspace và cố định từ lúc tạo. Cá nhân và Hộ kinh doanh dùng Open Banking. Doanh nghiệp dùng Open Banking hoặc NAPAS. ## Tài khoản chính và tài khoản ảo [#tài-khoản-chính-và-tài-khoản-ảo] * **Main Bank Account** là tài khoản neo giữ Bank Connection của Workspace. * **Virtual Account** là số tài khoản do nhà cung cấp cấp và gắn với một Main Bank Account. Một Main Bank Account có thể có nhiều Virtual Account hoặc không có Virtual Account nào. Virtual Account hữu ích khi bạn muốn mỗi khách hàng hoặc mỗi đơn hàng có một số tài khoản nhận tiền riêng. Cách này giúp đối soát chính xác hơn mà không phụ thuộc vào nội dung chuyển khoản. ## Trạng thái ngân hàng [#trạng-thái-ngân-hàng] Mỗi ngân hàng có một trạng thái vận hành. Trạng thái này quyết định bạn có thể tạo Bank Connection mới hay không: | Trạng thái | Ý nghĩa | | ------------ | ------------------------------------------ | | Hoạt động | Kết nối mới bình thường | | Bảo trì | Tạm thời không tạo kết nối mới được | | Ngừng hỗ trợ | Không tạo kết nối mới, kết nối cũ vẫn chạy | Việc nhận giao dịch của các kết nối đang có không bị dừng khi ngân hàng chuyển sang bảo trì. ## Kết nối từng ngân hàng [#kết-nối-từng-ngân-hàng] * [MBBank](/vi/bank-accounts/mbbank) * [ACB](/vi/bank-accounts/acb) * [OCB](/vi/bank-accounts/ocb) # 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ể. Đừ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. ## 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`) | 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. ## 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 `. | | 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ụ. | # Liên kết thanh toán (/vi/developers/payment-link) Liên kết thanh toán thu một khoản thanh toán trong một Workspace. Người trả mở trang công khai `/l/{publicId}`. Bạn tạo liên kết từ Client Portal hoặc API Token. Open Banking cho phép bỏ trống số tiền. NAPAS bắt buộc số tiền cố định. Người trả không nhập số tiền trên trang công khai. ## Tạo liên kết [#tạo-liên-kết] Quyền cần có là `payment_links:write` trên Workspace. ```bash curl -X POST "https://api.payfs.vn/v1.1/payment-links/$WORKSPACE_ID" \ -H "Authorization: Bearer $PAYFS_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "bank_account_id": "bank-account-id", "callback_url": "https://example.com/payfs/callback", "amount": "25000", "redirect_url": "https://example.com/return", "description": "Hóa đơn 1042" }' ``` Bỏ `amount` khi Open Banking không cố định số tiền. Không gửi `amount` rỗng. Số tiền là số nguyên VND, tối thiểu 2.000. Tiền tệ luôn là VND. `callback_url` bắt buộc và phải là HTTPS. `redirect_url` không bắt buộc. Nếu có, cũng phải là HTTPS. `expires_at` không bắt buộc. Mặc định là 24 giờ sau lúc tạo. Thời hạn tùy chọn phải ở tương lai và không quá 24 giờ. Không có liên kết không hết hạn. `virtual_account_id` chỉ gửi khi tài khoản ngân hàng có tài khoản ảo đang hoạt động. CLI tương ứng: ```sh payfs payment-links create \ --workspace "$WORKSPACE_ID" \ --bank-account bank-account-id \ --callback-url https://example.com/payfs/callback \ --amount 25000 ``` ## Callback và chuyển hướng [#callback-và-chuyển-hướng] Callback URL không phải Redirect URL, và không phải webhook của Workspace. Khi Liên kết thanh toán hoàn tất, PayFS ghi **một** sự kiện callback thành công cho liên kết đó. PayFS gửi sự kiện này bằng HTTPS `POST` với nội dung JSON tới Callback URL. Liên kết hoàn tất khi có credit `matched` hoặc credit `overpaid`. PayFS không gửi callback khi liên kết hết hạn, bị hủy hoặc thất bại. ### Yêu cầu [#yêu-cầu] ```http POST /payfs/callback HTTP/1.1 Host: example.com Content-Type: application/json User-Agent: PayFS-Payment-Link/1 X-PayFS-Signature: 48cb1f3d63e4949ae29c85f6de0820fc319c23a07251ff3530a10d6ce596d754 X-PayFS-Timestamp: 1790474401 X-PayFS-Event-ID: 7379150348229279744 X-PayFS-Attempt: 1 {"amount":"25000","currency":"VND","id":"7379150348229279744","paid_at":"2026-09-27T02:00:00.000Z","payment_link_id":"7379149980103606272","public_id":"q3Xw9LmB2vRt7YkP0sDf4HjN","reference":"PFSL7K2M9Q4X","status":"success","transaction_id":"7379150347981815808","version":1} ``` Nội dung là JSON gọn, khóa xếp theo thứ tự bảng chữ cái. Hãy kiểm tra chữ ký trên đúng các byte thô của nội dung. Đừng phân tích rồi tạo lại JSON trước khi kiểm tra. | Trường | Kiểu | Ý nghĩa | | ----------------- | ------ | ----------------------------------------------------------------------------------------------------------------- | | `version` | number | Phiên bản payload. Giá trị là `1`. | | `id` | string | Mã sự kiện. Cùng giá trị với `X-PayFS-Event-ID`. | | `payment_link_id` | string | Mã nội bộ của Liên kết thanh toán. Dùng mã này với API. | | `public_id` | string | Mã công khai trong `/l/{publicId}`. Khác với `payment_link_id`. | | `status` | string | Luôn là `success`. Trạng thái của liên kết trên API là `succeeded`. Đừng trộn hai giá trị này. | | `amount` | string | Số tiền PayFS đã nhận, dạng số thập phân, đơn vị VND. Với credit `overpaid`, số này lớn hơn số tiền của liên kết. | | `currency` | string | Luôn là `VND`. | | `reference` | string | Mã tham chiếu chuyển khoản của liên kết. Liên kết mới dùng tiền tố `PFSL` và 8 ký tự tiếp theo (`A-Z`, `0-9`). | | `transaction_id` | string | Giao dịch PayFS đã hoàn tất liên kết. | | `paid_at` | string | Thời điểm ISO 8601 của credit hoàn tất, theo UTC. | | Header | Giá trị | | ------------------- | ----------------------------------------------------------------- | | `X-PayFS-Signature` | Chuỗi hex chữ thường của HMAC-SHA256, 64 ký tự. Không có tiền tố. | | `X-PayFS-Timestamp` | Thời gian Unix, tính bằng giây, lúc PayFS ký sự kiện. | | `X-PayFS-Event-ID` | Mã sự kiện. Cùng giá trị với `id` trong nội dung. | | `X-PayFS-Attempt` | Số thứ tự lần gửi. Lần đầu là `1`. | ### Chữ ký [#chữ-ký] 1. Đọc `X-PayFS-Timestamp` và nội dung thô. 2. Tạo chuỗi `${timestamp}.${body}`. 3. Tính HMAC-SHA256 của chuỗi đó (UTF-8), dùng khóa ký của Workspace làm khóa. Dùng toàn bộ chuỗi khóa, gồm cả tiền tố `plsk_`. 4. Mã hóa kết quả thành hex chữ thường. So sánh với `X-PayFS-Signature` bằng phép so sánh thời gian cố định. PayFS ký sự kiện một lần, lúc ghi sự kiện. Mỗi lần gửi lại dùng cùng nội dung, `X-PayFS-Signature`, `X-PayFS-Timestamp` và `X-PayFS-Event-ID`. Chỉ `X-PayFS-Attempt` thay đổi. Vì vậy, timestamp có thể cũ hơn lúc gửi. Chấp nhận timestamp cũ tối đa 24 giờ (86.400 giây). Từ chối timestamp cũ hơn. ```js import { createHmac, timingSafeEqual } from 'node:crypto'; const REPLAY_WINDOW_SECONDS = 24 * 60 * 60; const CLOCK_SKEW_SECONDS = 5 * 60; // rawBody: chuỗi nội dung yêu cầu, đúng như đã nhận. // secrets: khóa ký hiện tại, và khóa trước đó trong 24 giờ sau khi đổi khóa. export function verifyPayFSCallback(rawBody, headers, secrets) { const signature = String(headers['x-payfs-signature'] ?? ''); const timestamp = Number(headers['x-payfs-timestamp']); if (!/^[0-9a-f]{64}$/.test(signature) || !Number.isInteger(timestamp)) { return false; } const age = Math.floor(Date.now() / 1000) - timestamp; if (age > REPLAY_WINDOW_SECONDS || age < -CLOCK_SKEW_SECONDS) { return false; } const received = Buffer.from(signature, 'hex'); return secrets.some(secret => { const expected = createHmac('sha256', secret) .update(`${timestamp}.${rawBody}`, 'utf8') .digest(); return timingSafeEqual(received, expected); }); } ``` Để kiểm tra mã của bạn, dùng yêu cầu mẫu ở trên với khóa `plsk_example_do_not_use_in_production`. Đặt thời gian hiện tại bằng timestamp mẫu. Chữ ký phải hợp lệ. ### Phản hồi, thời gian chờ và gửi lại [#phản-hồi-thời-gian-chờ-và-gửi-lại] * Trả về mã `2xx` bất kỳ để xác nhận sự kiện. Sau đó PayFS dừng gửi. * PayFS chờ tối đa 30 giây cho mỗi lần gửi, gồm cả chuyển hướng. Bên vận hành có thể đổi giá trị này bằng `WEBHOOK_TIMEOUT` (mili giây). * PayFS theo tối đa 3 lần chuyển hướng. PayFS kiểm tra lại từng đích chuyển hướng. PayFS từ chối đích có địa chỉ riêng hoặc địa chỉ dành riêng. * PayFS gửi lại khi có lỗi mạng, hết thời gian chờ, `408`, `429` hoặc `5xx`. * Các trường hợp sau dừng gửi, và PayFS đánh dấu sự kiện thất bại: mã trạng thái khác, chuyển hướng bị từ chối, đích bị chặn, tên máy chủ không tồn tại, và chứng chỉ TLS không hợp lệ. * Mặc định, PayFS gửi tối đa 10 lần. Thời gian chờ trước lần gửi lại bắt đầu từ 10 giây và tăng gấp đôi sau mỗi lần, tối đa 512 giây. Bên vận hành có thể đổi các giá trị này bằng `WEBHOOK_MAX_ATTEMPTS`, `WEBHOOK_INITIAL_DELAY`, `WEBHOOK_BACKOFF_MULTIPLIER` và `WEBHOOK_MAX_DELAY`. ### Xử lý trùng lặp [#xử-lý-trùng-lặp] Mỗi Liên kết thanh toán có tối đa một sự kiện thành công. Credit lặp lại hoặc đồng thời không tạo sự kiện thứ hai. Tuy vậy, endpoint của bạn vẫn có thể nhận cùng một sự kiện nhiều lần, ví dụ khi phản hồi `2xx` của bạn không tới PayFS. Lưu `X-PayFS-Event-ID` (hoặc `id`). Nếu đã xử lý mã đó, trả về `2xx` và không làm gì thêm. ### Khóa ký [#khóa-ký] Chữ ký dùng khóa ký của Workspace. Owner hoặc Admin có tư cách thành viên đang hoạt động có thể xem hoặc đổi khóa trong cài đặt Workspace. Member, Viewer, API Token và CLI không thể xem hoặc đổi khóa. Đổi khóa chỉ giữ khóa ngay trước đó trong 24 giờ. Lần đổi tiếp theo thay khóa trước đó. PayFS không giữ khóa cũ hơn. Callback đã ghi giữ chữ ký của khóa đang dùng lúc ghi. Lần gửi lại không ký lại. Trong 24 giờ đó, hãy kiểm tra bằng cả khóa hiện tại và khóa trước đó. Khóa ký không nằm trên trang công khai và không nằm trong query chuyển hướng. Redirect URL là địa chỉ trình duyệt của người trả có thể mở. Query chỉ thêm trường khi có giá trị: `status=success` hoặc `status=failed`, `amount`, `link_id`, `transaction_id`, `paid_at`. `link_id` là mã công khai, không phải mã nội bộ của Liên kết thanh toán. Chuyển hướng trình duyệt **không** phải bằng chứng thanh toán. Hết hạn không tự chuyển hướng. Hết hạn cũng không gọi callback. Webhook Workspace giữ nguyên, gồm `transaction.credit`, `transaction.debit`, `order.success` và `order.failed`. PayFS không thêm sự kiện Workspace `payment_link.*` trong bản này. ## Trạng thái [#trạng-thái] | Trạng thái | Ý nghĩa | | ----------- | ---------------------------------------------------- | | `pending` | Đang chờ thanh toán. Trang công khai hiện hướng dẫn. | | `succeeded` | Đã thanh toán. Không hiện hướng dẫn. | | `failed` | Đóng ở trạng thái thất bại. Không hiện hướng dẫn. | | `expired` | Hết hạn. Không hiện hướng dẫn. | | `cancelled` | Đã hủy. Không hiện hướng dẫn. | Một lần thanh toán bị từ chối trên NAPAS không tự đóng liên kết đang chờ. Có thể thử lại trước khi hết hạn. Credit `matched` hoặc `overpaid` hoàn tất liên kết. Với credit `overpaid`, liên kết ghi số tiền đã nhận. Credit `underpaid`, `duplicate`, `late`, `below_minimum` hoặc `rejected` nằm trong lịch sử thanh toán và không hoàn tất liên kết. Liên kết đã đóng không chuyển lại `succeeded` vì credit trễ hoặc trùng. ## Hủy [#hủy] Chỉ hủy liên kết đang `pending`. ```bash curl -X POST "https://api.payfs.vn/v1.1/payment-links/$WORKSPACE_ID/$LINK_ID/cancel" \ -H "Authorization: Bearer $PAYFS_API_TOKEN" ``` ## Trang công khai [#trang-công-khai] Đường dẫn là `/l/{publicId}`. Trang không hiện mã nội bộ và cũng không hiện mã công khai. Trang cũng không hiện tên Workspace, URL callback, hoặc khóa ký. Khi đang chờ, trang hiện số tiền nếu có, thời hạn, QR, mã ngân hàng nhận, số tài khoản, chủ tài khoản và mã tham chiếu. Không có ô nhập số tiền. Nếu không cố định số tiền, trang không hiện số tiền và QR không gắn số tiền. Mất kết nối không có nghĩa là thanh toán thất bại. Hướng dẫn lần cuối vẫn ở lại. Trạng thái đóng thì ẩn hướng dẫn thanh toán. # Bắt đầu nhanh (/vi/developers/quickstart) Mục tiêu của hướng dẫn này là giúp hệ thống của bạn nhận thông báo ngay khi tài khoản ngân hàng có tiền vào. ## Cách PayFS hoạt động [#cách-payfs-hoạt-động] Bạn không cần liên tục gọi PayFS để kiểm tra giao dịch mới. PayFS sẽ chủ động gọi đến endpoint của bạn. ## Bốn bước [#bốn-bước] ### 1. Tạo Workspace và kết nối ngân hàng [#1-tạo-workspace-và-kết-nối-ngân-hàng] Thực hiện trên Client Portal. Xem [Tạo Workspace](/vi/workspace/create) và [Kết nối ngân hàng](/vi/bank-accounts/organization). ### 2. Dựng một endpoint nhận webhook [#2-dựng-một-endpoint-nhận-webhook] Endpoint cần công khai trên Internet và trả về HTTP 200. ```javascript const express = require('express'); const app = express(); app.use(express.json()); app.post('/payfs-webhook', (req, res) => { const apiKey = req.headers['x-client-api-key']; if (apiKey !== process.env.PAYFS_WEBHOOK_API_KEY) { return res.status(401).json({ error: 'Unauthorized' }); } const tx = req.body; if (tx.transfer_type === 'credit') { console.log('Tiền về:', tx.amount, 'VND —', tx.content); } res.status(200).json({ status: 'ok' }); }); app.listen(3000); ``` ### 3. Khai báo endpoint trong Client Portal [#3-khai-báo-endpoint-trong-client-portal] Vào phần thông báo của Workspace, tạo webhook rồi dán URL endpoint. PayFS sẽ tạo sẵn API key và secret cho webhook đó. ### 4. Thử một giao dịch thật [#4-thử-một-giao-dịch-thật] Chuyển một khoản nhỏ vào tài khoản đã kết nối. Endpoint của bạn sẽ nhận webhook trong vài giây. Endpoint phải trả lời trong **30 giây**. Nếu xử lý nghiệp vụ lâu, hãy trả 200 trước rồi đẩy việc sang hàng đợi nền. Trả lời chậm bị tính là thất bại và PayFS sẽ gửi lại. ## Tiếp theo [#tiếp-theo] | Việc | Đọc trang | | --------------------------------- | -------------------------------------------------- | | Hiểu payload và các sự kiện | [Webhook](/vi/developers/webhooks) | | Xác minh chữ ký để chống giả mạo | [Chữ ký webhook](/vi/developers/webhook-signature) | | Gọi API của PayFS | [API Token](/vi/developers/api-token) | | Thu một khoản qua trang công khai | [Liên kết thanh toán](/vi/developers/payment-link) | # Chữ ký webhook (/vi/developers/webhook-signature) Kiểm tra API key đã đủ để biết ai gọi. Kiểm tra chữ ký cho biết thêm rằng **nội dung không bị sửa trên đường truyền**, và chống tấn công phát lại. Nên làm với mọi endpoint liên quan tới tiền. ## Thuật toán [#thuật-toán] PayFS ký theo ba bước: ``` 1. sorted = sắp xếp khóa JSON theo alphabet, đệ quy 2. data = timestamp + "." + JSON.stringify(sorted) 3. sig = HMAC_SHA256(data, webhook_secret) dạng hex ``` Ba điểm hay làm sai: 1. **Có dấu chấm** giữa timestamp và payload. Thiếu nó thì chữ ký không bao giờ khớp. 2. **Khóa JSON phải được sắp xếp** đúng như PayFS đã làm. 3. **Chữ ký là hex thô 64 ký tự, không có tiền tố.** Đừng tìm `sha256=`, PayFS không gửi. Chữ ký nằm ở header `X-PayFS-Signature`, timestamp ở `X-PayFS-Timestamp`. Chữ ký hết hạn sau **5 phút**. ## Node.js [#nodejs] ```javascript const crypto = require('crypto'); function sortObjectKeys(obj) { if (typeof obj !== 'object' || obj === null) return obj; if (Array.isArray(obj)) return obj.map(sortObjectKeys); return Object.keys(obj).sort().reduce((acc, k) => { acc[k] = sortObjectKeys(obj[k]); return acc; }, {}); } function verifyWebhookSignature(payload, signature, timestamp, secret) { // 1. Chặn tấn công phát lại if (Math.floor(Date.now() / 1000) - timestamp > 300) { return { valid: false, error: 'Chữ ký đã hết hạn' }; } // 2. Dựng lại chuỗi được ký const sorted = JSON.stringify(sortObjectKeys(JSON.parse(payload))); const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}.${sorted}`, 'utf8') .digest('hex'); // 3. So sánh theo thời gian hằng số. // Kiểm tra độ dài trước, vì timingSafeEqual ném lỗi khi hai buffer lệch độ dài. if (signature.length !== expected.length) { return { valid: false, error: 'Chữ ký không hợp lệ' }; } const ok = crypto.timingSafeEqual( Buffer.from(signature, 'hex'), Buffer.from(expected, 'hex') ); return ok ? { valid: true } : { valid: false, error: 'Chữ ký không hợp lệ' }; } ``` Dùng trong endpoint: ```javascript app.post('/payfs-webhook', (req, res) => { const apiKey = req.headers['x-client-api-key']; if (apiKey !== process.env.PAYFS_WEBHOOK_API_KEY) { return res.status(401).json({ error: 'Unauthorized' }); } const result = verifyWebhookSignature( JSON.stringify(req.body), req.headers['x-payfs-signature'], parseInt(req.headers['x-payfs-timestamp'], 10), process.env.PAYFS_WEBHOOK_SECRET ); if (!result.valid) { return res.status(401).json({ error: result.error }); } handleTransaction(req.body); res.status(200).json({ status: 'ok' }); }); ``` ## PHP [#php] ```php $v) $obj[$k] = sortObjectKeys($v); return $obj; } function verifyWebhookSignature($payload, $signature, $timestamp, $secret) { if (time() - $timestamp > 300) { return false; } $sorted = json_encode(sortObjectKeys(json_decode($payload, true)), JSON_UNESCAPED_SLASHES); $expected = hash_hmac('sha256', $timestamp . '.' . $sorted, $secret); return hash_equals($expected, $signature); } ``` ## Kiểm thử [#kiểm-thử] Ví dụ dưới đây tái lập được. Chạy thử để chắc chắn code của bạn đúng. ```javascript const crypto = require('crypto'); const secret = 'whsec_example_secret_do_not_use_in_production'; const timestamp = 1758173916; const payload = '{"account_id":"1418079746853494784","amount":14000,"bank":"MB","bank_account_number":"0933723830","content":"NGUYEN VAN A chuyen tien Ma giao dich Trace773231","transaction_date":"2025-09-15T15:02:00.000Z","transaction_id":"1418108930751619072","transfer_type":"credit"}'; const sig = crypto .createHmac('sha256', secret) .update(`${timestamp}.${payload}`, 'utf8') .digest('hex'); console.log(sig); // 86f02cefae56d51f72a00e04bf9d5a96b40cfe6902d54e495234c447ec706c5e ``` Không ra đúng chuỗi trên nghĩa là bạn đã sai ở một trong ba điểm nêu đầu trang. ## Xử lý sự cố [#xử-lý-sự-cố] **Chữ ký không hợp lệ** 1. Thiếu dấu chấm giữa timestamp và payload 2. Khóa JSON chưa được sắp xếp 3. Code đang cắt tiền tố `sha256=` mà PayFS không gửi 4. Sai webhook secret 5. Payload bị sửa trước khi xác minh, hãy dùng body thô **Chữ ký đã hết hạn** Đồng hồ máy chủ lệch, hoặc endpoint xử lý quá 5 phút. Đồng bộ giờ bằng NTP, và trả 200 trước rồi xử lý nghiệp vụ sau. # Webhook (/vi/developers/webhooks) Khi tài khoản ngân hàng có biến động, PayFS gửi một HTTP POST tới endpoint của bạn. Chưa dựng endpoint bao giờ, đọc [Bắt đầu nhanh](/vi/developers/quickstart) trước. ## Payload [#payload] ```json { "account_id": "1418079746853494784", "amount": 14000, "bank": "MB", "bank_account_number": "0933723830", "content": "NGUYEN VAN A chuyen tien Ma giao dich Trace773231", "transaction_date": "2025-09-15T15:02:00.000Z", "transaction_id": "1418108930751619072", "transfer_type": "credit" } ``` | Trường | Kiểu | Mô tả | | --------------------- | ------ | ---------------------------------------------------------------- | | `transaction_id` | string | ID giao dịch, duy nhất toàn hệ thống. Dùng làm khóa chống trùng. | | `account_id` | string | ID tài khoản ngân hàng trong PayFS | | `amount` | number | Số tiền, đơn vị VND, luôn là số nguyên dương | | `transfer_type` | string | `credit` là tiền vào, `debit` là tiền ra | | `content` | string | Nội dung chuyển khoản do ngân hàng trả về | | `transaction_date` | string | Thời điểm giao dịch, ISO 8601 theo giờ UTC | | `bank_account_number` | string | Số tài khoản nhận hoặc gửi | | `bank` | string | Mã ngân hàng: `MB`, `ACB`, `OCB` | `amount` luôn dương. Dùng `transfer_type` để biết tiền vào hay ra, đừng dựa vào dấu. ## Sự kiện [#sự-kiện] Khi tạo webhook, bạn chọn sự kiện muốn nhận. | Sự kiện | Khi nào | Payload | | -------------------- | ------------------------------ | -------- | | `transaction.credit` | Tiền vào tài khoản | Như trên | | `transaction.debit` | Tiền ra khỏi tài khoản | Như trên | | `order.success` | Đơn hàng thanh toán thành công | Xem dưới | | `order.failed` | Đơn hàng thanh toán thất bại | Xem dưới | Hai sự kiện `order.*` dùng cấu trúc khác: ```json { "order_id": "1418108930751619072", "amount": 250000, "status": "success", "customer_email": "khachhang@example.com", "created_at": "2025-09-15T15:02:00.000Z" } ``` Chỉ `order_id`, `amount` và `status` là bắt buộc. Ba trường còn lại có thể vắng. `order.success` và `order.failed` là sự kiện webhook của Workspace. Chúng không đổi trong bản này. Callback của một Liên kết thanh toán là HTTPS POST riêng tới Callback URL của liên kết đó, không phải hai sự kiện này. Xem [Liên kết thanh toán](/vi/developers/payment-link). ## Header [#header] PayFS gửi kèm 5 header sau mỗi lần gọi. | Header | Ví dụ | Dùng để | | -------------------- | ------------- | ------------------------------------------- | | `X-Client-API-Key` | `pk_1234...` | Xác thực nguồn gọi. **Luôn kiểm tra.** | | `X-PayFS-Signature` | `86f02cef...` | Chữ ký HMAC-SHA256, hex thô 64 ký tự | | `X-PayFS-Timestamp` | `1758173916` | UNIX timestamp, dùng chung với chữ ký | | `X-PayFS-Webhook-ID` | `1418108...` | ID của webhook endpoint | | `X-PayFS-Attempt` | `1` | Lần gửi thứ mấy | Kiểm tra API key là bắt buộc. Kiểm tra chữ ký là tùy chọn nhưng nên làm, xem [Chữ ký webhook](/vi/developers/webhook-signature). ## Xác thực bằng API key [#xác-thực-bằng-api-key] ```javascript app.post('/payfs-webhook', (req, res) => { const apiKey = req.headers['x-client-api-key']; if (!apiKey || apiKey !== process.env.PAYFS_WEBHOOK_API_KEY) { return res.status(401).json({ error: 'Unauthorized' }); } handleTransaction(req.body); res.status(200).json({ status: 'ok' }); }); ``` ```php 'Unauthorized']); exit; } $transaction = json_decode(file_get_contents('php://input'), true); handleTransaction($transaction); http_response_code(200); echo json_encode(['status' => 'ok']); ``` ## Chống xử lý trùng [#chống-xử-lý-trùng] PayFS gửi lại khi thất bại, nên cùng một giao dịch có thể tới nhiều lần. Dùng `transaction_id` làm khóa chống trùng. ```javascript if (await daXuLy(tx.transaction_id)) { return res.status(200).json({ status: 'already_processed' }); } await danhDauDaXuLy(tx.transaction_id); ``` Lưu vào cơ sở dữ liệu hoặc Redis, đừng lưu trong bộ nhớ tiến trình. ## Gửi lại khi thất bại [#gửi-lại-khi-thất-bại] PayFS coi là thành công khi endpoint trả mã 2xx. | Thông số | Mặc định | | ------------------------- | -------- | | Thời gian chờ mỗi lần gửi | 30 giây | | Số lần thử tối đa | 10 | | Khoảng chờ lần đầu | 10 giây | | Hệ số tăng khoảng chờ | 2 | Endpoint phải trả lời trong **30 giây**. Xử lý lâu thì trả 200 trước rồi đẩy việc sang hàng đợi nền. Trả lời chậm bị tính là thất bại và PayFS sẽ gửi lại. ## Mã trạng thái nên trả về [#mã-trạng-thái-nên-trả-về] | Tình huống | Mã | | ---------------------- | --------------------- | | Xử lý xong | 200 | | Thiếu hoặc sai API key | 401 | | Payload không hợp lệ | 400 | | Lỗi tạm thời phía bạn | 500, PayFS sẽ gửi lại | ## Xử lý sự cố [#xử-lý-sự-cố] **Thiếu header `X-Client-API-Key`** Đa số framework chuẩn hóa tên header về chữ thường. Đọc `x-client-api-key`. **Sai API key** Đối chiếu lại với giá trị trong Client Portal, đồng thời kiểm tra chuỗi không bị cắt khi truyền. **Webhook không được gọi** Kiểm tra URL truy cập được từ Internet, đã chọn đúng sự kiện, và tường lửa không chặn. Lịch sử gửi trong Client Portal cho biết PayFS đã thử gửi chưa và nhận được mã phản hồi nào. # Tích hợp Easy Platform (/vi/frameworks/easy-platform) Tích hợp Easy Platform **chưa phát hành**. Nó nằm trong kế hoạch phát triển, chưa có ngày phát hành cụ thể. ## Hiện tại tích hợp thế nào? [#hiện-tại-tích-hợp-thế-nào] PayFS gửi giao dịch qua webhook. Vì vậy, bạn có thể tích hợp với Easy Platform ngay bằng cách nhận webhook trên máy chủ của mình rồi chuyển dữ liệu sang Easy Platform. 1. [Thiết lập webhook](/vi/developers/webhooks) trỏ về máy chủ của bạn 2. Xác minh chữ ký để chắc chắn request đến từ PayFS, xem [Chữ ký webhook](/vi/developers/webhook-signature) 3. Từ máy chủ của bạn, ghi dữ liệu sang Easy Platform Trang [Webhook](/vi/developers/webhooks) có ví dụ hoàn chỉnh bằng Node.js và PHP. ## Cần hỗ trợ [#cần-hỗ-trợ] Nếu bạn đang xây dựng tích hợp Easy Platform và cần trao đổi, liên hệ qua [Telegram](https://t.me/+CHaEUcOhygAyNDY1) hoặc [Discord](https://discord.gg/qYGfhpPW). # Tích hợp Google Sheets (/vi/frameworks/google-sheets) Tích hợp Google Sheets **chưa phát hành**. Nó nằm trong kế hoạch phát triển, chưa có ngày phát hành cụ thể. ## Hiện tại tích hợp thế nào? [#hiện-tại-tích-hợp-thế-nào] PayFS gửi giao dịch qua webhook. Vì vậy, bạn có thể tích hợp với Google Sheets ngay bằng cách nhận webhook trên máy chủ của mình rồi chuyển dữ liệu sang Google Sheets. 1. [Thiết lập webhook](/vi/developers/webhooks) trỏ về máy chủ của bạn 2. Xác minh chữ ký để chắc chắn request đến từ PayFS, xem [Chữ ký webhook](/vi/developers/webhook-signature) 3. Từ máy chủ của bạn, ghi dữ liệu sang Google Sheets Trang [Webhook](/vi/developers/webhooks) có ví dụ hoàn chỉnh bằng Node.js và PHP. ## Cần hỗ trợ [#cần-hỗ-trợ] Nếu bạn đang xây dựng tích hợp Google Sheets và cần trao đổi, liên hệ qua [Telegram](https://t.me/+CHaEUcOhygAyNDY1) hoặc [Discord](https://discord.gg/qYGfhpPW). # Tích hợp Laravel (/vi/frameworks/laravel) Tích hợp Laravel **chưa phát hành**. Nó nằm trong kế hoạch phát triển, chưa có ngày phát hành cụ thể. ## Hiện tại tích hợp thế nào? [#hiện-tại-tích-hợp-thế-nào] PayFS gửi giao dịch qua webhook. Vì vậy, bạn có thể tích hợp với Laravel ngay bằng cách nhận webhook trên máy chủ của mình rồi chuyển dữ liệu sang Laravel. 1. [Thiết lập webhook](/vi/developers/webhooks) trỏ về máy chủ của bạn 2. Xác minh chữ ký để chắc chắn request đến từ PayFS, xem [Chữ ký webhook](/vi/developers/webhook-signature) 3. Từ máy chủ của bạn, ghi dữ liệu sang Laravel Trang [Webhook](/vi/developers/webhooks) có ví dụ hoàn chỉnh bằng Node.js và PHP. ## Cần hỗ trợ [#cần-hỗ-trợ] Nếu bạn đang xây dựng tích hợp Laravel và cần trao đổi, liên hệ qua [Telegram](https://t.me/+CHaEUcOhygAyNDY1) hoặc [Discord](https://discord.gg/qYGfhpPW). # Tích hợp Lark Base (/vi/frameworks/lark) Tích hợp Lark Base **chưa phát hành**. Nó nằm trong kế hoạch phát triển, chưa có ngày phát hành cụ thể. ## Hiện tại tích hợp thế nào? [#hiện-tại-tích-hợp-thế-nào] PayFS gửi giao dịch qua webhook. Vì vậy, bạn có thể tích hợp với Lark Base ngay bằng cách nhận webhook trên máy chủ của mình rồi chuyển dữ liệu sang Lark Base. 1. [Thiết lập webhook](/vi/developers/webhooks) trỏ về máy chủ của bạn 2. Xác minh chữ ký để chắc chắn request đến từ PayFS, xem [Chữ ký webhook](/vi/developers/webhook-signature) 3. Từ máy chủ của bạn, ghi dữ liệu sang Lark Base Trang [Webhook](/vi/developers/webhooks) có ví dụ hoàn chỉnh bằng Node.js và PHP. ## Cần hỗ trợ [#cần-hỗ-trợ] Nếu bạn đang xây dựng tích hợp Lark Base và cần trao đổi, liên hệ qua [Telegram](https://t.me/+CHaEUcOhygAyNDY1) hoặc [Discord](https://discord.gg/qYGfhpPW). # Tích hợp WordPress (/vi/frameworks/wordpress) Tích hợp WordPress **chưa phát hành**. Nó nằm trong kế hoạch phát triển, chưa có ngày phát hành cụ thể. ## Hiện tại tích hợp thế nào? [#hiện-tại-tích-hợp-thế-nào] PayFS gửi giao dịch qua webhook. Vì vậy, bạn có thể tích hợp với WordPress ngay bằng cách nhận webhook trên máy chủ của mình rồi chuyển dữ liệu sang WordPress. 1. [Thiết lập webhook](/vi/developers/webhooks) trỏ về máy chủ của bạn 2. Xác minh chữ ký để chắc chắn request đến từ PayFS, xem [Chữ ký webhook](/vi/developers/webhook-signature) 3. Từ máy chủ của bạn, ghi dữ liệu sang WordPress Trang [Webhook](/vi/developers/webhooks) có ví dụ hoàn chỉnh bằng Node.js và PHP. ## Cần hỗ trợ [#cần-hỗ-trợ] Nếu bạn đang xây dựng tích hợp WordPress và cần trao đổi, liên hệ qua [Telegram](https://t.me/+CHaEUcOhygAyNDY1) hoặc [Discord](https://discord.gg/qYGfhpPW). # Đăng nhập (/vi/getting-started/login) Bạn đăng nhập bằng email và mật khẩu đã dùng khi đăng ký. Màn hình đăng nhập PayFS ## Yêu cầu mật khẩu [#yêu-cầu-mật-khẩu] * Từ 8 đến 128 ký tự * Có ít nhất 1 chữ thường, 1 chữ hoa và 1 chữ số Ký tự đặc biệt được chấp nhận nhưng không bắt buộc. Nếu quên mật khẩu, xem [Khôi phục mật khẩu](/vi/getting-started/password-recovery). ## Giữ tài khoản an toàn [#giữ-tài-khoản-an-toàn] * Không dùng lại mật khẩu PayFS ở dịch vụ khác * Dùng trình quản lý mật khẩu thay vì tự nhớ * Với hệ thống tự động, đừng chia sẻ mật khẩu đăng nhập. Hãy tạo [API Token](/vi/developers/api-token) riêng và chỉ cấp quyền tối thiểu cần thiết. ## Đang phát triển [#đang-phát-triển] Các cách đăng nhập sau **chưa khả dụng và đang được lên kế hoạch phát triển**: xác thực hai yếu tố bằng ứng dụng Authenticator hoặc mã OTP qua SMS, và đăng nhập một lần với Google Workspace, Microsoft Entra ID hoặc SAML 2.0. # Quên mật khẩu (/vi/getting-started/password-recovery) ## Các bước [#các-bước] 1. Ở trang đăng nhập, bấm **Quên mật khẩu?** Trang khôi phục mật khẩu 2. Nhập email đã đăng ký rồi chọn **Gửi** 3. Mở email PayFS gửi đến rồi nhấp vào liên kết trong email 4. Nhập mật khẩu mới và xác nhận Liên kết khôi phục có hiệu lực trong **1 giờ**. Không chia sẻ liên kết này, vì bất kỳ ai có liên kết đều có thể đặt lại mật khẩu của bạn. ## Mật khẩu mới [#mật-khẩu-mới] * Từ 8 đến 128 ký tự * Có ít nhất 1 chữ thường, 1 chữ hoa và 1 chữ số Ký tự đặc biệt được chấp nhận nhưng không bắt buộc. | Ví dụ | Kết quả | | --------------- | ---------------- | | `MyPayFS2026Ab` | Đạt | | `payfs123` | Thiếu chữ hoa | | `PAYFS123` | Thiếu chữ thường | | `PayFSabc` | Thiếu chữ số | ## Sau khi đổi mật khẩu [#sau-khi-đổi-mật-khẩu] Nếu bạn nghi ngờ tài khoản từng bị người khác truy cập: 1. Xoay vòng [API Token](/vi/developers/api-token), vì token cũ có thể đã bị sao chép 2. Kiểm tra danh sách webhook, xem có endpoint lạ không 3. Cập nhật khóa trong các hệ thống đang gọi PayFS ## Không nhận được email [#không-nhận-được-email] 1. Kiểm tra thư mục Spam, đánh dấu PayFS là người gửi an toàn 2. Cho phép `noreply@payfs.vn` và `support@payfs.vn` 3. Đợi 5 đến 10 phút rồi yêu cầu gửi lại ## Không truy cập được email [#không-truy-cập-được-email] Liên hệ bộ phận hỗ trợ và cung cấp email đăng ký cùng họ tên đầy đủ. [support@payfs.vn](mailto:support@payfs.vn) · Hotline và Zalo 08228 85558 · [Telegram](https://t.me/+CHaEUcOhygAyNDY1) # Đăng ký tài khoản (/vi/getting-started/registration) Đăng ký miễn phí và chỉ mất vài phút. ## 1. Điền thông tin [#1-điền-thông-tin] Truy cập [payfs.vn](https://payfs.vn), rồi chọn **Đăng ký**. Màn hình đăng ký PayFS | Trường | Bắt buộc | Ghi chú | | ------------- | -------- | ------------------------------------------------- | | Họ và tên | Có | | | Email | Có | Dùng làm tên đăng nhập. | | Số điện thoại | Không | Có thể bổ sung sau. | | Mật khẩu | Có | 8 đến 128 ký tự, có chữ thường, chữ hoa và chữ số | ## 2. Xác thực email [#2-xác-thực-email] Mở email PayFS gửi đến rồi nhấp vào liên kết xác thực. Nếu không thấy email, hãy kiểm tra thư mục Spam. ## 3. Tạo Workspace [#3-tạo-workspace] Sau khi đăng nhập, tạo một Workspace rồi kết nối tài khoản ngân hàng. Xem [Tạo Workspace](/vi/workspace/create). ## Gói khởi điểm [#gói-khởi-điểm] Tài khoản mới dùng gói **Free**: 1 Workspace và 30 giao dịch mỗi tháng. Gói này phù hợp để thử nghiệm tích hợp. Xem [gói dịch vụ](/vi/pricing/service-packages) khi cần tăng hạn mức. ## Đang phát triển [#đang-phát-triển] Chưa có trong quy trình đăng ký: xác thực số điện thoại qua SMS, khai báo thông tin doanh nghiệp, và xác minh danh tính bằng giấy tờ. Thông tin doanh nghiệp phục vụ kết nối ngân hàng được khai ở bước [kết nối ngân hàng](/vi/bank-accounts/organization), không phải khi đăng ký. ## Không nhận được email xác thực [#không-nhận-được-email-xác-thực] 1. Kiểm tra thư mục Spam, đánh dấu PayFS là người gửi an toàn 2. Cho phép `noreply@payfs.vn` 3. Bấm **Gửi lại email xác thực**, đợi 5 đến 10 phút Nếu vẫn không nhận được, hãy liên hệ [support@payfs.vn](mailto:support@payfs.vn) hoặc gọi hotline 08228 85558. # NAPAS là gì? (/vi/getting-started/what-is-napas) NAPAS, tên đầy đủ là Công ty Cổ phần Thanh toán Quốc gia Việt Nam, là đơn vị cung cấp dịch vụ chuyển mạch thanh toán điện tử tại Việt Nam. ## Tổng quan về NAPAS [#tổng-quan-về-napas] NAPAS là hạ tầng trung tâm của hệ thống thanh toán điện tử Việt Nam, với các vai trò: * **Chuyển mạch trung tâm**: Kết nối tất cả ngân hàng và tổ chức tài chính * **Xử lý giao dịch**: Thanh toán thẻ, chuyển tiền liên ngân hàng * **Đảm bảo an toàn**: Bảo mật và giám sát các giao dịch * **Tuân thủ quy định**: Đáp ứng các tiêu chuẩn quốc tế và quy định của NHNN ## Các dịch vụ chính của NAPAS [#các-dịch-vụ-chính-của-napas] ### 1. Chuyển mạch ATM [#1-chuyển-mạch-atm] * Kết nối mạng lưới ATM toàn quốc * Cho phép khách hàng rút tiền tại ATM của ngân hàng khác * Xử lý giao dịch tra cứu số dư, chuyển tiền nhanh ### 2. Chuyển mạch POS [#2-chuyển-mạch-pos] * Kết nối thiết bị POS tại các đơn vị chấp nhận thanh toán * Xử lý thanh toán thẻ tại cửa hàng và nhà hàng * Hỗ trợ cả thẻ từ và thẻ chip ### 3. Chuyển mạch Internet Banking [#3-chuyển-mạch-internet-banking] * Kết nối hệ thống Internet Banking giữa các ngân hàng * Chuyển tiền liên ngân hàng online 24/7 * Đảm bảo an toàn và minh bạch giao dịch ### 4. Chuyển mạch thanh toán di động [#4-chuyển-mạch-thanh-toán-di-động] * Hỗ trợ thanh toán di động (QR Code, NFC) * Kết nối ví điện tử với ngân hàng * Xử lý giao dịch P2P và P2B ### 5. IBPS (Interbank Payment System) [#5-ibps-interbank-payment-system] * Hệ thống thanh toán liên ngân hàng 24/7 * Chuyển tiền nhanh trong 15 giây * Phí thấp, giao dịch an toàn ## NAPAS và hệ sinh thái Fintech [#napas-và-hệ-sinh-thái-fintech] ### Vai trò trung gian [#vai-trò-trung-gian] NAPAS đóng vai trò **trung tâm kết nối**: ``` Ngân hàng A ↔ NAPAS ↔ Ngân hàng B ↑ ↓ Fintech ←→ NAPAS ←→ Ví điện tử ↑ ↓ PayFS ←→ NAPAS ←→ Đơn vị chấp nhận thanh toán ``` ### API và dịch vụ cho Fintech [#api-và-dịch-vụ-cho-fintech] * **Cổng API**: Cung cấp API chuẩn cho các fintech * **Môi trường thử nghiệm**: Môi trường thử nghiệm miễn phí * **Chương trình chứng nhận**: Chứng nhận an toàn cho đối tác * **Hỗ trợ kỹ thuật**: Hỗ trợ kỹ thuật chuyên sâu ## PayFS và NAPAS [#payfs-và-napas] PayFS cung cấp hình thức kết nối qua NAPAS bên cạnh Open Banking. Với hình thức này, Workspace của bạn nhận được giao dịch từ mọi ngân hàng tại Việt Nam, thay vì chỉ ba ngân hàng mà PayFS kết nối trực tiếp. ### Khi nào nên chọn NAPAS [#khi-nào-nên-chọn-napas] * Khách hàng của bạn dùng nhiều ngân hàng khác nhau * Bạn cần phạm vi bao phủ rộng hơn thay vì thông tin giao dịch chi tiết Xem [Cơ chế tổ chức tài khoản ngân hàng](/vi/bank-accounts/organization) để so sánh hai hình thức. ## Quy định và tuân thủ [#quy-định-và-tuân-thủ] ### Các chuẩn kỹ thuật NAPAS vận hành [#các-chuẩn-kỹ-thuật-napas-vận-hành] * **ISO 8583**: Chuẩn định dạng thông điệp cho giao dịch tài chính * **EMV**: Chuẩn bảo mật cho thẻ chip * **PCI DSS**: Bảo mật dữ liệu thẻ thanh toán * **3D Secure**: Xác thực bổ sung cho giao dịch online ### Quy trình kiểm tra [#quy-trình-kiểm-tra] * **Kiểm thử xâm nhập**: Kiểm tra bảo mật định kỳ * **Kiểm toán tuân thủ**: Kiểm toán hàng năm * **Đánh giá rủi ro**: Đánh giá thường xuyên * **Ứng phó sự cố**: Quy trình xử lý sự cố 24/7 ## Tương lai và phát triển [#tương-lai-và-phát-triển] ### Lộ trình phát triển của NAPAS [#lộ-trình-phát-triển-của-napas] * **Tiền kỹ thuật số của ngân hàng trung ương (CBDC)**: Hỗ trợ tiền số ngân hàng trung ương * **Thanh toán xuyên biên giới**: Thanh toán xuyên biên giới * **Tích hợp AI/ML**: Ứng dụng AI trong phòng chống gian lận * **Công nghệ blockchain**: Nghiên cứu công nghệ blockchain ### Cơ hội cho Fintech [#cơ-hội-cho-fintech] * **Open Banking**: NAPAS hỗ trợ mạnh mẽ xu hướng ngân hàng mở * **RegTech**: Công nghệ hỗ trợ tuân thủ quy định * **InsurTech**: Mở rộng sang lĩnh vực bảo hiểm * **WealthTech**: Dịch vụ quản lý tài sản số # OpenBanking là gì? (/vi/getting-started/what-is-openbanking) OpenBanking (ngân hàng mở) là mô hình cho phép bên thứ ba truy cập dữ liệu ngân hàng qua API (Application Programming Interface) một cách an toàn và được ủy quyền. ## Khái niệm OpenBanking [#khái-niệm-openbanking] OpenBanking tạo ra một hệ sinh thái tài chính mở, trong đó: * **Ngân hàng** cung cấp API để chia sẻ dữ liệu khách hàng * **Fintech** có thể xây dựng sản phẩm và dịch vụ trên nền tảng ngân hàng * **Khách hàng** được hưởng lợi từ các dịch vụ tài chính đa dạng và tiện ích hơn ## Lợi ích của OpenBanking [#lợi-ích-của-openbanking] ### Cho khách hàng [#cho-khách-hàng] * **Trải nghiệm tốt hơn**: Quản lý tài chính từ một ứng dụng * **Dịch vụ đa dạng**: Nhiều lựa chọn từ các nhà cung cấp khác nhau * **Chi phí thấp hơn**: Cạnh tranh tạo ra giá cả hợp lý * **Kiểm soát dữ liệu**: Quyết định chia sẻ thông tin với ai ### Cho doanh nghiệp [#cho-doanh-nghiệp] * **Tích hợp nhanh**: Không cần thương lượng hợp đồng phức tạp * **Đổi mới sản phẩm**: Xây dựng dịch vụ trên API ngân hàng * **Giảm chi phí**: Không cần đầu tư hạ tầng ngân hàng * **Ra mắt nhanh**: Đưa sản phẩm ra thị trường trong vài tuần ### Cho ngân hàng [#cho-ngân-hàng] * **Mở rộng hệ sinh thái**: Thu hút đối tác fintech * **Tăng doanh thu**: Phí API và dịch vụ bổ sung * **Đổi mới công nghệ**: Học hỏi từ startup fintech * **Cải thiện trải nghiệm**: Khách hàng có nhiều lựa chọn dịch vụ ## OpenBanking tại Việt Nam [#openbanking-tại-việt-nam] ### Tình hình hiện tại [#tình-hình-hiện-tại] * **Ngân hàng Nhà nước** đang xây dựng khung pháp lý * **Các ngân hàng lớn** như Vietcombank, BIDV, MBBank đã có API * **Fintech** như PayFS có thể tích hợp với các ngân hàng * **Doanh nghiệp** bắt đầu áp dụng để tự động hóa thanh toán ### Các tiêu chuẩn thường gặp trong ngành [#các-tiêu-chuẩn-thường-gặp-trong-ngành] Đây là những tiêu chuẩn mà các bên tham gia OpenBanking thường áp dụng. Mỗi tổ chức tự công bố phạm vi chứng nhận của mình. * **PCI DSS**: bảo mật dữ liệu thẻ thanh toán * **ISO 27001**: quản lý an toàn thông tin * **OAuth 2.0 và JWT**: xác thực và ủy quyền cho API * **Luật An toàn thông tin mạng**: quy định về bảo vệ dữ liệu tại Việt Nam ## Cách thức hoạt động [#cách-thức-hoạt-động] ### 1. Đăng ký và xác thực [#1-đăng-ký-và-xác-thực] ### 2. Luồng giao dịch [#2-luồng-giao-dịch] ## PayFS và OpenBanking [#payfs-và-openbanking] PayFS đóng vai trò là **cầu nối** giữa doanh nghiệp và ngân hàng: ### Vai trò của PayFS [#vai-trò-của-payfs] * **Tổng hợp**: Tập hợp API từ nhiều ngân hàng * **Chuẩn hóa**: Thống nhất định dạng dữ liệu và API * **Bảo mật**: Bảo vệ dữ liệu trong quá trình trao đổi * **Hỗ trợ**: Hỗ trợ kỹ thuật và tư vấn nghiệp vụ ### Lợi ích khi sử dụng PayFS [#lợi-ích-khi-sử-dụng-payfs] * **Một API cho nhiều ngân hàng**: Không cần tích hợp từng ngân hàng riêng * **Xử lý phần phức tạp**: PayFS xử lý các trường hợp đặc biệt và lỗi * **Tuân thủ**: Hỗ trợ đáp ứng các quy định pháp lý * **Hỗ trợ 24/7**: Hỗ trợ kỹ thuật liên tục ## Tương lai của OpenBanking [#tương-lai-của-openbanking] ### Xu hướng phát triển [#xu-hướng-phát-triển] * **Ngân hàng ưu tiên API**: Ngân hàng thiết kế sản phẩm dựa trên API * **Tài chính tích hợp**: Tích hợp dịch vụ tài chính vào mọi ứng dụng * **Thanh toán theo thời gian thực**: Thanh toán tức thời 24/7 * **Thông tin chuyên sâu dựa trên dữ liệu**: Phân tích dữ liệu để cải thiện dịch vụ ### Cơ hội cho doanh nghiệp [#cơ-hội-cho-doanh-nghiệp] * **Nguồn doanh thu mới**: Tạo doanh thu từ dịch vụ tài chính * **Trải nghiệm khách hàng tốt hơn**: Trải nghiệm liền mạch * **Hiệu quả vận hành**: Tự động hóa quy trình tài chính * **Cơ hội đổi mới**: Phát triển sản phẩm dựa trên dữ liệu tài chính *** # PayFS là gì? (/vi/getting-started/what-is-payfs) PayFS là nền tảng tích hợp thanh toán ngân hàng do Công ty cổ phần Pay5S phát triển. Nền tảng này giúp doanh nghiệp và nhà phát triển kết nối với hệ thống ngân hàng để theo dõi và xử lý giao dịch tự động. ## Tổng quan về PayFS [#tổng-quan-về-payfs] PayFS được thiết kế để giải quyết những thách thức trong việc tích hợp thanh toán ngân hàng: * **Tự động hóa**: từ theo dõi giao dịch đến gửi webhook về hệ thống của bạn * **Đa ngân hàng**: Open Banking với MBBank, ACB và OCB; NAPAS với tất cả ngân hàng tại Việt Nam * **API đơn giản**: REST API kèm tài liệu và ví dụ mã nguồn * **Bảo mật**: chữ ký HMAC-SHA256 cho webhook, API Token phân quyền theo Workspace ## Tính năng chính [#tính-năng-chính] ### Tích hợp đa ngân hàng [#tích-hợp-đa-ngân-hàng] * **OpenBanking**: MBBank (`MB`), ACB (`ACB`), OCB (`OCB`) * **NAPAS**: tất cả ngân hàng tại Việt Nam * Một API dùng chung cho mọi ngân hàng * Không cần ký hợp đồng riêng với từng ngân hàng ### Client Portal [#client-portal] * Theo dõi giao dịch theo thời gian thực * Báo cáo và thống kê * Quản lý nhiều Workspace cho nhiều môi trường ### Webhook và thông báo [#webhook-và-thông-báo] * Nhận thông báo ngay khi có giao dịch * Gửi tới endpoint của bạn, hoặc tới Telegram * Ký HMAC-SHA256 để bạn xác minh nguồn gốc ### Đang phát triển [#đang-phát-triển] Các công cụ sau **chưa phát hành**: SDK cho PHP, Python và Node.js; plugin WordPress; gói Laravel; thông báo qua Zalo Official Account. Hiện tại bạn tích hợp trực tiếp qua REST API và webhook. Xem [Webhook](/vi/developers/webhooks) để có ví dụ bằng Node.js và PHP. ## Ai nên sử dụng PayFS? [#ai-nên-sử-dụng-payfs] ### Thương mại điện tử và kinh doanh trực tuyến [#thương-mại-điện-tử-và-kinh-doanh-trực-tuyến] * Cửa hàng online cần theo dõi thanh toán tự động * Nền tảng thương mại điện tử * Dịch vụ thuê bao và thanh toán định kỳ ### Fintech và cổng thanh toán [#fintech-và-cổng-thanh-toán] * Công ty fintech cần tích hợp với ngân hàng * Nhà cung cấp cổng thanh toán * Ví điện tử và thanh toán di động ### Doanh nghiệp lớn [#doanh-nghiệp-lớn] * Doanh nghiệp lớn với nhiều giao dịch * Hệ thống ERP/CRM cần tích hợp thanh toán * Quản lý tài chính tự động ## Bắt đầu với PayFS [#bắt-đầu-với-payfs] 1. **Đăng ký tài khoản** tại [payfs.vn](https://payfs.vn) 2. **Tạo Workspace** rồi kết nối tài khoản ngân hàng 3. **Thiết lập webhook** để nhận thông báo giao dịch 4. **Tích hợp API** vào ứng dụng của bạn ## Thông tin công ty [#thông-tin-công-ty] **Công ty cổ phần Pay5S** * MST: 0318747756 * Địa chỉ: 85 Đường 9, Vạn Phúc City, Hiệp Bình, TP HCM * Email liên hệ đối tác: [info@payfs.vn](mailto:info@payfs.vn) * Email hỗ trợ kỹ thuật: [support@payfs.vn](mailto:support@payfs.vn) * Hotline/Zalo: 08228 85558 ## Hỗ trợ và cộng đồng [#hỗ-trợ-và-cộng-đồng] * **Tài liệu**: Hướng dẫn chi tiết và ví dụ mã nguồn * **Telegram**: [PayFS Community](https://t.me/+CHaEUcOhygAyNDY1) * **Discord**: [PayFS Developers](https://discord.gg/qYGfhpPW) * **Hỗ trợ qua email**: [support@payfs.vn](mailto:support@payfs.vn) * **Hotline**: 08228 85558 (Zalo, WhatsApp) *** # Tài liệu PayFS (/vi) PayFS thông báo cho bạn ngay khi tài khoản ngân hàng có giao dịch mới thông qua một API duy nhất. Bạn không cần tích hợp riêng với từng ngân hàng. ## Bạn là ai [#bạn-là-ai] ## Ngân hàng được hỗ trợ [#ngân-hàng-được-hỗ-trợ] | Cách kết nối | Ngân hàng | | ------------ | --------------------------------------- | | OpenBanking | MBBank (`MB`), ACB (`ACB`), OCB (`OCB`) | | NAPAS | Tất cả ngân hàng tại Việt Nam | Xem [cách chọn hình thức kết nối](/vi/bank-accounts/organization). ## Bắt đầu [#bắt-đầu] 1. [Đăng ký tài khoản](/vi/getting-started/registration) 2. [Tạo Workspace](/vi/workspace/create) và kết nối ngân hàng 3. [Thiết lập webhook](/vi/developers/quickstart) ## Hỗ trợ [#hỗ-trợ] * **Kỹ thuật và thanh toán:** [support@payfs.vn](mailto:support@payfs.vn) * **Hợp tác kinh doanh:** [info@payfs.vn](mailto:info@payfs.vn) * **Hotline và Zalo:** 08228 85558 * **Cộng đồng:** [Telegram](https://t.me/+CHaEUcOhygAyNDY1) · [Discord](https://discord.gg/qYGfhpPW) # Tích hợp Telegram Bot (/vi/integrations/telegram) PayFS có thể gửi thông báo giao dịch trực tiếp vào Telegram, bên cạnh webhook HTTP. ## Cách hoạt động [#cách-hoạt-động] Khi tạo webhook trong Client Portal, bạn chọn loại **Telegram** thay vì HTTP. PayFS sẽ gửi tin nhắn qua bot, thay vì gọi HTTP POST tới máy chủ của bạn. Bạn cần hai thông tin: | Thông tin | Lấy ở đâu | | --------- | ------------------------------------------------------------------ | | Bot token | Tạo bot mới với [@BotFather](https://t.me/BotFather) trên Telegram | | Chat ID | ID của nhóm hoặc kênh nhận thông báo | ## Các bước thiết lập [#các-bước-thiết-lập] 1. Nhắn tin cho [@BotFather](https://t.me/BotFather), gửi lệnh `/newbot`, đặt tên bot 2. Sao chép bot token mà BotFather trả về 3. Thêm bot vào nhóm hoặc kênh Telegram của bạn 4. Lấy chat ID của nhóm đó 5. Mở mục thông báo của Workspace trong Client Portal, rồi tạo webhook loại Telegram 6. Dán bot token và chat ID 7. Chọn sự kiện muốn nhận ## Sự kiện nhận được [#sự-kiện-nhận-được] Giống webhook HTTP: `transaction.credit`, `transaction.debit`, `order.success`, `order.failed`. Xem [Webhook](/vi/developers/webhooks) để biết ý nghĩa từng sự kiện. Callback của Liên kết thanh toán không đi qua Telegram. Webhook Telegram và webhook HTTP độc lập với nhau. Bạn tạo được cả hai cùng lúc cho một Workspace, để vừa xử lý tự động vừa có thông báo cho đội ngũ theo dõi. ## Hỗ trợ [#hỗ-trợ] Cộng đồng PayFS trên [Telegram](https://t.me/+CHaEUcOhygAyNDY1). # Tích hợp Zalo Official Account (/vi/integrations/zalo) Tích hợp Zalo Official Account **chưa khả dụng**. Tính năng này nằm trong kế hoạch phát triển, chưa có ngày phát hành. ## Hiện tại nhận thông báo bằng cách nào? [#hiện-tại-nhận-thông-báo-bằng-cách-nào] PayFS hỗ trợ hai kênh thông báo giao dịch: * **Webhook**: PayFS gửi HTTP POST tới endpoint của bạn. Xem [Webhook](/vi/developers/webhooks). * **Telegram**: gửi tin nhắn vào nhóm hoặc kênh Telegram. Xem [Telegram Bot](/vi/integrations/telegram). Nếu cần đưa thông báo vào Zalo ngay, bạn có thể nhận webhook trên hệ thống của mình rồi chuyển tiếp sang Zalo Official Account bằng API của Zalo. ## Liên hệ [#liên-hệ] Số hotline **08228 85558** cũng dùng được trên Zalo để hỗ trợ kỹ thuật. Đây là kênh liên hệ với đội ngũ PayFS, không phải kênh nhận thông báo giao dịch tự động. # Sử dụng trên thiết bị di động (/vi/mobile/user-guide) Ứng dụng di động PayFS **chưa phát hành**. Chưa có bản cho iOS hay Android. ## Hiện tại dùng gì [#hiện-tại-dùng-gì] Client Portal hoạt động trên trình duyệt di động. Bạn có thể xem giao dịch và kiểm tra trạng thái kết nối ngân hàng ngay trên điện thoại. Nếu bạn muốn nhận thông báo giao dịch trên điện thoại, cách nhanh nhất là dùng [thông báo qua Telegram](/vi/integrations/telegram). Telegram có ứng dụng cho cả iOS và Android, và bạn nhận được thông báo đẩy ngay khi có giao dịch. # Quy ước về gói dịch vụ (/vi/pricing/service-packages) PayFS tính phí theo gói thuê bao hàng tháng. Mỗi gói quy định hạn mức giao dịch, số Workspace bạn tạo được, và mức phí cho phần giao dịch vượt hạn mức. ## Bảng gói dịch vụ [#bảng-gói-dịch-vụ] | Gói | Giá mỗi tháng | Giao dịch mỗi tháng | Số Workspace | Phí vượt mỗi giao dịch | | ---- | ------------- | ------------------- | ------------ | ---------------------- | | Free | 0 đ | 30 | 1 | 650 đ | | P1 | 199.000 đ | 500 | 2 | 400 đ | | P2 | 699.000 đ | 2.000 | 5 | 350 đ | | P3 | 2.999.000 đ | 10.000 | 10 | 300 đ | | VIP1 | 5.000.000 đ | 20.000 | 100 | 250 đ | Gói Free dành để dùng thử. Với 30 giao dịch mỗi tháng, nó đủ để chạy thử tích hợp chứ chưa đủ cho hệ thống thật. ### Khi vượt hạn mức [#khi-vượt-hạn-mức] PayFS không khóa Workspace khi bạn dùng hết hạn mức. Phần giao dịch vượt được tính theo mức phí vượt của gói bạn đang dùng. Gói càng cao thì phí vượt càng thấp. Nếu tháng nào bạn cũng vượt, nâng gói thường rẻ hơn là trả phí vượt. ## Hai hình thức kết nối ngân hàng [#hai-hình-thức-kết-nối-ngân-hàng] Gói dịch vụ quyết định hạn mức. Hình thức kết nối quyết định ngân hàng nào dùng được. Hai thứ này độc lập với nhau. ### OpenBanking [#openbanking] Kết nối trực tiếp với API của ngân hàng. Hiện hỗ trợ ba ngân hàng: * MBBank (`MB`) * ACB (`ACB`) * OCB (`OCB`) Phù hợp khi khách hàng của bạn tập trung ở các ngân hàng này và bạn cần thông tin giao dịch chi tiết. ### NAPAS [#napas] Kết nối qua hệ thống chuyển mạch quốc gia, hỗ trợ tất cả ngân hàng tại Việt Nam. Phù hợp khi khách hàng của bạn dùng nhiều ngân hàng khác nhau và bạn cần phạm vi phủ rộng. Xem [Cơ chế tổ chức tài khoản ngân hàng](/vi/bank-accounts/organization) để so sánh chi tiết hơn. ## Tính năng có ở mọi gói [#tính-năng-có-ở-mọi-gói] Không có tính năng nào bị khóa theo gói. Gói chỉ thay đổi hạn mức. * REST API và webhook * Xác minh chữ ký HMAC-SHA256 cho webhook * API Token phân quyền theo từng Workspace * Thông báo qua Telegram * Theo dõi giao dịch và báo cáo trên Client Portal ## Nâng cấp gói [#nâng-cấp-gói] Xem [Hướng dẫn nâng cấp gói dịch vụ](/vi/pricing/upgrade-guide). ## Cần tư vấn [#cần-tư-vấn] **Hotline và Zalo**: 08228 85558 **Email**: [info@payfs.vn](mailto:info@payfs.vn) **Cộng đồng**: [Telegram](https://t.me/+CHaEUcOhygAyNDY1) · [Discord](https://discord.gg/qYGfhpPW) # Hướng dẫn nâng cấp gói dịch vụ (/vi/pricing/upgrade-guide) Nâng cấp khi bạn chạm một trong hai giới hạn: số giao dịch mỗi tháng, hoặc số Workspace. ## Khi nào nên nâng cấp [#khi-nào-nên-nâng-cấp] Gói càng cao thì phí vượt hạn mức càng thấp. Nếu tháng nào bạn cũng vượt, nâng gói thường rẻ hơn là trả phí vượt. | Gói | Giá mỗi tháng | Giao dịch | Workspace | Phí vượt | | ---- | ------------- | --------- | --------- | -------- | | Free | 0 đ | 30 | 1 | 650 đ | | P1 | 199.000 đ | 500 | 2 | 400 đ | | P2 | 699.000 đ | 2.000 | 5 | 350 đ | | P3 | 2.999.000 đ | 10.000 | 10 | 300 đ | | VIP1 | 5.000.000 đ | 20.000 | 100 | 250 đ | Ví dụ: nếu bạn ở gói P1 và dùng 800 giao dịch một tháng, phần vượt là 300 giao dịch, tính 400 đ mỗi giao dịch, tức 120.000 đ. Cộng với 199.000 đ tiền gói là 319.000 đ. Gói P2 giá 699.000 đ cho 2.000 giao dịch. Ở mức dùng này thì P1 vẫn rẻ hơn. Hãy tính theo mức dùng thật của bạn trước khi đổi gói. ## Các bước [#các-bước] 1. Đăng nhập Client Portal 2. Vào mục gói dịch vụ trong phần tài khoản 3. Chọn gói mới 4. Thanh toán 5. Gói mới có hiệu lực sau khi thanh toán được ghi nhận Bạn nhận được email xác nhận khi việc nâng cấp hoàn tất. ## Cần tư vấn [#cần-tư-vấn] **Hotline và Zalo**: 08228 85558 **Email**: [info@payfs.vn](mailto:info@payfs.vn) # Workspace là gì (/vi/workspace/concept) Workspace là một không gian làm việc độc lập. Mỗi Workspace có tài khoản ngân hàng riêng, webhook, giao dịch và thành viên riêng. Dữ liệu không dùng chung giữa các Workspace. Bạn cần ít nhất một Workspace trước khi có thể nhận giao dịch. ## Khi nào cần nhiều Workspace [#khi-nào-cần-nhiều-workspace] **Tách môi trường.** Dùng một Workspace cho môi trường phát triển và một Workspace cho môi trường chạy thật. Tránh dùng nhầm cấu hình thật khi đang test. **Tách dự án.** Dùng một Workspace cho mỗi website hoặc ứng dụng để báo cáo và giao dịch không lẫn vào nhau. Nếu bạn chỉ có một cửa hàng và một tài khoản ngân hàng, một Workspace là đủ. ## Đặt tên [#đặt-tên] Đưa môi trường vào tên để khỏi nhầm: * `shop_online_prod` * `mobile_app_staging` ## Giới hạn theo gói [#giới-hạn-theo-gói] | Gói | Giao dịch mỗi tháng | Số Workspace | | ---- | ------------------- | ------------ | | Free | 30 | 1 | | P1 | 500 | 2 | | P2 | 2.000 | 5 | | P3 | 10.000 | 10 | | VIP1 | 20.000 | 100 | Khi vượt hạn mức giao dịch, Workspace không bị khóa; phần vượt được tính theo phí vượt của gói. Xem [gói dịch vụ](/vi/pricing/service-packages). ## Vai trò thành viên [#vai-trò-thành-viên] | Vai trò | Làm được gì | | ------- | -------------------------------------------------------------------- | | Owner | Toàn quyền. Là người tạo Workspace và không thể chuyển quyền sở hữu. | | Admin | Đổi cấu hình, kết nối ngân hàng, quản lý thành viên | | Member | Xem và làm việc với giao dịch | | Viewer | Chỉ xem | Xem [chia sẻ Workspace](/vi/workspace/share). ## Những thứ không đổi được [#những-thứ-không-đổi-được] Loại chủ thể và chế độ ngân hàng được cố định ngay từ lúc tạo. Muốn đổi thì phải tạo Workspace mới. Chủ sở hữu cũng không chuyển sang người khác được. Vì vậy hãy cân nhắc kỹ ở [bước tạo Workspace](/vi/workspace/create). # Tạo Workspace (/vi/workspace/create) Workspace là nơi bạn kết nối tài khoản ngân hàng và cấu hình webhook. Bạn cần ít nhất một Workspace trước khi nhận giao dịch. ## Bước 1: Chọn loại chủ thể [#bước-1-chọn-loại-chủ-thể] Trên Client Portal, chọn **Tạo Workspace**. Danh sách Workspace trên Client Portal Chọn loại chủ thể: Cá nhân, Doanh nghiệp hoặc Hộ kinh doanh. Chọn loại chủ thể khi tạo Workspace Loại chủ thể quyết định **Chế độ ngân hàng** và chế độ này **không thể thay đổi** sau khi tạo. Cá nhân và Hộ kinh doanh dùng Open Banking. Doanh nghiệp dùng Open Banking hoặc NAPAS. Nếu chọn sai, bạn phải tạo Workspace mới. ## Bước 2: Đặt tên và chọn chế độ ngân hàng [#bước-2-đặt-tên-và-chọn-chế-độ-ngân-hàng] Đặt tên Workspace và chọn chế độ ngân hàng Nếu bạn dùng nhiều môi trường, hãy đặt tên kèm theo môi trường: `shop_online_prod`, `mobile_app_staging`. ## Tiếp theo [#tiếp-theo] 1. [Kết nối tài khoản ngân hàng](/vi/bank-accounts/organization) 2. [Thiết lập webhook](/vi/developers/webhooks) 3. [Mời thành viên](/vi/workspace/share) nếu làm việc theo nhóm ## Số Workspace tạo được [#số-workspace-tạo-được] Số Workspace được tạo dao động từ 1 ở gói Free đến 100 ở gói VIP1. Xem [gói dịch vụ](/vi/pricing/service-packages). # Chia sẻ Workspace (/vi/workspace/share) Bạn có thể mời người khác vào Workspace để cùng theo dõi giao dịch và quản lý cấu hình. ## Vai trò [#vai-trò] | Vai trò | Quyền | | ------- | --------------------------------------------------------------------------- | | Owner | Toàn quyền. Là người tạo Workspace và không thể chuyển quyền sở hữu. | | Admin | Có thể thay đổi cấu hình Workspace, kết nối ngân hàng và quản lý thành viên | | Member | Xem dữ liệu và làm việc với giao dịch | | Viewer | Chỉ xem | ## Mời thành viên [#mời-thành-viên] 1. Mở Workspace, vào mục **Thành viên** 2. Chọn **Mời thành viên** 3. Nhập email người được mời 4. Chọn vai trò 5. Gửi lời mời Người được mời sẽ nhận email và cần chấp nhận lời mời. Bạn có thể hủy lời mời trước khi lời mời đó được chấp nhận. ## Thay đổi và gỡ thành viên [#thay-đổi-và-gỡ-thành-viên] Owner và Admin có thể thay đổi vai trò của thành viên khác hoặc gỡ thành viên khỏi Workspace. Thành viên cũng có thể tự rời Workspace. Quyền của API Token không bao giờ vượt quá quyền hiện tại của người tạo token. Khi vai trò của một người bị hạ, token do người đó tạo cũng bị hạ theo. # Lưu trữ Workspace (/vi/workspace/storage) ## Dữ liệu được lưu [#dữ-liệu-được-lưu] Mỗi Workspace lưu giao dịch, lịch sử gửi webhook, danh sách các tài khoản ngân hàng đã kết nối và danh sách thành viên. Lịch sử gửi webhook ghi lại từng lần gửi, gồm cả nội dung request, mã trạng thái mà endpoint của bạn trả về, và số lần đã thử. Đây là nơi cần xem đầu tiên khi bạn nghi ngờ bị bỏ lỡ một giao dịch. ## Xuất dữ liệu [#xuất-dữ-liệu] Bạn có thể xuất danh sách giao dịch từ Client Portal hoặc lấy dữ liệu qua API. Xem [API Token](/vi/developers/api-token) để biết cách gọi. ## Tạm ngưng Workspace [#tạm-ngưng-workspace] Khi tạm ngưng, Workspace ngừng xử lý giao dịch mới. Dữ liệu cũ vẫn được giữ nguyên và có thể xem lại. Xóa Workspace là thao tác không thể hoàn tác. Hãy xuất dữ liệu bạn cần giữ trước khi xóa. # Chuyển đổi Workspace (/vi/workspace/switch) Nếu bạn có nhiều Workspace, Client Portal luôn hiển thị dữ liệu của đúng một Workspace tại một thời điểm. ## Cách chuyển [#cách-chuyển] 1. Mở danh sách Workspace trong Client Portal 2. Chọn Workspace bạn muốn xem Sau khi chuyển đổi, giao dịch, tài khoản ngân hàng và webhook được hiển thị đều thuộc Workspace đang chọn. Dữ liệu không dùng chung giữa các Workspace. Giao dịch của Workspace này không xuất hiện trong báo cáo của Workspace kia. ## Với API [#với-api] API không có khái niệm "Workspace đang chọn". Mỗi yêu cầu API đều chỉ rõ Workspace trong đường dẫn, và API Token phải có quyền trên đúng Workspace đó. Xem [API Token](/vi/developers/api-token). # Cập nhật Workspace (/vi/workspace/update) Chỉ thành viên có vai trò **Owner** hoặc **Admin** mới có thể thay đổi cấu hình Workspace. ## Thông tin sửa được [#thông-tin-sửa-được] * Tên Workspace * Mô tả * Cấu hình webhook và thông báo * Vai trò của từng thành viên ## Thông tin không sửa được [#thông-tin-không-sửa-được] **Loại chủ thể** và **Chế độ ngân hàng** cố định từ lúc tạo Workspace. Nếu cần đổi, bạn phải tạo Workspace mới. Quyền sở hữu Workspace cũng không thể chuyển cho người khác. ## Kích hoạt và tạm ngưng [#kích-hoạt-và-tạm-ngưng] Bạn có thể tạm ngưng rồi kích hoạt lại Workspace. Khi tạm ngưng, Workspace ngừng xử lý giao dịch mới nhưng vẫn giữ dữ liệu cũ. ## Các bước [#các-bước] 1. Mở Workspace trong Client Portal 2. Vào **Cài đặt** 3. Chỉnh sửa thông tin cần thay đổi 4. Lưu lại