tgpay cryptoAPI
crypto-payapitransferspayouts

Referensi API: transfer dan cek kripto

Baca 6 menitDiperbarui 9 Okt 2026

Metode untuk mengirim dana keluar. Transfer mengirim dana dari saldo aplikasimu ke dompet pengguna Telegram atau menahannya sampai penerima baru membuka bot; cek kripto adalah link klaim yang dananya kamu sediakan di muka. Konvensi umum (autentikasi, envelope, jumlah, spend_id) ada di halaman Referensi Merchant API.

Ketiga metode pengiriman dana keluar tunduk pada mode pembayaran aplikasi: aplikasi baru bisa membayar siapa pun sejak awal; kalau pemiliknya mempersempitnya, yang bisa dibayar hanya penerima dalam daftar (403 recipient_not_allowed) atau tidak ada sama sekali (403 payouts_disabled). Modenya diatur pemilik di Mini App; API tidak bisa mengubahnya. Apa saja yang boleh dibayar lewat API diatur di ketentuan Merchant API.

transfer

POST /pay/api/transfer — scope payouts, batas 30 per menit. Penerima yang sudah dikenal aplikasi langsung menerima pembayaran. Untuk username yang belum dikenal, transfer dibuat dengan status pending: dana ditahan dalam escrow sampai penerima membuka bot dengan username tersebut. Dana yang belum diklaim dikembalikan ke saldo aplikasi setelah masa berlaku 30 hari berakhir (expires_at). Pastikan statusnya sudah returned sebelum mencatat dana itu sebagai dana yang kembali dalam pembukuanmu. Kirim invite_url sendiri ke penerima — bot tidak bisa mengirim pesan ke orang yang belum pernah membukanya. Status akhirnya adalah completed atau returned. Aktifkan webhook transfer_completed dan transfer_returned untuk mengikuti perubahan status, atau periksa lewat getTransfers.

Isi tepat satu dari user_id atau username.

ParameterTipeWajibKeterangan
user_idintegertepat satu dari user_id / usernameid pengguna Telegram penerima; harus sudah jadi pengguna aplikasi
usernamestringtepat satu dari user_id / usernameusername penerima, dengan atau tanpa @; username yang belum dikenal menghasilkan pembayaran berstatus pending
assetstringyakode aset
amountstringyastring desimal positif; juga dibatasi minimum dan maksimum per transfer dari platform (perkiraan setara dolar AS pada kurs saat ini)
spend_idstringyakunci idempotensi, 1–64 karakter, unik per pembayaran
commentstringtidakmaksimal 1024 karakter, ditampilkan ke penerima
disable_send_notificationbooleantidaktrue menonaktifkan notifikasi penerima untuk pembayaran langsung; klaim transfer yang menunggu tetap mengirim notifikasi

Hasilnya adalah objek 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. Selama menunggu penerima baru, user_id bisa bernilai null; completed_at bernilai null sampai transfer selesai.

Error: 403 payouts_disabled / 403 recipient_not_allowed (mode pembayaran), 404 user_not_found (id tidak dikenal atau penerima tidak tersedia), 400 invalid_recipient (format username penerima tidak valid), 400 amount_too_small / 400 amount_too_big (di luar batas per transfer), 409 insufficient_funds, 400 unknown_asset, 400 invalid_amount, dan pasangan spend_id 409 idempotency_conflict / 409 idempotency_in_progress.

transferBatch

POST /pay/api/transferBatch — scope payouts, batas 10 per menit. Ekstensi untuk pembayaran massal: sampai 100 transfer dalam satu panggilan.

Satu parameter: items — array yang tiap itemnya berisi satu set parameter transfer lengkap (user_id atau username, asset, amount, spend_id, plus comment dan disable_send_notification yang opsional). Semua spend_id harus unik di dalam batch itu; kalau tidak, seluruh panggilan gagal dengan 400 duplicate_spend_id sebelum ada yang dieksekusi. Struktur item yang tidak valid, mode pembayaran aplikasi, atau batas harian juga bisa menolak seluruh permintaan sebelum pembayaran dimulai. Setelah diterima, hasilnya ada di result.items.

Tiap item diselesaikan sendiri-sendiri, sesuai urutan — satu item yang gagal tidak pernah membatalkan item lainnya. Panggilannya tetap mengembalikan HTTP 200 dengan ok: true meski ada item yang gagal, jadi selalu periksa tiap item satu per satu:

  • berhasil: {"ok": true, "spend_id": "…", "result": <transfer object>}
  • gagal: {"ok": false, "spend_id": "…", "error": {"code": …, "name": "…"}} dengan nama error yang sama seperti transfer tunggal.

Item batch berbagi ruang idempotensi dengan transfer tunggal: mengulang seluruh batch — atau mengirim ulang satu itemnya sebagai transfer tunggal dengan spend_id yang sama — akan mengulang hasil lama, bukan membayar dua kali.

getTransfers

GET /pay/api/getTransfers — scope read. Filter: asset, transfer_ids (dipisah koma), spend_id (cocok persis — cari satu pembayaran pakai kuncimu sendiri), status (pending / completed / returned), plus offset / count. Mengembalikan {"items": [transfer, …]}, diurutkan dari yang terbaru.

createCheck

POST /pay/api/createCheck — scope checks, batas 60 per menit. Secara bawaan, metode ini membuat cek sekali pakai dari saldo aplikasimu. Siapa pun yang memiliki link, atau hanya pengguna yang ditentukan, bisa mengklaimnya. Ekstensi recipients membuat daftar penerima dengan jumlah tersendiri untuk masing-masing orang. Totalnya ditahan saat pembuatan (available berpindah ke onhold di getBalance). Pembuatan cek mengikuti batas jumlah dan pembayaran harian yang sama dengan transfer.

ParameterTipeWajibKeterangan
assetstringyakode aset
amountstringkecuali recipients diisistring desimal positif; jika recipients diisi, total dihitung dari daftar
pin_to_user_idintegertidakhanya id pengguna Telegram ini yang boleh mengklaim
pin_to_usernamestringtidakhanya @username ini yang boleh mengklaim (tanda @ boleh tidak ditulis; diabaikan kalau pin_to_user_id juga diisi). Username-nya harus milik pengguna aplikasi yang sudah ada
spend_idstringtidakkunci idempotensi (ekstensi) — gunakan agar percobaan ulang tidak membuat cek ganda
recipientsarraytidakekstensi: 1–100 item, masing-masing berisi user_id atau username dan amount berupa string desimal positif. Tidak bisa digabung dengan pengguna yang dikunci
passwordstringtidakekstensi: kata sandi untuk klaim; maksimal 64 karakter
expires_inintegertidakekstensi: masa berlaku dalam detik; dikosongkan atau 0 = tanpa kedaluwarsa

Hasilnya adalah objek cek: check_id, hash, asset, amount, amount_minor, bot_check_url (link klaim t.me), status (active / activated), pin_to_user_id, created_at, activated_at, expires_at, dan recipients (null untuk cek biasa; jika ada daftar, tiap entri memiliki user_id, username, amount, amount_minor, claimed_at). Tiap klaim memicu webhook opsional check_activated; klaim penerima dalam daftar juga menyertakan activated_slot. Saat kedaluwarsa, sisa yang belum diklaim dikembalikan; cek dengan daftar penerima bisa mengirim check_expired.

Respons saat ini memetakan semua cek yang belum diklaim penuh ke status: "active", termasuk cek kedaluwarsa. Periksa juga expires_at; status active saja bukan bukti bahwa link masih bisa diklaim.

Error: 403 payouts_disabled / 403 recipient_not_allowed (mode pembayaran — dalam mode allowlist, setiap penerima yang dikunci atau disebut dalam daftar penerima harus diizinkan), 400 unknown_asset, 400 invalid_amount, 404 user_not_found (username yang dikunci tidak cocok dengan siapa pun), 409 insufficient_funds, dan pasangan spend_id.

deleteCheck

POST /pay/api/deleteCheck — scope checks. Satu parameter: check_id. Membatalkan cek aktif dan mengembalikan sisa yang belum diklaim ke saldo aplikasimu; mengembalikan true. Error: 404 check_not_found, 409 check_not_active (sudah diklaim penuh, kedaluwarsa, atau dihapus).

getChecks

GET /pay/api/getChecks — scope read. Filter: asset, check_ids (dipisah koma), status (active / activated), plus offset / count. Mengembalikan {"items": [check, …]}, diurutkan dari yang terbaru; cek yang sudah dihapus tidak pernah ikut dikembalikan.