Ugrás a fő tartalomra
Certyneo
Fejlesztő dokumentáció

Webhooks kapja meg a valós idejű aláírási eseményeket

Konfigurálja az HTTPS URL-t a Certyneo irányítópultjában, és kapjon egy HMAC-SHA256 aláírással ellátott POST-ot, amikor esemény történik a borítékjain: aláírás, elutasítás, lejárat. 11 támogatott esemény, 5 kézbesítési kísérlet exponenciális backoff-fal, kriptográfiai ellenőrzés 8 sor kódban.

< 5s

Az esemény utáni átlagos átviteli idő

5x

Összesen kézbesítési kísérletek, körülbelül 1 óra 20 perc alatt terítve

HMAC-SHA256

Minden egyes kérés aláírási algoritmusa

Az események katalógusa

Az alábbi 12 esemény a Certyneo boríték teljes életciklását lefedi. Engedélyezze azokat, amelyek érdekelnek Beállítások → Webhookok menüpontban, figyelmen kívül hagyja a többit — az előfizetés granulált eseményre.

EseményKiindulás
envelope.createdEgy borítékot hoznak létre (UI, API vagy sablon segítségével) ami a CRM oldalról történő bejegyzés létrehozásakor használható.
envelope.sentA boríték elküldésre kerül a aláírókhoz (első e-mail küldése).
envelope.completedAz összes aláírók aláírtak, és az eIDAS pecsételt PDF tárolva van. A payload a signedDocumentUrl-t tartalmazza, egy 7 napig érvényes előre aláírt linket; vagy GET /v1/envelopes/id/signed-document, és az audit trail GET /v1/envelopes/id/audit-trail segítségével.
envelope.declinedEgy aláíró elutasította a borítékot. Az elutasító címe `data.declinedBy`-ban van, és az indok, ha megadták, `data.reason`-ban.
envelope.voidedA borítékot az adásadó törölte, mielőtt a teljes aláírás megtörtént volna.
envelope.expiredA boríték lejárati dátuma lejárt teljes aláírás nélkül. Kérdezze meg a GET /v1/envelopes/id-t, hogy megtudja, mely aláírók hiányoznak.
envelope.returned_to_senderEgy aláíró visszaküldte a borítékot a kibocsátónak javítás céljából, nem utasította el. Az indok `data.reason`-ban van, és az indítványozó `data.returnedBy`-ban.
envelope.resubmittedA kibocsátó korrigálta, majd visszaküldte a korábban visszaküldött borítékot. Jelzi az aláírási ciklus folytatódását.
recipient.signedEgy egyedi aláíró aláírt (de nem feltétlenül az összes). Hasznos az előrehaladás nyomon követéséhez és a szekvenciális munkafolyamat következő lépésére való átváltáshoz. Figyelem: a pecsételt PDF még nem létezik ezen a ponton, még az utolsó aláíró esetében sem — egy ebből indított letöltés HTTP 409-et ad vissza. Használja az envelope.completed-et a dokumentumhoz.
recipient.viewedEgy aláíró nyitotta meg a aláírási linket, még nem írt alá, ami hasznos a célzott kereskedelmi fellendítésekhez.
recipient.approvedEgy jóváhagyó érvényesítette a borítékot aláírás nélkül (belső érvényesítési munkafolyamat). A cím `data.approvedBy`-ban van.
recipient.bouncedEgy címzett levelezési szervere véglegesen visszautasította a meghívót vagy az újraküldést (nem létező postafiók, halott tartomány). A címzett BOUNCED állapotba kerül, és az automatikus újraküldések leállnak. A cím a `data.recipientEmail` alatt található: javítsa ki, majd küldje újra a borítékot.

recipient.signed nem jelent "dokumentum elérhető"

A recipient.signed MINDEN aláíróra kibocsátódik abban a pillanatban, amikor befejezi az aláírást — beleértve az utolsót is, mielőtt a pecsételt PDF összeállítódna és tárolódna. Ebből a kezelőből indított letöltés tehát mindig HTTP 409 "Signed document not available until the envelope is COMPLETED" értéket kap. Ez nem hiba: ez egy "még nem kész". Iratkozzon fel az envelope.completed-re a dokumentum lekéréshez, és tartsa meg a recipient.signed-et az előrehaladás követéséhez (ki írta alá, és mikor).

Használati teher formátuma

Minden kézbesítés ugyanazt az top-level JSON sémát osztja: `event`, `data` és `timestamp`. Az esemény nevét a `X-Certyneo-Event` fejlécben is megismétlik, ami lehetővé teszi az útvonalválasztást még a test elemzése előtt. A `data` tartalma az esemény szerint változik, de mindig egy egyszerű értékek sík objektuma marad — soha nem tömb vagy beágyazott objektum. Íme egy teljes `envelope.completed` kézbesítés.

POST /webhooks/certyneo HTTP/1.1
Host: your.app
Content-Type: application/json
X-Certyneo-Event: envelope.completed
X-Certyneo-Delivery-Id: cm8f2h6a10004qr9k5p2wm3xt
X-Certyneo-Signature: 4f3d1c8b2a9e7f60d5c4b3a2918e7f6d5c4b3a2918e7f6d5c4b3a2918e7f6d5c
{
  "id": "cm8f2h6a10004qr9k5p2wm3xt",
  "event": "envelope.completed",
  "data": {
    "envelopeId": "cm7x2k9p40001qz8h3f7bn2ld",
    "sandbox": false,
    "subject": "Contrat de prestation Acme Corp",
    "status": "COMPLETED",
    "signatureLevel": "ADVANCED",
    "aesSignerCount": 2,
    "completedAt": "2026-05-27T08:42:13.000Z",
    "recipientCount": 2,
    "recipients": [
      { "email": "alice@acme.com", "name": "Alice Martin", "role": "SIGNER", "status": "SIGNED" },
      { "email": "bob@acme.com", "name": "Bob Durand", "role": "SIGNER", "status": "SIGNED" }
    ],
    "signedDocumentUrl": "https://storage.certyneo.com/signed/cm7x2k9p4.../contrat.pdf?X-Amz-Expires=604800&X-Amz-Signature=..."
  },
  "timestamp": "2026-05-27T08:42:13.521Z"
}

A signedDocumentUrl egy előre aláírt link, amely az eseménytől számított 7 napig érvényes: elkerüli a PDF lekéréséhez szükséges második hitelesített hívást. Hiányzik — és nem null —, ha az előaláírás meghiúsult, vagy ha egy QES-borítékot készítottek el tárolt dokumentum nélkül; használja helyette a GET /v1/envelopes/id/signed-document végpontot, amely a hiteles forrás. Ügyeljen arra is, hogy az eseménytől több mint 7 nappal később manuális újrajátszás után a dead-letter queue-ból: a payload-ban szereplő link lejárt, az API-végpont nem.

A HMAC aláírás a brutális testre számít, ahogy elküldtük ne változtassuk meg a réseket, a JSON újraparsolás gyakran megváltoztatja a kulcsok sorrendjét és megszakítja a hitelesítést.

Ellenőrizni a HMAC aláírást

Minden kérés alá van írva a webhook-titokkal (az előfizetés létrehozásakor csak egyszer jelenik meg). Az aláírás az `X-Certyneo-Signature` fejlécben kerül továbbításra: ez a kérés nyers törzse HMAC-SHA256, hexadecimálisan kódolva, előtag vagy időbélyeg nélkül. MINDIG ellenőrizze az aláírást a payload feldolgozása előtt — e lépés nélkül bárki hamisíthat egy eseményt és meghívhatja az Ön végpontját.

Node.js / TypeScript

import crypto from "node:crypto";

export function verifyCertyneoSignature(
  rawBody: string,
  signatureHeader: string,
  secret: string,
): boolean {
  // X-Certyneo-Signature = HMAC-SHA256(secret, rawBody), hex-encoded.
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");

  const received = Buffer.from(signatureHeader, "hex");
  const computed = Buffer.from(expected, "hex");

  // timingSafeEqual throws when the two buffers differ in length —
  // a malformed header must return false, not crash the handler.
  if (received.length !== computed.length) return false;

  // timingSafeEqual to mitigate timing attacks.
  return crypto.timingSafeEqual(computed, received);
}

Python

import hashlib
import hmac


def verify_certyneo_signature(
    raw_body: bytes, signature_header: str, secret: str
) -> bool:
    """Verify a Certyneo webhook signature.

    `X-Certyneo-Signature` holds the hex-encoded HMAC-SHA256 of the
    raw request body, computed with your webhook secret.
    """
    expected = hmac.new(
        secret.encode("utf-8"),
        raw_body,
        hashlib.sha256,
    ).hexdigest()

    return hmac.compare_digest(expected, signature_header)

Gyakori hiba

Ne használd a `===` vagy `==` funkciót a várt és a kapott aláírás összehasonlítására. Használd a time-safe funkciót (`crypto.timingSafeEqual` Node, `hmac.compare_digest` Python).

Újrapróbálási politika

Ha az endpoint túl hosszú ideig válaszol, megtagadja a kapcsolatot vagy 5xx-et (vagy 429-et) ad vissza, exponenciális visszalépés szerint próbálkozunk újra: összesen 5 kísérlet, körülbelül 1 óra 20 perc alatt. Az ötödik után az esemény dead-letter queue-ba kerül — megtekinthető és újrajátszható az irányítópultról, de már nem próbálkozik meg automatikusan. Az explicit megtagadás (401, 403, 404, 410, 422…) viszont sohasem próbálkozik újra: a válasz nem változna meg, az esemény közvetlenül a dead-letter queue-ba kerül.

MegpróbálvaTartalom előtti időtartamA eseménytől kezdve lejárt idő
#100
#2+ 1 min1 min
#3+ 5 min6 min
#4+ 15 min21 min
#5+ 1 h1 h 21

A feltüntetett határidők minimumok: az újrapróbálkozási vizsgálatot egy cron ütemezi, így a kísérlet az elméleti idő után néhány perccel indulhat el. Az elhagyott események a Webhooks → Hibák alatt találhatók, manuális újrajátszás gombbal és korlátlan megőrzési idővel. Az az endpoint, amely öt végzetes hibát láncolnak össze — vagy amely 404 / 410 -et válaszol — automatikusan letiltásra kerül, és e-mailben értesítést fog kapni: aktiválja újra a javítása után, a számláló nulláról indul (minden sikeres kézbesítés szintén nulláról indítja újra).

A valódi boríték elküldése nélkül tesztelni

Először hozzon létre egy előfizetést — a válasz tartalmazza az HMAC-ellenőrzéshez szükséges `secret`-et, amely csak egyszer jelenik meg. A Beállítások → Webhookok menüből a "Teszt" gomb ezután olyan POST-ot küld, amely pontosan olyan aláírt, mint a valódi kézbesítés, és megjeleníti a szerver nyers válaszát: ez a leggyorsabb módja a kezelő validálásának, lokálisan az ngrok-on vagy a folyamatos integrációban.

# Create a subscription — "secret" is returned once, store it now.
curl -X POST https://api.certyneo.com/v1/webhooks \
  -H "Authorization: Bearer $CERTYNEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your.app/webhooks/certyneo",
    "events": ["envelope.completed", "recipient.signed"]
  }'

Az URL nyilvánosan elérhető HTTPS-en keresztül: egy privát cím vagy localhost az SSRF-védelemmel elutasított az előfizetés létrehozásakor.

Az előfizetések környezet szerint elkülönítve vannak, mint a kulcsok: egy sk_test_ kulccsal létrehozott webhook csak tesztborítékok eseményeit fogadja, egy sk_live_ kulccsal létrehozott webhook csak valós borítékok eseményeit. Egy tesztboríték tehát soha nem éri el az Ön üzemi URL-jét, és minden terhelés a "sandbox" jelzést tartalmazza (igaz vagy hamis).

6 gyakorlat

  • A HMAC-jelet ellenőrizni a testből való olvasás előtt időbiztonságos összehasonlítást használni.
  • Deduplikálja az `X-Certyneo-Delivery-Id` fejléc alapján (azonos a törzs `id` mezőjével) az már látott azonosítók adatbázisban való tárolásával — egy újrajátszás újra kézbesíthet egy olyan eseményt, amelyet már feldolgozott, ha a 2xx elveszett, minden kísérletben azonos azonosítóval.
  • HTTP 2xx válaszoljon 10 másodpercen belül, majd aszinkron módon dolgozzon (queue). Ezen túl a kézbesítés leáll és hiba számít.
  • A brut testfelvétel + a teljes aláírás hibaelhárítás a HMAC ellenőrzés gyakran nem sikerül a láthatatlan BOM-on vagy fehérhelyeken.
  • Figyelje a Webhooks → Hibák oldalt: e-mailben értesítést kap, ha az endpoint letiltva van, de nem eseményrõl eseményre — az az esemény, amely kimerítette a kísérleteit, Önnek kell azt újrajátszania.
  • Szűrje az eseményeket az előfizetéskor, nem a kezelőben, és maradjon az 5 előfizetés alatt számlánként.

Nem kell üzemeltetnie egy végpontot ezen események fogadásához: az összekötő az Ön helyett létrehozza az előfizetést, és közvetlenül egy boríték eseménynél indítja el a folyamatot. Lásd Certyneo a Power Automatehez és a Microsoft 365-höz.

Tovább kell mennünk.

Készen álltok a rendszerek csatlakoztatására?

A webhook-ok és a REST API a Standard terv óta kerülnek az alkalmazottak közé. Hozza létre a fiókját, hozzon létre egy `sk_test_` kulcsot, és csatlakoztassa a végpontot a sandboxban, mielőtt éles környezetbe lépne.