tgpay cryptoAPI
crypto-payapitransferspayouts

Tài liệu API: chuyển tiền và Lì xì

7 phút đọcCập nhật lần cuối: 9 thg 10, 2026

Các phương thức chi trả. Một lệnh chuyển đưa tiền từ số dư ứng dụng của bạn vào ví của một người dùng Telegram hoặc tạm giữ tiền cho đến khi người nhận mới mở bot. Một Lì xì là liên kết nhận tiền, với số tiền được tạm giữ trước trên số dư ứng dụng. Các quy ước chung (xác thực, cấu trúc phản hồi, số tiền, spend_id) nằm ở trang tài liệu Merchant API.

Cả ba phương thức đưa tiền ra đều tuân theo chế độ chi trả của ứng dụng: một ứng dụng mới chi trả được cho bất kỳ ai ngay từ đầu; nếu chủ sở hữu đã siết lại, chỉ những người nhận trong danh sách mới được chi trả (403 recipient_not_allowed), hoặc không ai cả (403 payouts_disabled). Chủ sở hữu đặt chế độ này trong Mini App; API không đổi được. Còn các khoản chi trả được phép dùng vào việc gì thì do điều khoản Merchant API quy định.

transfer

POST /pay/api/transfer — scope payouts, giới hạn 30 mỗi phút. Người nhận đã có trong ứng dụng sẽ nhận tiền ngay. Nếu username chưa có trong ứng dụng, lệnh chuyển có trạng thái pending: tiền được tạm giữ cho đến khi người nhận mở bot lần đầu bằng đúng username đó. Tiền chưa được nhận sẽ trả về số dư ứng dụng sau hạn 30 ngày (expires_at). Xác nhận trạng thái status: "returned" trước khi ghi nhận khoản hoàn vào sổ sách. Bạn cần tự gửi invite_url cho người nhận vì bot không thể nhắn cho người chưa từng mở bot. Trạng thái cuối cùng là completed hoặc returned; hãy bật webhook transfer_completed và transfer_returned, hoặc gọi getTransfers để theo dõi.

Chỉ truyền một trong hai tham số user_id hoặc username. Nếu bỏ cả hai hoặc truyền đồng thời cả hai, yêu cầu sẽ bị từ chối do tham số không hợp lệ.

Tham sốKiểuBắt buộcÝ nghĩa
user_idintegermột trong user_id / usernameID Telegram của người nhận; người nhận phải đã có trong ứng dụng
usernamestringmột trong user_id / usernametên người dùng của người nhận, có hoặc không có @; tên chưa có trong ứng dụng sẽ tạo khoản chi trả đang chờ
assetstringcómã tài sản
amountstringcóchuỗi thập phân dương; ngoài ra còn phải nằm trong mức tối thiểu và tối đa cho mỗi lệnh của nền tảng (ước lượng theo giá trị quy đổi ra USD tại tỷ giá hiện hành)
spend_idstringcókhóa idempotency, 1–64 ký tự, không trùng giữa các khoản chi
commentstringkhôngtối đa 1024 ký tự, hiện cho người nhận
disable_send_notificationbooleankhôngtrue tắt thông báo cho người nhận khi chi trả ngay; khi nhận một khoản chuyển đang chờ, người nhận vẫn được thông báo

Kết quả là đối tượng transfer: transfer_id, hash, user_id, recipient_username, asset, amount, amount_minor, spend_id, comment, status (pending / completed / returned), created_at, completed_at, expires_at, invite_url. user_id có thể là null khi đang chờ người nhận mới; completed_at là null cho đến khi lệnh chuyển hoàn tất.

Lỗi: 403 payouts_disabled / 403 recipient_not_allowed (do chế độ chi trả), 404 user_not_found (ID chưa có trong ứng dụng hoặc người nhận không khả dụng), 400 invalid_recipient (tên người dùng của người nhận sai định dạng), 400 amount_too_small / 400 amount_too_big (nằm ngoài khoảng cho phép của mỗi lệnh), 409 insufficient_funds, 400 unknown_asset, 400 invalid_amount, và cặp lỗi của spend_id: 409 idempotency_conflict / 409 idempotency_in_progress.

transferBatch

POST /pay/api/transferBatch — scope payouts, giới hạn 10 mỗi phút. Một phần mở rộng dành cho chi trả hàng loạt: tối đa 100 lệnh chuyển trong một lần gọi.

Một tham số: items — một mảng mà mỗi phần tử là trọn bộ tham số của transfer (user_id hoặc username, asset, amount, spend_id, kèm comment và disable_send_notification tùy chọn). Các spend_id phải khác nhau trong cùng một lô, nếu không cả lần gọi thất bại với 400 duplicate_spend_id trước khi bất cứ gì được thực thi. Cấu trúc phần tử không hợp lệ, chế độ chi trả hoặc hạn mức hằng ngày của ứng dụng cũng có thể khiến cả yêu cầu bị từ chối trước khi chi trả. Khi yêu cầu được chấp nhận, kết quả nằm trong result.items.

Các phần tử được xử lý độc lập, theo thứ tự — một phần tử thất bại không bao giờ làm hoàn tác các phần tử khác. Lần gọi vẫn trả về HTTP 200 với ok: true ngay cả khi có phần tử thất bại, nên hãy luôn kiểm tra từng phần tử:

  • thành công: {"ok": true, "spend_id": "…", "result": <transfer object>}
  • thất bại: {"ok": false, "spend_id": "…", "error": {"code": …, "name": "…"}} với đúng bộ tên lỗi của một transfer đơn lẻ.

Các phần tử trong lô dùng chung không gian idempotency với lệnh chuyển đơn lẻ: thử lại cả lô — hoặc gửi lại một phần tử dưới dạng một transfer đơn lẻ với cùng spend_id — sẽ trả lại kết quả đã lưu thay vì chi trả hai lần.

getTransfers

GET /pay/api/getTransfers — scope read. Bộ lọc: asset, transfer_ids (phân tách bằng dấu phẩy), spend_id (khớp chính xác — tra một khoản chi theo khóa của riêng bạn), status (pending / completed / returned), cùng offset / count. Trả về {"items": [transfer, …]}, mới nhất trước.

createCheck

POST /pay/api/createCheck — scope checks, giới hạn 60 mỗi phút. Mặc định, tạo Lì xì dùng một lần từ số dư ứng dụng. Ai có liên kết hoặc chỉ người được gán sẵn có thể nhận. Phần mở rộng recipients tạo danh sách người nhận cụ thể với số tiền riêng cho từng người. Tổng tiền được tạm giữ ngay khi tạo (available chuyển sang onhold trong getBalance). Tạo Lì xì chịu cùng giới hạn số tiền và hạn mức chi trả hằng ngày như lệnh chuyển.

Tham sốKiểuBắt buộcÝ nghĩa
assetstringcómã tài sản
amountstringtrừ khi đặt recipientschuỗi thập phân dương; nếu có recipients, tổng tiền được tính từ danh sách
pin_to_user_idintegerkhôngchỉ Telegram user id này được nhận
pin_to_usernamestringkhôngchỉ @username này được nhận (dấu @ là tùy chọn; bị bỏ qua khi đã đặt cả pin_to_user_id). Username phải thuộc về người dùng đã có trong ứng dụng
spend_idstringkhôngkhóa idempotency (phần mở rộng) — hãy dùng nó
recipientsarraykhôngphần mở rộng: 1–100 phần tử, mỗi phần tử có user_id hoặc username và amount là chuỗi thập phân dương. Không dùng cùng người nhận được gán sẵn
passwordstringkhôngphần mở rộng: mật khẩu bắt buộc khi nhận, tối đa 64 ký tự
expires_inintegerkhôngphần mở rộng: thời hạn tính bằng giây; bỏ trống hoặc 0 = không hết hạn

Kết quả là đối tượng check: check_id, hash, asset, amount, amount_minor, bot_check_url (liên kết t.me để nhận), status (active / activated), pin_to_user_id, created_at, activated_at, expires_at và recipients (null với Lì xì thông thường; nếu có danh sách, mỗi phần tử gồm user_id, username, amount, amount_minor, claimed_at). Mỗi lượt nhận gửi webhook check_activated nếu đã bật; lượt nhận theo danh sách còn có activated_slot. Hết hạn sẽ trả lại phần chưa nhận; Lì xì theo danh sách có thể gửi check_expired.

Phản hồi hiện tại trả status: "active" cho mọi Lì xì chưa được nhận hết, kể cả đã hết hạn. Hãy kiểm tra cả expires_at; riêng active không chứng minh liên kết vẫn nhận được tiền.

Lỗi: 403 payouts_disabled / 403 recipient_not_allowed (do chế độ chi trả — ở chế độ allowlist, mọi người được gán sẵn hoặc nêu trong danh sách nhận đều phải được phép nhận), 400 unknown_asset, 400 invalid_amount, 404 user_not_found (username được gán không khớp với ai), 409 insufficient_funds, và cặp lỗi của spend_id.

deleteCheck

POST /pay/api/deleteCheck — scope checks. Một tham số: check_id. Hủy Lì xì đang hoạt động và trả phần chưa nhận về số dư ứng dụng của bạn; trả về true. Lỗi: 404 check_not_found, 409 check_not_active (đã nhận hết, hết hạn hoặc bị xóa).

getChecks

GET /pay/api/getChecks — scope read. Bộ lọc: asset, check_ids (phân tách bằng dấu phẩy), status (active / activated), cùng offset / count. Trả về {"items": [check, …]}, mới nhất trước; các Lì xì đã xóa không bao giờ được trả về.