Webhook, bir şey olduğunda (örneğin bir belgeyi onayladığınızda) Billfetch’in başka bir araca haber vermesini sağlar. Billfetch seçtiğiniz adrese kısa bir mesaj (JSON gövdeli bir HTTPS POST) gönderir. Zapier, Make ve n8n size bu adresi verir; böylece Billfetch’i kod yazmadan yüzlerce uygulamaya bağlayabilirsiniz.
Webhook ekleyin
- Zapier, Make veya n8n’de Webhooks by Zapier › Catch Hook, Custom webhook veya Webhook adlı bir tetikleyici oluşturun. Verdiği adresi kopyalayın.
- Billfetch’te Ayarlar’ı açın ve Entegrasyonlar altında Webhook’lar’ı seçin.
- Adresi yapıştırın. Adres
https://ile başlamalıdır. - Gönderilecek olaylar altında bir veya daha fazla olay işaretleyin. En az bir olay gerekir.
- Webhook ekle’yi seçin.
Billfetch imza sırrını webhook’u ekledikten hemen sonra yalnız bir kez gösterir. Kopyala’yı seçin ve güvenli bir yerde saklayın. Yalnız Zapier veya Make kullanıyorsanız sırrı atlayabilirsiniz. İstekleri kendi sunucunuz alıyorsa, her isteğin gerçekten Billfetch’ten geldiğini sırla doğrulayın (aşağıya bakın).
Test gönderin
Bir webhook’un yanındaki Test gönder’i seçin. Billfetch hemen bir webhook.test olayı gönderir ve sonucu aynı satırda gösterir:
- Teslim edildi · HTTP 200 · 312 ms: adres yanıt verdi, her şey çalışıyor. Zapier veya Make’te bu test isteğiyle sonraki adımları kurabilirsiniz.
- Adres HTTP 404 yanıtı verdi (veya başka bir kod): adres yanıt verdi ama isteği reddetti. Adresin tam olduğunu ve Zap’in veya senaryonun açık olduğunu kontrol edin.
- 10 saniye içinde yanıt gelmedi veya Adrese bağlanılamadı: adres yanlış ya da sunucu kapalı.
- Adres özel ya da yerel bir ağı gösteriyor: adres herkese açık değil. Billfetch özel ağlara hiçbir zaman istek göndermez.
Her webhook için 10 dakikada en çok 5 test gönderebilirsiniz. Test gövdesi seçtiğiniz olayları ve her birinin bir örneğini içerir; böylece gerçek bir olay gelmeden alanları eşleyebilirsiniz.
Olaylar
| Olay | Ne zaman gönderilir |
|---|---|
document.received | Yeni bir belge geldiğinde: yükleme, e-posta, Telegram, bir bağlantı veya içe aktarma. Kasanızda zaten olan bir belgenin kopyası bu olayı tetiklemez. |
document.approved | İncelemede bir belgeyi onayladığınızda. |
export.completed | Bir muhasebeci paketi üretildiğinde. |
missing.summary | Günde bir kez (07:00 UTC): bu ay hâlâ eksik olan kalemlerin sayısı. |
webhook.test | Yalnız Test gönder’i seçtiğinizde. |
Bir istek neye benzer
Her istek Content-Type: application/json ile bir POST’tur ve şu başlıkları taşır:
| Başlık | Anlamı |
|---|---|
Billfetch-Event | Olay türü, örneğin document.approved. |
Billfetch-Delivery | Bu teslimatın benzersiz kimliği. Teslimat yeniden denendiğinde değişmez; tekrarları bununla ayıklayabilirsiniz. |
Billfetch-Signature | t=<unix zamanı>,v1=<imza>. “İmzayı doğrulayın” bölümüne bakın. |
User-Agent | Billfetch-Webhooks/1.0 |
Gövde her zaman aynı zarftadır. id olay kimliğidir (bu olayı alan her webhook’ta aynıdır), data olaya göre değişir:
{
"id": "3f0b6a52-7a7e-4c1d-9f8e-0f3c2b1a9d10",
"type": "document.approved",
"occurredAt": "2026-10-17T09:30:00+00:00",
"tenantId": "8d2c4e1a-0b5f-4a7e-9c3d-2e1f0a9b8c7d",
"data": {
"documentId": "00000000-0000-0000-0000-000000000001",
"ledgerItemId": "00000000-0000-0000-0000-000000000002",
"entityId": "00000000-0000-0000-0000-000000000003",
"categoryId": "00000000-0000-0000-0000-000000000004",
"supplier": "Example Supplies Ltd",
"invoiceNumber": "INV-1042",
"issueDate": "2026-10-15",
"currency": "GBP",
"gross": 120.00,
"tax": 20.00
}
}
Diğer olayların data alanı:
// document.received
{ "documentId": "…", "filename": "invoice-1042.pdf", "source": "Upload", "receivedAt": "2026-10-17T09:30:00+00:00",
"mime": "application/pdf", "size": 48213, "entityId": null }
// export.completed
{ "exportJobId": "…", "entityId": "…", "from": "2026-09-01T00:00:00+00:00", "to": "2026-09-30T23:59:59+00:00",
"profile": "xero_csv", "mode": "full", "documents": 42, "contentHash": "9f86d0…" }
// missing.summary — Eksikler listesinin bölüm başına sayıları
{ "period": "2026-10", "sections": { "a": 3, "b": 1, "c": 0 } }
source şunlardan biridir: Upload, Imap (e-posta), Connector, CompaniesHouse, Telegram, Migration (Dext/AutoEntry içe aktarma), Accountant veya AccountantUnverified. Tutarlar sayıdır, tarihler ISO 8601 biçimindedir. Zamanla yeni alanlar eklenebilir; tanımadığınız alanları yok sayın.
İmzayı doğrulayın
İstekleri kendi sunucunuz alıyorsa bunu yapın. İsteğin Billfetch’ten geldiğini ve değiştirilmediğini kanıtlar.
Billfetch-Signaturebaşlığını okuyun vet(Unix zaman damgası) ilev1’e (imza) ayırın.t’yi, bir noktayı ve istek gövdesini ham hâliyle, geldiği gibi birleştirin; örneğin1760693400.{"id":…}. JSON’u önce ayrıştırıp yeniden yazmayın.- Bu metnin HMAC-SHA256 değerini, anahtar olarak imza sırrının tamamını (
whsec_öneki dahil) kullanarak hesaplayın ve küçük harfli onaltılık (hex) yazın. - Sonucu
v1ile sabit süreli bir karşılaştırmayla karşılaştırın. Farklıysa veyatsunucunuzun saatinden 5 dakikadan fazla uzaksa isteği reddedin.
Node.js:
import crypto from 'node:crypto'
// rawBody: gövde geldiği gibi (string ya da Buffer), yeniden yazılmış JSON değil.
export function verifyBillfetch(rawBody, header, secret, toleranceSeconds = 300) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')))
const t = Number(parts.t)
if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false
const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest()
const given = Buffer.from(parts.v1 ?? '', 'hex')
return given.length === expected.length && crypto.timingSafeEqual(given, expected)
}
Python:
import hashlib
import hmac
import time
def verify_billfetch(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t = int(parts.get("t", "0"))
if abs(time.time() - t) > tolerance:
return False
expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts.get("v1", ""))
Yeniden denemeler ve zaman aşımı
- Billfetch yanıt için en çok 10 saniye bekler. Her
2xxdurum kodu teslim edildi sayılır. Yönlendirmeler izlenmez. - Teslimat başarısız olursa Billfetch 1 dakika, 5 dakika, 30 dakika, 2 saat ve 12 saat sonra yeniden dener: yaklaşık 15 saatte toplam 6 deneme. Sonra teslimat Başarısız olarak işaretlenir.
- Test olayları bir kez gönderilir, yeniden denenmez.
- Teslimatlar birden fazla kez veya farklı sırayla gelebilir. Tekrarları
Billfetch-Deliveryveya olayid’si ile ayıklayın. - Webhook kartındaki Son teslimatlar son teslimatları durumları ve son HTTP koduyla gösterir.
Sırrı güvende tutun
- Sır sızdıysa veya kaybettiyseniz webhook’un yanındaki Yeni sır’ı seçip onaylayın. Eski sır hemen geçersiz olur; yenisini hemen aracınıza yapıştırın.
- Kaldır, bekleyen yeniden denemeler dahil o adrese tüm gönderimleri durdurur.
- Billfetch yalnız herkese açık
https://adreslerine gönderir. Düzhttp,localhostve özel ağ adresleri reddedilir.