Proszę czekać, ładujemy treść.
Jak odbierać powiadomienia z KSeFCore w czasie rzeczywistym przez webhooki
Webhooki pozwalają Twojej aplikacji odbierać powiadomienia o zdarzeniach w KSeFCore w czasie rzeczywistym. Zamiast regularnie odpytywać API o status, możesz po prostu nasłuchiwać na webhooki.
Twój endpoint musi:
javascript
// Przykład endpointu w Express.js
app.post('/webhooks/ksefcore', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-webhook-signature'];
const timestamp = req.headers['x-webhook-timestamp'];
const eventType = req.headers['x-event-type'];
const eventId = req.headers['x-event-id'];
// Weryfikacja podpisu
if (!verifySignature(req.body, signature, timestamp)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Przetwarzanie zdarzenia
const payload = JSON.parse(req.body.toString('utf8'));
const { type, data } = payload;
switch (type) {
case 'ksef.outgoing.sent':
handleOutgoingSent(data);
break;
case 'ksef.outgoing.accepted':
handleOutgoingAccepted(data);
break;
// ... inne zdarzenia
}
// Potwierdzenie odbioru
res.status(204).end();
});Zaloguj się do panelu KSeFCore i przejdź do:
Każdy webhook ma standardową strukturę:
json
{
"id": "<event_id>",
"type": "ksef.outgoing.sent",
"version": 1,
"created_at": "2026-01-07T12:00:00.000000+00:00",
"org_id": "<org_uuid>",
"client_id": "<client_uuid>",
"resource": { "type": "submission", "id": "<submission_public_id>" },
"correlation_id": "<string>",
"data": {
// Dane specyficzne dla zdarzenia
}
}id - Unikalny ID zdarzenia (event_id) — użyj do idempotencjitype - Typ zdarzenia (event type)version - Wersja envelope (zawsze 1)created_at - Czas utworzenia zdarzenia (ISO 8601)org_id - ID organizacji (jeśli znane)client_id - ID klientaresource - Kontekst biznesowy (np. submission/document)correlation_id - Id do korelacji w logach i idempotencjidata - Dane specyficzne dla zdarzeniaksef.outgoing.queued - Zgłoszenie przyjęte i zakolejkowaneksef.outgoing.sent - Request zarejestrowany w KSeF (mamy session_reference i invoice_reference); finalny wynik dopiero w accepted/rejectedksef.outgoing.accepted - UPO dostępne, zgłoszenie zaakceptowaneksef.outgoing.rejected - Odrzucenie przez KSeFksef.outgoing.failed - Finalna porażka po stronie KSeFCoreksef.incoming.synced - Dokumenty zapisane w bazieksef.incoming.failed - Błąd synchronizacjiKSeFCore ponawia wysyłkę tylko dla błędów uznanych za retryable:
408, 429, 5xxInne 4xx są traktowane jako błąd finalny.
| Próba | Opóźnienie | |-------|------------| | 1 | natychmiast | | 2 | 60 sekund | | 3 | 300 sekund | | 4 | 900 sekund | | 5 | 3600 sekund | | 6 | 7200 sekund |
Po przekroczeniu limitu prób webhook jest oznaczany jako failed i możesz zobaczyć błąd w panelu.
Każde zdarzenie ma unikalne ID (id). Użyj go do zapobiegania duplikatom:
javascript
// Sprawdź czy zdarzenie już przetworzono
const processedEventId = await db.get('processed_events', webhook.id);
if (processedEventId) {
return res.status(200).json({ received: true, duplicate: true });
}
// Przetwarzanie...
await processWebhook(webhook);
// Zapisz ID przetworzonego zdarzenia
await db.set('processed_events', webhook.id, true);
console.log('Processed webhook: ' + webhook.id);W panelu możesz włączyć tryb testowy dla webhooka:
Użyj narzędzi jak ngrok lub localtunnel do testowania lokalnego endpointu:
bash
# Uruchom ngrok
ngrok http 3000
# Otrzymasz publiczny URL
# https://abc123.ngrok.io -> http://localhost:3000
# Użyj tego URL w konfiguracji webhooka