Webhooks gaukite realiu laiku pasirašymo įvykius
Įrinkite HTTPS URL savo "Certyneo" lentelėje ir gaukite HMAC-SHA256 pasirašytą POST, kai tik įvyks įvykis ant jūsų užrašų: pasirašymas, atsisakymas, galiojimo pabaigos. 8 palaikomi įvykiai, 6 bandymų eksponentiškas bandymas, 8 kodo eilutės kriptografijos patikra.
< 5s
Vidutinis pristatymo laikas po įvykio
5x
Bandymai, jei nepavyksta (iki ~ 9 h vėliau)
HMAC-SHA256
Kiekvienos prašymo parašo algoritmas
Renginių sąrašas
8 toliau išvardyti įvykiai apima visą Certyneo užrašų gyvenimo ciklą. Įjungkite tuos, kurie jus domina, nustatymuose → "Webhooks", ignoruokite kitus prenumeratos yra granuliarūs pagal įvykį.
| Pasirodymas | Išpuolis |
|---|---|
envelope.created | Įrašas sukuriamas (UI, API ar šablonu) naudingas sinchronizuoti įrašą CRM pusėje nuo pat kūrimo. |
envelope.sent | Užrašas išsiunčiamas pasirašiusiems asmenims (pirmas išsiųstas el. paštas). |
envelope.completed | Visi pasirašę asmenys pasirašė. eIDAS uždaryto PDF ir audito pėdsakoje galima rasti naudotojo naudotojo `proof_pdf_url`. |
envelope.declined | Parašytojas atsisakė užrašų, o priežastis (jei ją pateikia parašytojas) pateikiama `data.decline_reason`. |
envelope.voided | Užrašas buvo atšauktas išdavėjo iki visiško pasirašymo. |
envelope.expired | Užrašas baigėsi pasibaigus galiojimo terminui, jei nebuvo pasirašyta visos jo dalys. |
recipient.signed | Vienas pasirašęs (bet nebūtinai visi) naudingas sekmenciniams darbai: perkelti į kitą pasirašėją. |
recipient.viewed | Vienas iš pasirašytojų atvėrė pasirašymo nuorodą, dar nepasirašęs, naudinga tikslinėms prekybos paleidimams. |
Naudotojo krovinio formatas
Visi įvykiai turi tą pačią aukščiausio lygio JSON schemą: `event`, `envelope_id`, `occurred_at`, `data`. `data` turinys skiriasi pagal įvykį (API nuorodą pagal įvykį dokumentuoti laukai).
{
"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 parašas apskaičiuojamas ant žalio kūno, kaip išsiųstas.
HMAC parašo patikra
Kiekvienas užklausas pasirašomas jūsų "webhook" paslaptimi (įrodytu tik kartą sukuriant jį į skydliauką, o paskui užšifruotas po to).<timestamp>,v1=<hex_hmac>Visada patikrinkite parašą prieš apdorojant naudotinį krovinį. Be šio žingsnio kiekvienas gali suklastoti įvykį ir skambinti jūsų galiniam taškai.
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)Dažnas klaidas
Naudokite funkciją "timing-safe" (`crypto.timingSafeEqual` Node, `hmac.compare_digest` Python), nes jei to nepadarysite, dviejų parašų palyginimo laiko skirtumas palaipsniui atskleis paslaptį paciento puolikui (timing attack).
Perbandymo politika
Jei jūsų pasiekiamasis taškas atsako kitaip nei HTTP 2xx (išleidimas, 5xx, atsisakyta ryšys), mes iškvietame eksponentinį atsarginįjįjįjįjį. Iš viso 6 bandymai ~9 valandos. Po 6 bandymų įvykis yra pažymėtas "fallowed" jūsų interneto ryšio skydelyje ir išsiunčiamas įspėjamasis el. paštu.
| Bandymas | Bendras laikotarpis | Praėjusį laiką |
|---|---|---|
| #1 | 0 | 0 |
| #2 | + 1 min | 1 min |
| #3 | + 5 min | 6 min |
| #4 | + 30 min | 36 min |
| #5 | + 2 h | 2h 36 |
| #6 | + 6 h | 8h 36 |
Jei norite rankiniu būdu perduoti pralaimėtą įvykį, "webhook" lentyninėje yra mygtukas " Perduoti" kiekvienam pralaimėjusiam pristatymui, kuris yra prieinamas 7 dienas po galutinio pralaimėjimo.
Bandymas be tikro užrašų siuntimo
Galutinis taškas `/v1/webhooks/test` priima URL ir įvykio tipą, ir POSTe fiktyvų naudotinį krovinį, pasirašytą kaip tikras.
# 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 praktikos, kurias reikia laikytis
- HMAC parašas tikrinamas prieš skaitant kūną naudoti laikui pasiekiamą palyginimą.
- Kiekviena `envelope_id` × `event` apdorojama tik vieną kartą, saugant ID, jau matytus bazėje (išgręžimai gali atkurti tą patį įvykį).
- Atsakykite į HTTP 200 per 5 sekundes ir tada tvarkykite asinkroniškai (užsisakykite uoliai).
- Nėra jokių įrodymų, kad HMAC patikra yra nesuderinama su BOM arba nematoma baltos erdvės.
- Įjungti "dead-letter" eilę į įvykius "negerai" ir perkelti rankiniu būdu, jei įvyks incidentas jūsų tarnyboje.
- Toleruoti 5 minučių atostogą nuo `t=` iki priėmimo laiko, atmetti, kad būtų užblokuoti transliacijos.
Norėdami eiti toliau
Ar pasiruošę prisijungti prie savo sistemų?
Sukurkite nemokamą paskyrą per 2 minutes "webhook" konfigūracija yra prieinama nuo pat "Starter" plano (nemokama, 5 užrašai per mėnesį).