Webhookit
Webhookit mahdollistavat reaaliaikaiset ilmoitukset Kirjapron tapahtumista ulkoisille järjestelmille.
Yleiskatsaus
Osio nimeltä “Yleiskatsaus”Webhook lähettää HTTP POST -pyynnön määrittämääsi URL-osoitteeseen kun tietty tapahtuma tapahtuu. Tämä mahdollistaa integraatiot esimerkiksi:
- CRM-järjestelmiin
- Varastonhallintaan
- Raportointityökaluihin
- Automaatioalustoihin (Zapier, Make, n8n)
Tuetut tapahtumat
Osio nimeltä “Tuetut tapahtumat”Laskut
Osio nimeltä “Laskut”| Tapahtuma | Kuvaus |
|---|---|
invoice.created | Uusi lasku luotu |
invoice.sent | Lasku lähetetty asiakkaalle |
invoice.paid | Lasku merkitty maksetuksi |
invoice.overdue | Lasku erääntynyt |
Maksut
Osio nimeltä “Maksut”| Tapahtuma | Kuvaus |
|---|---|
payment.received | Maksu vastaanotettu |
payment.matched | Maksu kohdistettu laskulle |
Kirjaukset
Osio nimeltä “Kirjaukset”| Tapahtuma | Kuvaus |
|---|---|
transaction.created | Uusi kirjaus luotu |
transaction.updated | Kirjausta muokattu |
Asiakkaat
Osio nimeltä “Asiakkaat”| Tapahtuma | Kuvaus |
|---|---|
customer.created | Uusi asiakas lisätty |
customer.updated | Asiakastietoja muokattu |
Webhookin rakenne
Osio nimeltä “Webhookin rakenne”Headers
Osio nimeltä “Headers”POST /your-webhook-endpoint HTTP/1.1Content-Type: application/jsonX-Kirjapro-Signature: sha256=abc123...X-Kirjapro-Event: invoice.createdX-Kirjapro-Delivery: uuidPayload
Osio nimeltä “Payload”{ "event": "invoice.created", "timestamp": "2025-01-15T14:30:00Z", "company_id": "uuid", "data": { "id": "uuid", "invoice_number": "2025-001", "customer_id": "uuid", "customer_name": "ABC Oy", "total_amount": 1240.00, "currency": "EUR", "due_date": "2025-01-29", "status": "draft" }}Allekirjoituksen vahvistus
Osio nimeltä “Allekirjoituksen vahvistus”Jokainen webhook sisältää X-Kirjapro-Signature -headerin. Vahvista allekirjoitus ennen datan käsittelyä.
Node.js esimerkki
Osio nimeltä “Node.js esimerkki”const crypto = require('crypto');
function verifySignature(payload, signature, secret) { const expected = crypto .createHmac('sha256', secret) .update(payload) .digest('hex');
return `sha256=${expected}` === signature;}
// Express middlewareapp.post('/webhook', express.raw({type: 'application/json'}), (req, res) => { const signature = req.headers['x-kirjapro-signature']; const isValid = verifySignature(req.body, signature, process.env.WEBHOOK_SECRET);
if (!isValid) { return res.status(401).send('Invalid signature'); }
const event = JSON.parse(req.body); // Käsittele tapahtuma
res.status(200).send('OK');});Python esimerkki
Osio nimeltä “Python esimerkki”import hmacimport hashlib
def verify_signature(payload: bytes, signature: str, secret: str) -> bool: expected = hmac.new( secret.encode(), payload, hashlib.sha256 ).hexdigest() return f"sha256={expected}" == signature
# Flask@app.route('/webhook', methods=['POST'])def webhook(): signature = request.headers.get('X-Kirjapro-Signature') if not verify_signature(request.data, signature, WEBHOOK_SECRET): return 'Invalid signature', 401
event = request.json # Käsittele tapahtuma
return 'OK', 200Webhookin luominen
Osio nimeltä “Webhookin luominen”Käyttöliittymässä
Osio nimeltä “Käyttöliittymässä”- Siirry Asetukset → Integraatiot → Webhookit
- Klikkaa Lisää webhook
- Syötä:
- URL: Endpointin osoite
- Tapahtumat: Valitse mitä tapahtumia seurataan
- Aktiivinen: Kyllä/Ei
- Klikkaa Tallenna
- Kopioi Webhook Secret turvalliseen paikkaan
API:n kautta
Osio nimeltä “API:n kautta”curl -X POST https://api.kirjapro.fi/webhooks \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhook", "events": ["invoice.created", "invoice.paid"], "active": true }'Uudelleenlähetys
Osio nimeltä “Uudelleenlähetys”Jos webhook-kutsu epäonnistuu (ei 2xx-vastausta), Kirjapro yrittää uudelleen:
| Yritys | Viive |
|---|---|
| 1 | Välittömästi |
| 2 | 1 minuutti |
| 3 | 5 minuuttia |
| 4 | 30 minuuttia |
| 5 | 2 tuntia |
Viiden epäonnistuneen yrityksen jälkeen webhook merkitään epäaktiiviseksi.
Parhaat käytännöt
Osio nimeltä “Parhaat käytännöt”Vastaa nopeasti
Osio nimeltä “Vastaa nopeasti”Palauta 200 OK heti kun pyyntö on vastaanotettu. Käsittele data asynkronisesti.
// ✅ Hyväapp.post('/webhook', (req, res) => { res.status(200).send('OK'); processEventAsync(req.body); // Käsittele taustalla});
// ❌ Huonoapp.post('/webhook', async (req, res) => { await processEvent(req.body); // Timeout-riski res.status(200).send('OK');});Käsittele duplikaatit
Osio nimeltä “Käsittele duplikaatit”Webhook voidaan lähettää useammin kuin kerran. Käytä X-Kirjapro-Delivery -headeria duplikaattien tunnistamiseen.
const processedDeliveries = new Set();
app.post('/webhook', (req, res) => { const deliveryId = req.headers['x-kirjapro-delivery'];
if (processedDeliveries.has(deliveryId)) { return res.status(200).send('Already processed'); }
processedDeliveries.add(deliveryId); // Käsittele tapahtuma});Käytä HTTPS:ää
Osio nimeltä “Käytä HTTPS:ää”Webhook-URL:n tulee aina käyttää HTTPS:ää.
Testaaminen
Osio nimeltä “Testaaminen”Testipyynnön lähettäminen
Osio nimeltä “Testipyynnön lähettäminen”- Siirry Asetukset → Integraatiot → Webhookit
- Valitse webhook
- Klikkaa Lähetä testipyyntö
- Tarkista lokista vastaus
Lokaalisti kehittäessä
Osio nimeltä “Lokaalisti kehittäessä”Käytä tunnelointityökalua kuten:
ngrok http 3000# Käytä ngrok-URL:ia webhook-osoitteenaVianetsintä
Osio nimeltä “Vianetsintä”Webhook ei käynnisty
Osio nimeltä “Webhook ei käynnisty”- Tarkista että webhook on Aktiivinen
- Varmista että valitut tapahtumat ovat oikein
- Tarkista webhook-loki virheistä
Allekirjoitus ei täsmää
Osio nimeltä “Allekirjoitus ei täsmää”- Varmista että käytät oikeaa Webhook Secret
- Tarkista että payload on raw body, ei parsed JSON
- Varmista encoding (UTF-8)
Seuraavaksi
Osio nimeltä “Seuraavaksi”- API Reference - Kaikki endpointit
- Autentikointi - JWT ja API-avaimet