tgpay cryptoAPI
crypto-payapiwebhookssignature

Referensi API: webhook

Baca 3 menitDiperbarui 11 Agu 2026

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_typeTerjadi saatPayload
invoice_paidfaktur dibayar — selalu dikirimobjek faktur
invoice_expiredfaktur lewat tenggatnya tanpa dibayarobjek faktur
check_activatedsalah satu cekmu diklaimobjek cek
refund_completedpengembalian dana dijalankanobjek faktur dengan field refunded_*
subscription_activatedpengguna menyetujui paketobjek langganan
subscription_chargedsatu periode ditagih — charge.kind menyebut yang mana: initial, renewal, atau resubscribeobjek langganan + charge: {period_no, kind, asset, amount, fee, paid_at}
subscription_cancelledlangganan dibatalkan salah satu pihakobjek langganan
subscription_expiredmasa tenggang habis tanpa dibayarobjek 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 TgPayCrypto-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["TgPayCrypto-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_id sebelum 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.