tgpay cryptoAPI
crypto-payapireferencetokens

Referensi Merchant API

Baca 8 menitDiperbarui 22 Okt 2026

Konvensi yang dipakai semua metode, plus metode katalog yang hanya membaca. Halaman per metode: faktur dan pengembalian dana, transfer dan cek kripto, langganan, webhook.

API mengikuti konvensi Crypto Bot untuk metode yang didokumentasikan di sini. Ganti base URL dan token, lalu uji metode yang dipakai integrasimu di testnet. Tambahan kami ditandai ekstensi di bawah.

Spesifikasi OpenAPI 3.1 yang bisa dibaca mesin juga tersedia: crypto-pay-openapi.yaml · crypto-pay-openapi.json. Masukkan saja ke generator kode, klien API, atau alat AI-mu, tetapi periksa juga halaman tiap metode: skema mungkin belum mencakup ekstensi terbaru.

Base URL dan autentikasi

Semua metode ada di https://app.tgpaycrypto.com/pay/api/<methodName>. Di testnet, base URL-nya https://testnet.tgpaycrypto.com/pay/api — aplikasi dan tokennya terpisah, dana uji cobanya tidak bernilai.

Autentikasi tiap permintaan dengan token di header TgPayCrypto-API-Token (TgCryptoPay-API-Token, nama lama sebelum 2026-09-07, dan Crypto-Pay-API-Token diterima sebagai alias kompatibilitas; kalau beberapa dikirim sekaligus, yang kanonik yang menang). Token yang hilang, tidak valid, atau sudah dicabut — termasuk token terbatas yang kedaluwarsa, token aplikasi yang dihapus, atau token milik pemilik yang diblokir — mengembalikan 401 unauthorized.

Tokennya berbentuk <app_id>:<secret> dan hanya ditampilkan sekali, saat dibuat atau diganti; server cuma menyimpan hash-nya. Lihat Mulai sebagai developer.

Token dan scope

Ada dua jenis kredensial, keduanya diautentikasi dengan cara yang sama:

  • Token utama — akses penuh ke semua metode, dan satu-satunya kunci yang menandatangani webhook.
  • Token terbatas (ekstensi) — maksimal 10 token yang belum dicabut per aplikasi, termasuk yang kedaluwarsa, dibuat di Lainnya → Merchant API: pilih aplikasinya, lalu buka Akses dan token. Buat token di bagian Token terbatas, masing-masing punya label dan sebagian scope saja. Mencabut satu token berlaku seketika dan tidak memengaruhi yang lain; mengganti token utama juga tidak memengaruhi token terbatas. Token juga bisa memiliki tenggat kedaluwarsa; setelah itu token tidak bisa dipakai untuk autentikasi.
ScopeMetode yang dibuka
(token valid apa pun)getMe, getCurrencies, getExchangeRates
readgetBalance, getStats, getInvoices, getChecks, getTransfers, getSubscriptionPlans, getSubscriptions
invoicescreateInvoice, deleteInvoice
refundsrefundInvoice
payoutstransfer, transferBatch
checkscreateCheck, deleteCheck
subscriptionscreateSubscriptionPlan, archiveSubscriptionPlan, cancelSubscription
webhooksupdateApp

Scope bersifat kumulatif dan berdiri sendiri — invoices tidak otomatis memberi read, jadi server yang cuma membuat faktur boleh memegang token yang tidak bisa membaca saldo atau riwayat pembayaran. Memanggil metode yang tidak dicakup tokennya mengembalikan 403 scope_required. getMe melaporkan scopes token yang sedang dipakai (null untuk token utama) dan token_name, jadi kamu selalu bisa memeriksa token apa yang sedang kamu pegang.

Mode pembayaran

Scope menentukan metode mana yang boleh dipanggil sebuah token; mode pembayaran aplikasi menentukan kepada siapa token mana pun miliknya — termasuk token utama — boleh mengirim dana. Aplikasi baru bisa membayar siapa pun sejak menit pertama; pemiliknya bisa mempersempitnya di Lainnya → Merchant API: buka aplikasinya, lalu pilih Pengaturan pembayaran → Pembayaran lewat API sebagai pengaman kalau token bocor, sama seperti batas harian. Melonggarkannya kembali butuh PIN atau biometrik; API hanya bisa membacanya (getMe → payout_mode).

payout_modeYang boleh dilakukan transfer, transferBatch, dan createCheck
anymembayar pengguna mana pun, menahan pembayaran untuk @username yang belum dikenal di escrow, membuat cek yang bisa diklaim siapa saja — ini nilai bawaannya, sekaligus perilaku Crypto Bot
allowlisthanya membayar pengguna Telegram yang diizinkan. Setiap penerima cek yang dikunci atau disebut dalam daftar penerima harus diizinkan. Penerima lain, @username yang belum dikenal, dan cek yang bisa diklaim siapa saja mengembalikan 403 recipient_not_allowed
offtidak ada — setiap panggilan pembayaran mengembalikan 403 payouts_disabled; faktur, langganan, pengembalian dana, dan webhook tetap jalan seperti biasa

Kalau ada pembayaran yang ditolak, pemiliknya diberi tahu di Telegram dan bisa mengubah modenya. Batas pembayaran harian tetap berlaku bersama mode ini. Apa saja yang boleh kamu bayar lewat API diatur di ketentuan Merchant API.

Permintaan dan respons

  • Metode baca memakai GET dengan parameter di query string. Metode yang memindahkan uang hanya POST — parameternya sebagai body JSON, form-urlencoded, atau query param (kalau bentrok, body yang menang); multipart/form-data ditolak.
  • Respons dari handler API berupa JSON dengan envelope yang sama: sukses {"ok": true, "result": …}, error {"ok": false, "error": {"code": <HTTP status>, "name": "<error_name>"}}. Pakai error.name untuk percabangan — itu string stabil yang bisa dibaca mesin.
  • Nilai query bertipe salah di metode GET (misalnya offset=abc) bisa ditolak sebelum handler API dijalankan. Periksa status HTTP; jangan menganggap semua respons error memakai envelope di atas. Kirim nilai query dengan tipe yang benar.

Jumlah

  • Jumlah kripto berupa string desimal dalam satuan aset ("10.5") — jangan pernah angka JSON. Respons juga membawa amount_minor (ekstensi): nilai satuan terkecil sebagai string bilangan bulat, karena bilangan besar dalam wei bisa melampaui batas ketepatan bilangan bulat pada Number di JavaScript.
  • Nilai decimals tiap aset datang dari getCurrencies — hitung jumlahnya dari situ, jangan ditulis sebagai konstanta di kode.
  • Jumlah fiat maksimal 2 angka di belakang koma.
  • Kurs berupa string fixed-point, bukan angka.

Paginasi

Metode daftar (getInvoices, getChecks, getTransfers, getSubscriptions) menerima offset (bawaan 0) dan count (bawaan 100, maksimal 1000; getSubscriptions maksimal 500) lalu mengembalikan {"items": […]}, diurutkan dari yang terbaru. Filter ID (invoice_ids, check_ids, transfer_ids) berupa daftar bilangan bulat yang dipisah koma. Semua timestamp berupa string ISO 8601.

Idempotensi: spend_id

Metode yang memindahkan uang menerima kunci spend_id yang kamu buat sendiri (1–64 karakter): wajib di transfer dan di tiap item transferBatch, opsional di createCheck dan refundInvoice (ekstensi — pakai saja). Mengulang dengan kunci dan parameter yang sama akan mengulang hasil aslinya, bukan memindahkan dana dua kali, jadi permintaan yang kena timeout selalu aman diulang. Kunci yang sama dengan parameter berbeda mengembalikan 409 idempotency_conflict; percobaan ulang sementara yang asli masih berjalan mengembalikan 409 idempotency_in_progress.

Batas frekuensi

Per aplikasi, dihitung gabungan untuk semua tokennya; kalau terlampaui akan mengembalikan 429 rate_limited:

MetodeBatas
createInvoice, createCheck60 per menit
refundInvoice30 per menit
transfer30 per menit
transferBatch10 per menit
updateApp10 per menit
createSubscriptionPlan20 per menit

Batas permintaan tambahan mungkin berlaku. Saat menerima 429 rate_limited, tambah jeda sebelum mencoba lagi. Saat platform sedang pemeliharaan, metode tulis mengembalikan 503 maintenance sementara metode baca tetap jalan.

Metode katalog dan akun

getMe

GET /pay/api/getMe — tanpa parameter. Mengembalikan identitas aplikasinya: app_id, name, payment_processing_bot_username, webhook_url, webhook_events (tipe webhook tambahan yang diaktifkan aplikasinya), field introspeksi token scopes / token_name yang dijelaskan di atas, dan payout_mode (off / allowlist / any), daily_payout_max_usd_cents (0 = pemilik tidak menetapkan batas), dan daily_payout_spent_usd_cents (pengeluaran selama 24 jam terakhir).

updateApp

POST /pay/api/updateApp — scope webhooks. Parameter opsional: name (1–64 karakter), webhook_url (URL HTTPS publik; string kosong menghapusnya), dan webhook_events (array atau daftar nama event tambahan yang didukung, dipisah koma). Daftar event kosong menyisakan invoice_paid saja. Mengembalikan field aplikasi yang sama seperti getMe.

getBalance

GET /pay/api/getBalance — tanpa parameter. Mengembalikan array berisi satu baris per aset yang didukung, termasuk yang saldonya kosong: currency_code, available (saldo yang bisa dipakai), onhold (dana cek yang belum diklaim dan pembayaran @username yang menunggu), dan amount_minor.

getCurrencies

GET /pay/api/getCurrencies — tanpa parameter. Daftar resmi apa saja yang didukung API: baris kripto (is_blockchain: true) dan mata uang fiat yang bisa dipakai untuk memberi harga faktur (is_fiat: true). Tiap baris membawa code, name, decimals, dan flag is_stablecoin.

getExchangeRates

GET /pay/api/getExchangeRates — tanpa parameter. Kurs kripto ke fiat: source, target, rate (string fixed-point), dan is_valid. Anggap kurs ini sebagai perkiraan. is_valid: true tidak menjamin kurs masih berlaku saat ini. Jika kurs tidak bisa diperoleh, hasil bisa berupa array kosong. Gunakan jumlah dan kurs yang tercatat di faktur untuk mencocokkan pembayaran yang sudah terjadi.

getStats

GET /pay/api/getStats — start_at / end_at opsional (ISO 8601; rentang bawaannya 24 jam terakhir). Mengembalikan volume (nilai USD faktur yang dibayar dalam rentang itu, diperkirakan dengan kurs saat ini; aset tanpa harga dihitung nol), conversion (dibayar/dibuat, dalam persen), unique_users_count, created_invoice_count, paid_invoice_count, dan batas rentang yang benar-benar dipakai. Tanggal yang tidak bisa diurai mengembalikan 400 invalid_date.

Error yang bisa muncul di semua metode

HTTPerror.nameKapan
401unauthorizedtoken hilang, tidak valid, atau sudah dicabut
403scope_requiredtoken tidak punya scope untuk metode itu
403payouts_disabledmode pembayaran aplikasi off (hanya metode pembayaran)
403recipient_not_allowedpenerima tidak ada di daftar penerima aplikasi (hanya metode pembayaran)
400invalid_requestparameter tidak bisa diurai atau tidak valid (POST)
403daily_cap_exceededbatas pembayaran harian aplikasi akan terlampaui
403verification_requiredoperasi keluar pemilik dibatasi; berlaku untuk transfer, cek, dan pengembalian dana
503merchant_payouts_pausedpemotongan saldo aplikasi dihentikan sementara
429rate_limitedbatas frekuensi terlampaui
503maintenanceplatform sedang dalam pemeliharaan (metode tulis)
500internal_errorerror server yang tidak terduga

Error khusus tiap metode dicantumkan di halaman metodenya masing-masing.

Error tanpa format JSON

Respons error berupa teks biasa atau HTML saja belum menunjukkan lapisan mana yang mengembalikannya. Periksa status HTTP, isi respons, dan header respons.

Jika Cloudflare mengembalikan error code: 1010, klien ditolak berdasarkan signature browser sebelum permintaan mencapai API. Cakupan token bukan penyebab error Cloudflare ini. User-Agent yang tidak ada atau tidak standar dapat memicu perlindungan jaringan. Coba kirim header User-Agent yang mengidentifikasi klienmu, misalnya MyShop/1.0, lalu ulangi permintaan; cara ini tidak menjamin masalah teratasi. Jika error tetap muncul, kirim status HTTP, isi respons, dan header respons ke dukungan setelah menghapus token dan cookie.