Referensi API: webhook
Webhook mengirim event ke servermu begitu event itu terjadi. Isi Webhook URL aplikasimu di Lainnya → Merchant API; setelah itu platform mem-POST body JSON bertanda tangan untuk tiap event yang kamu ikuti.
Envelope
{
"update_id": 123,
"update_type": "invoice_paid",
"request_date": "2026-08-11T12:00:00Z",
"payload": { … }
}
update_id tetap sama di setiap pengiriman ulang event yang sama — pakai
itu sebagai kunci deduplikasi. request_date dicatat per percobaan
pengiriman. payload berisi objek lengkap sesuai tipe event-nya: objek
faktur untuk event faktur, objek cek, atau objek langganan (bentuknya ada
di halaman referensi masing-masing).
Tipe event
update_type | Terjadi saat | Payload |
|---|---|---|
invoice_paid | faktur dibayar — selalu dikirim | objek faktur |
invoice_expired | faktur lewat tenggatnya tanpa dibayar | objek faktur |
check_activated | salah satu cekmu diklaim | objek cek |
refund_completed | pengembalian dana dijalankan | objek faktur dengan field refunded_* |
subscription_activated | pengguna menyetujui paket | objek langganan |
subscription_charged | satu periode ditagih — charge.kind menyebut yang mana: initial, renewal, atau resubscribe | objek langganan + charge: {period_no, kind, asset, amount, fee, paid_at} |
subscription_cancelled | langganan dibatalkan salah satu pihak | objek langganan |
subscription_expired | masa tenggang habis tanpa dibayar | objek langganan |
Selain invoice_paid, semuanya harus diaktifkan dulu (ekstensi di luar
Crypto Bot — penerima yang ketat mengikuti bentuk Crypto Bot tidak akan
pernah bertemu update_type asing kecuali kamu memang memintanya).
Aktifkan per aplikasi di Event webhook tambahan pada layar Merchant
API — toggle-nya muncul begitu webhook URL diisi, dan namanya persis
identifier mentah di tabel di atas.
Memverifikasi tanda tangan
Tiap pengiriman membawa header TgCryptoPay-API-Signature
(Crypto-Pay-API-Signature adalah alias kompatibilitas dengan nilai yang
sama): HMAC-SHA256 dalam heksadesimal atas body permintaan mentah, dengan
kunci berupa digest SHA-256 dari token API utama aplikasimu. Skemanya
sama persis dengan Crypto Bot, jadi kode verifikasi yang sudah ada tetap
jalan tanpa diubah:
import hashlib, hmac
secret = hashlib.sha256(API_TOKEN.encode()).digest()
expected = hmac.new(secret, raw_body, hashlib.sha256).hexdigest()
ok = hmac.compare_digest(expected, headers["TgCryptoPay-API-Signature"])
Verifikasi atas byte mentah yang diterima — hasil parse yang diserialisasi ulang bisa berbeda byte demi byte dan membuat pemeriksaannya gagal. Hanya token utama yang menandatangani; token terbatas tidak pernah. Mengganti token utama langsung mengganti kunci tanda tangan webhook, jadi perbarui juga secret di servermu di saat yang sama.
Pengiriman dan percobaan ulang
- Pengiriman dianggap berhasil kalau servermu menjawab 2xx dalam 10 detik.
- Selain itu — status error, timeout, koneksi gagal — akan dicoba ulang dengan backoff eksponensial: percobaan pertama sekitar 10 detik kemudian, jedanya berlipat dua sampai 8 jam, maksimal 17 percobaan yang tersebar kira-kira 3 hari.
- Setelah percobaan terakhir, pengirimannya dibuang. Webhook URL-nya sendiri tidak pernah dimatikan otomatis — endpoint yang sering gagal tidak diam-diam membuat aplikasimu berhenti berlangganan.
- Karena percobaan ulang itu pasti terjadi, handler-mu harus idempoten:
saring duplikat berdasarkan
update_idsebelum bertindak.
⚠️ Verifikasi dulu, baru penuhi pesanannya
Siapa pun bisa mem-POST ke webhook URL-mu. Sebelum pemeriksaan tanda
tangannya lolos, anggap body-nya sebagai input yang tidak tepercaya: jangan
kirim pesanan, jangan tambahkan saldo pengguna, jangan tandai apa pun
sebagai lunas. Urutan yang aman: verifikasi tanda tangan → saring duplikat
berdasarkan update_id → baru bertindak.
Artikel ini membantu?
Terima kasih atas masukannya.