Fara beint að aðalefni
Certyneo
Þróunargögn

Webhooks fáðu undirritunarviðburði í rauntíma

Settu upp HTTPS vefsíðu í Certyneo skjáborðinu þínu og fáðu POST sem er undirritaður með HMAC-SHA256 þegar viðburður kemur upp á umslaginu þínu: undirritun, synjun, útgengi. 8 viðburðir studdir, framsetningar tilraunir á 6 tilraunum, dulkóðapróf í 8 línum kóða.

< 5s

Meðalframkvæmdartími eftir atvik

5x

Tilraunir ef misteknar (til ~ 9 klst síðar)

HMAC-SHA256

Undirtekningargátorítmi fyrir hverja beiðni

Atburðarskrá

The 8 atburðir hér að neðan ná yfir alla lífstímabil Certyneo umslag.

AtburðurUppspretta
envelope.createdUmslag er búið til (með UI, API eða sniðmát) gagnlegt til að samræma skráningu á CRM hliðinni strax við gerð.
envelope.sentUmslögin eru send undirritendum (fyrsti tölvupóstur sendur).
envelope.completedAllir undirritendur hafa skrifað undir. eIDAS-þétt PDF og endurskoðunarleið er í boði í notendahlaðnum í gegnum `proof_pdf_url`.
envelope.declinedSkýrsla um að hafna er í `data.decline_reason`.
envelope.voidedUmslagið var aflýst af útgefanda áður en það var undirritað.
envelope.expiredUpplýsingar um að undirritun er hætt er að finna á `data.missing_signers`.
recipient.signedEinn einstaklingur sem skrifaði undir hefur skrifað undir (en ekki allir).
recipient.viewedSá sem skrifaði undir opnaði undirritunarhlekkinn án þess að skrifa undir.

Stærð greiðslugjalds

Allir atburðirnir deila sömu JSON top-level skemmu: `event`, `envelope_id`, `occurred_at`, `data`. Innihald `data` er mismunandi eftir atburði (viðburðarskráð svið í API viðmiðuninni). Hér er fullkomið dæmi um `envelope.completed`.

{
  "event": "envelope.completed",
  "envelope_id": "env_01HG3K8X9Y2N4P5Q6R7S8T9V0W",
  "occurred_at": "2026-05-27T08:42:13.521Z",
  "data": {
    "title": "Contrat de prestation Acme Corp",
    "status": "completed",
    "created_at": "2026-05-24T14:12:00.000Z",
    "completed_at": "2026-05-27T08:42:13.000Z",
    "signers": [
      {
        "email": "client@acme.example",
        "name": "Alex Client",
        "signed_at": "2026-05-27T08:42:13.000Z",
        "method": "eidas_aes",
        "ip": "203.0.113.42"
      }
    ],
    "proof_pdf_url": "https://certyneo.com/api/envelopes/env_01HG.../proof.pdf"
  }
}

HMAC-fyrirtækið er reiknað út á hreina líkamann eins og sendur er.

Verið fyrir HMAC-fyrirtækinu.

Hver beiðni er undirritað með webhook leyndarmálinu þínu (sýnilegt einu sinni þegar þú stofnar það í stjórnborðinu og síðan dulkóðað í hvíld).<timestamp>,v1=<hex_hmac>Alltaf athugaðu undirskriftina áður en þú vinnur með greiðslugjald. Án þess að fara í þetta skref getur hver sem er skapað atburð og kallað á endamæli þitt.

Node.js / TypeScript

import crypto from "node:crypto";

export function verifyCertyneoSignature(
  rawBody: string,
  signatureHeader: string,
  secret: string,
): boolean {
  // Header format: t=<timestamp>,v1=<hex_hmac>
  const parts = Object.fromEntries(
    signatureHeader.split(",").map((p) => p.split("=")),
  );
  const ts = parts.t;
  const sig = parts.v1;
  if (!ts || !sig) return false;

  // Reject events older than 5 minutes (replay protection).
  const age = Math.abs(Date.now() / 1000 - Number(ts));
  if (age > 300) return false;

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${ts}.${rawBody}`)
    .digest("hex");

  // timingSafeEqual to mitigate timing attacks.
  return crypto.timingSafeEqual(
    Buffer.from(expected, "hex"),
    Buffer.from(sig, "hex"),
  );
}

Python

import hashlib
import hmac
import time


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

    Header format: `t=<timestamp>,v1=<hex_hmac>`
    Rejects events older than 5 minutes (replay protection).
    """
    parts = dict(p.split("=") for p in signature_header.split(","))
    ts = parts.get("t")
    sig = parts.get("v1")
    if not ts or not sig:
        return False

    if abs(time.time() - int(ts)) > 300:
        return False

    expected = hmac.new(
        secret.encode("utf-8"),
        f"{ts}.{raw_body.decode('utf-8')}".encode("utf-8"),
        hashlib.sha256,
    ).hexdigest()

    return hmac.compare_digest(expected, sig)

Algeng mistök

Notaðu ekki `===` eða `==` til að bera saman væntanlega undirskrift við móttekna. Notaðu tímasparandi hlutverk (`crypto.timingSafeEqual` í Node, `hmac.compare_digest` í Python). Annars kemur samanburður milli tveggja undirrita smám saman og afhjúpar leyndarmálið fyrir sjúkra árásara (timing attack).

Endurprófunarstefna

Ef lokastaðurinn svarar öðru en HTTP 2xx (tímabilið, 5xx, tenging hafnað) þá hringjum við með frásagnarlegum bakslag. Alls 6 tilraunir á ~9 klst. Eftir 6 er atburðurinn merktur `failed` í veffflutningaskránni og við sendum viðvörunarpóst.

TilraunSamansett fresturTími liðinn
#100
#2+ 1 min1 min
#3+ 5 min6 min
#4+ 30 min36 min
#5+ 2 h2h 36
#6+ 6 h8h 36

Ef þú vilt senda fram misheppnað atburð handvirkt þá er á veffflutningaskránni knappur Endurafhending á hverri misheppnuðu sendingu sem er í boði í 7 daga eftir að hún hefur misheppnað.

Prófa án þess að senda raunverulega umslag

Endamálið `/v1/webhooks/test` samþykkir URL og atburðartegund og POST skáldleg greiðslugjald sem er undirritað nákvæmlega eins og raunverulegt. Tilvalið til að staðfesta handfara þinn í áframhaldandi samþættingu eða á staðnum (með ngrok eða sambærilegum).

# Trigger a test webhook to your endpoint
curl -X POST https://api.certyneo.com/v1/webhooks/test \
  -H "Authorization: Bearer $CERTYNEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event": "envelope.completed", "url": "https://your.app/webhooks/certyneo"}'

6 aðferðir sem þú þarft að fara eftir

  • Athugaðu HMAC-fyrirritun fyrir öllum lestri á líkamann notaðu tímas öruggan samanburð.
  • Að vinna með hvern `envelope_id` × `event` aðeins einu sinni með því að geyma ID sem þegar hafa verið skoðaðar í grunninn (aðföll geta skilað sama atburði aftur).
  • Svar HTTP 200 innan 5 sekúndna og síðan meðhöndla asynchronous (sví). Annars verður þú í timeout og telst að reyna aftur.
  • Loggaðu brott líkamann + fullur undirritun í debug HMAC staðfesting mistekur oft á BOM eða ósýnilegum hvíta rými.
  • Tengja upp dauðabréf á viðburðum `failed` til að flytja handvirkt ef tilvik á hliðinni á þjónustu þinni.
  • Að þola 5 mínútna frest milli `t=` og móttöku yfir, hafna til að koma í veg fyrir endurspeglun.

Til að fara lengra

Eruð þið tilbúin til að tengja saman kerfi ykkar?

Búðu til ókeypis reikning á 2 mínútum uppsetningin á vefhlaðvarpi er í boði í Starter áætluninni (frjáls, 5 umsláttir/mánuð).