Siirry sisältöön

Webhookit

Webhookit mahdollistavat reaaliaikaiset ilmoitukset Kirjapron tapahtumista ulkoisille järjestelmille.

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)
TapahtumaKuvaus
invoice.createdUusi lasku luotu
invoice.sentLasku lähetetty asiakkaalle
invoice.paidLasku merkitty maksetuksi
invoice.overdueLasku erääntynyt
TapahtumaKuvaus
payment.receivedMaksu vastaanotettu
payment.matchedMaksu kohdistettu laskulle
TapahtumaKuvaus
transaction.createdUusi kirjaus luotu
transaction.updatedKirjausta muokattu
TapahtumaKuvaus
customer.createdUusi asiakas lisätty
customer.updatedAsiakastietoja muokattu
POST /your-webhook-endpoint HTTP/1.1
Content-Type: application/json
X-Kirjapro-Signature: sha256=abc123...
X-Kirjapro-Event: invoice.created
X-Kirjapro-Delivery: uuid
{
"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"
}
}

Jokainen webhook sisältää X-Kirjapro-Signature -headerin. Vahvista allekirjoitus ennen datan käsittelyä.

const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return `sha256=${expected}` === signature;
}
// Express middleware
app.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');
});
import hmac
import 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', 200
  1. Siirry AsetuksetIntegraatiotWebhookit
  2. Klikkaa Lisää webhook
  3. Syötä:
    • URL: Endpointin osoite
    • Tapahtumat: Valitse mitä tapahtumia seurataan
    • Aktiivinen: Kyllä/Ei
  4. Klikkaa Tallenna
  5. Kopioi Webhook Secret turvalliseen paikkaan
Terminal window
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
}'

Jos webhook-kutsu epäonnistuu (ei 2xx-vastausta), Kirjapro yrittää uudelleen:

YritysViive
1Välittömästi
21 minuutti
35 minuuttia
430 minuuttia
52 tuntia

Viiden epäonnistuneen yrityksen jälkeen webhook merkitään epäaktiiviseksi.

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
});
// ❌ Huono
app.post('/webhook', async (req, res) => {
await processEvent(req.body); // Timeout-riski
res.status(200).send('OK');
});

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
});

Webhook-URL:n tulee aina käyttää HTTPS:ää.

  1. Siirry AsetuksetIntegraatiotWebhookit
  2. Valitse webhook
  3. Klikkaa Lähetä testipyyntö
  4. Tarkista lokista vastaus

Käytä tunnelointityökalua kuten:

Terminal window
ngrok http 3000
# Käytä ngrok-URL:ia webhook-osoitteena
  1. Tarkista että webhook on Aktiivinen
  2. Varmista että valitut tapahtumat ovat oikein
  3. Tarkista webhook-loki virheistä
  1. Varmista että käytät oikeaa Webhook Secret
  2. Tarkista että payload on raw body, ei parsed JSON
  3. Varmista encoding (UTF-8)