Programiści

Webhook

Odbieraj zdarzenia podpisywania w czasie rzeczywistym za pośrednictwem protokołu HTTP z dostawami podpisanymi przez HMAC, automatycznymi ponownymi próbami i siatką bezpieczeństwa polegającą na odtwarzaniu z konsoli.

HMAC

SHA-256 podpisanie żądania

Per-webhook sekret, wysłany jako X-Endorsed-Signature

10s

Upłynął limit czasu dostawy

Zwróć 2xx w oknie lub próba zakończy się niepowodzeniem

5×

Ponawia próbę po pierwszej próbie

60s, 5m, 15m, 1h, następnie 6h

Replay

Z konsoli programisty

Sprawdź każdą próbę i powtórz poszczególne zdarzenia

Co możesz zrobić ze zdarzeniami webhook

Każde znaczące przejście w cyklu życia powoduje wyemitowanie wpisanego zdarzenia. Użyj ich, aby zaktualizować własne rekordy bez odpytywania.

✅

Wyzwalaj dalsze działania

Kiedy koperta jest w pełni podpisana, zaktualizuj swój CRM, zwolnij udostępniony zasób lub wyślij potwierdzenie w swoim własnym produkcie – wszystko bez odpytywania API.

🔄

Zsynchronizuj status dokumentu

Utrzymuj synchronizację bazy danych z cyklem życia podpisywania: wysłane, otwarte, podpisane, odrzucone, wygasłe, unieważnione. Jedno zdarzenie na przejście, nie jest wymagana pętla odpytywania.

📋

Rejestrowanie audytu i zgodności

Przesyłaj zdarzenia webhook do swojego własnego sklepu audytowego. Identyfikatory korelacji łączą każde zdarzenie z pierwotnym żądaniem API w celu zapewnienia pełnej identyfikowalności.

🔁

Odtwórz ponownie nieudane dostawy

Zdarzenia, które wyczerpują drabinkę ponownych prób, trafiają do kolejki niedostarczonych wiadomości, którą możesz sprawdzić w konsoli programisty i celowo odtworzyć.

Webhook odniesienie do zdarzenia

Zarejestruj webhook, wybierz zdarzenia, które chcesz, a EndorsedSign dostarczy ładunek JSON zawierający `event`, `tenantId`, `timestamp` i `data`. Nazwy zdarzeń odpowiadają ciągom, które wysyłasz w wywołaniu tworzenia webhook.

Typ zdarzeniaKiedy wystrzeliKluczowe pola „danych”.
document.createdPrzesyłasz dokument poprzez APIidentyfikator dokumentu, identyfikator klienta, identyfikator dokumentu zewnętrznego
document.sentLink do podpisu wysłany do pierwszego odbiorcyidentyfikator dokumentu, identyfikator klienta, kanał
document.viewedSigner otwiera link do podpisudocumentId, sygnatariuszE-mail, przeglądaneAt
document.signedIndywidualny podpisujący kończy swój krokdocumentId, podpisującyE-mail, podpisanyAt
document.completedWszystkie strony podpisałydocumentId, ukończonoAt, downloadUrl
document.declinedSygnatariusz wyraźnie odmawiaidentyfikator dokumentu, adres e-mail osoby podpisującej, powód
document.expiredDokument osiąga datę ważności bez podpisuidentyfikator dokumentu, wygasł o godz
signing.startedToken sesji podpisu został wykorzystanyidentyfikator dokumentu, identyfikator sesji, adres e-mail osoby podpisującej
signing.completedZakończenie sesji podpisywania (podpisanie lub odrzucenie)identyfikator dokumentu, identyfikator sesji, wynik
klient.utworzony / .zaktualizowany / .usuniętyMutujesz rekord klientaidentyfikator klienta, zewnętrzny identyfikator klienta
szablon.utworzono / zaktualizowanoMutujesz szablontemplateId, nazwa

Pełna lista znajduje się w backendie `WEBHOOK_EVENTS`. Dodaj lub zawęź subskrypcje na webhook — potok dostarczania rozdziela jedno wywołanie HTTP na zarejestrowany punkt końcowy.

Weryfikacja podpisów webhook (Node.js)

Każda dostawa zawiera nagłówek `X-Endorsed-Signature`: `t={unix_seconds},v1={hex}`. `v1` to HMAC-SHA256 z `{timestamp}.{rawBody}` przy użyciu sekretu zwróconego podczas tworzenia webhook. Odrzucaj znaczniki czasu poza ±5 minut. Podpis „X-Webhook-Podpis” może nadal pojawiać się w testowych dostawach portalu dla deweloperów jako przestarzały alias zawierający wyłącznie treść — sprawdź „X-Endorsed-Signature”. Warunki wstępne: Twój sekret webhook w env var, trasie ekspresowej, która przechowuje surową treść. Oczekiwany wynik: nierozpoznane lub zmienione ładunki są odrzucane z kodem 401 przed uruchomieniem jakiejkolwiek procedury obsługi.

typescript
import crypto from 'node:crypto';
import express from 'express';

const WEBHOOK_SECRET = process.env.ENDORSED_WEBHOOK_SECRET!;
const TOLERANCE_SECONDS = 5 * 60;

export function verifyWebhookSignature(
  rawBody: string,
  header: string | undefined,
  nowSeconds = Math.floor(Date.now() / 1000),
): boolean {
  if (!header) return false;
  let timestamp: number | null = null;
  let v1 = '';
  for (const part of header.split(',')) {
    const eq = part.indexOf('=');
    if (eq === -1) continue;
    const key = part.slice(0, eq).trim();
    const value = part.slice(eq + 1).trim();
    if (key === 't' && /^\d+$/.test(value)) timestamp = Number.parseInt(value, 10);
    if (key === 'v1' && /^[a-f0-9]{64}$/i.test(value)) v1 = value.toLowerCase();
  }
  if (timestamp === null || !v1) return false;
  if (Math.abs(nowSeconds - timestamp) > TOLERANCE_SECONDS) return false;
  const expected = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(timestamp + '.' + rawBody)
    .digest('hex');
  const a = Buffer.from(expected, 'hex');
  const b = Buffer.from(v1, 'hex');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

app.post(
  '/webhooks/endorsed',
  express.json({ verify: (req, _res, buf) => { (req as any).rawBody = buf.toString('utf8'); } }),
  (req, res) => {
    const sig = req.header('X-Endorsed-Signature');
    if (!verifyWebhookSignature((req as any).rawBody, sig)) {
      return res.status(401).send('Invalid signature');
    }
    res.sendStatus(200);
  },
);

Zwróć 2xx w ciągu 30 s lub dostawa zostanie oznaczona jako nieudana. Nieudane próby ponów próbę, korzystając z powyższej drabiny, i będzie można je odtworzyć w konsoli programisty.

Jak skonfigurować punkt końcowy webhook

  1. 1

    Utwórz punkt końcowy w swojej aplikacji

    Dodaj trasę, która akceptuje żądania POST i zwraca HTTP 200 w ciągu 10 sekund. Każda odpowiedź 2xx liczy się jako pomyślne dostarczenie.

  2. 2

    Zarejestruj punkt końcowy w ustawieniach dzierżawy

    Idź do Admin → Ustawienia → Webhooks. Wprowadź adres URL punktu końcowego i wybierz żądane typy zdarzeń. Dla każdego punktu końcowego generowany jest klucz tajny podpisu.

  3. 3

    Weryfikuj podpis przy każdym żądaniu

    Przeczytaj `X-Endorsed-Signature`. Oblicz ponownie HMAC-SHA256 na `{timestamp}.{rawBody}` i czas stały porównaj z `v1` (zobacz przykładowy kod powyżej). Odrzuć brakujący nagłówek, złą wartość szesnastkową, znacznik czasu przekraczający ± 5 minut lub niezgodność HMAC. `X-Webhook-Signature` jest przestarzałym aliasem w niektórych dostawach testowych — nie traktuj go jako aktywnego kontraktu.

  4. 4

    Zwróć szybko 2xx, proces asynchroniczny

    Potwierdź dostarczenie 200 w ciągu 10 sekund i umieść treść zdarzenia w kolejce do przetwarzania asynchronicznego. Konsola programisty pokazuje każdą próbę (nagłówki, treść, status, czas) i umożliwia odtworzenie dowolnego dostarczenia — nie ma potrzeby ponownego uruchamiania procesu podpisywania źródła tylko w celu przetestowania modułu obsługi.

Częste pytania

Rzeczywisty ładunek webhook — dokument ukończony

Kiedy wszystkie strony się podpiszą, EndorsedSign wysyła ten ładunek do zarejestrowanego punktu końcowego. Sprawdź podpis HMAC, umieść w kolejce i potwierdź za pomocą 200.

Historia zdarzeń dostawy z wpisami dotyczącymi cyklu życia dokumentu
Historia zdarzeń dostawy — podpisane zdarzenia cyklu życia ze znacznikami czasu i wynikami statusu na potrzeby walidacji operacyjnej.

Podłącz swój pierwszy webhook

Zajmij piaskownicę, zarejestruj punkt końcowy w Admin → Programista → Webhook i sprawdź lub odtwórz każdą dostawę z konsoli programisty.