Chaindoc veebihookid
Saate reaalajas teateid, kui teie Chaindoc-kontol toimuvad sündmused. Webhookid edastavad sündmuste andmed teie serverisse koheselt, mistõttu pole vaja teavet küsida.
Ülevaade
Chaindoc Webhooks võimaldab teie rakendusel saada reaalajas teateid, kui teie kontol toimuvad sündmused. API päringute asemel edastavad webhooks sündmuste andmed teie serverisse niipea, kui toimub mingi tegevus.
Peamised omadused
- Reaalajas teated – sündmuste kohene edastamine teie serverisse
- Automaatsed korduskatseid – kuni 3 korduskatseid eksponentsiaalse tagasilükkamisega
- Allkirja kontrollimine – HMAC SHA256 andmete autentsuse kontrollimiseks
- Sündmuste filtreerimine – saate ainult need sündmused, mis teile huvi pakuvad
- Veakontroll – jälgige webhooki edastamise staatust ja vigu
Kasutusjuhud
- Saada e-posti teated, kui dokumendid on allkirjastatud
- Käivitage töövood, kui dokumendid on blockchainis kinnitatud
- Uuendage oma andmebaasi, kui luuakse allkirja taotlused
- Sünkroniseerige dokumendi staatus väliste süsteemidega
- Auditi jälg ja vastavuse logimine
Seadistamine
1. samm: looge API-võti
Mine oma Chaindoc-i juhtpaneelis valikule „Seaded” → „API-juurdepääs” ja loo API-võti, mille veebihooki konfiguratsioon on aktiveeritud.
2. samm: konfigureerige veebihooki URL
Kasutage API-d oma webhooki lõpppunkti konfigureerimiseks:
curl -X PATCH https://api.chaindoc.io/user/api-access/1/config \
-H "Authorization: Bearer your_auth_token" \
-H "Content-Type: application/json" \
-d '{
"webhookUrl": "https://yourapp.com/webhooks/chaindoc",
"webhookEnabled": true,
"webhookSecret": "your_secure_random_string"
}'3. samm: rakendage veebihooki lõpppunkt
Looge oma serverisse lõpppunkt veebihooki sündmuste vastuvõtmiseks. Siin on näited erinevates keeltes:
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
app.post('/webhooks/chaindoc', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const eventType = req.headers['x-webhook-event'];
// Verify signature
if (!verifySignature(req.body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process event
console.log('Received event:', eventType, req.body);
// Handle different event types
switch (eventType) {
case 'document.created':
handleDocumentCreated(req.body);
break;
case 'document.verified':
handleDocumentVerified(req.body);
break;
case 'signature.request.completed':
handleSignatureCompleted(req.body);
break;
}
// Always respond with 200 OK
res.status(200).send('Webhook received');
});
function verifySignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(JSON.stringify(payload)).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
app.listen(3000);Ürituste tüübid
Chaindoc saadab veebihooke järgmiste sündmuste puhul:
document.created
Käivitatakse, kui API kaudu luuakse uus dokument.
{
"event": "document.created",
"documentId": "86840ee4-8bf2-4a91-a289-e99d8307ec25",
"name": "Service Agreement",
"timestamp": "2024-12-04T10:30:00.000Z"
}document.verified
Käivitatakse, kui dokument on edukalt kinnitatud plokiahelas.
{
"event": "document.verified",
"documentId": "86840ee4-8bf2-4a91-a289-e99d8307ec25",
"versionId": "f0b7721f-0399-4035-9b69-7b95d3a367f0",
"txHash": "0x789ghi...",
"chainId": 137,
"timestamp": "2024-12-04T10:35:00.000Z"
}document.signed
Käivitatakse, kui kõik vajalikud allkirjad on kogutud.
{
"event": "document.signed",
"documentId": "86840ee4-8bf2-4a91-a289-e99d8307ec25",
"signatureRequestId": "req_21096b94498f4a2d9795e810edc2c9a9",
"signers": [
{
"email": "signer1@example.com",
"signedAt": "2024-12-04T10:30:00.000Z"
},
{
"email": "signer2@example.com",
"signedAt": "2024-12-04T10:32:00.000Z"
}
],
"timestamp": "2024-12-04T10:32:00.000Z"
}signature.request.created
Käivitatakse, kui luuakse uus allkirja taotlus.
{
"event": "signature.request.created",
"signatureRequestId": "req_21096b94498f4a2d9795e810edc2c9a9",
"documentId": "86840ee4-8bf2-4a91-a289-e99d8307ec25",
"recipients": [
{"email": "signer1@example.com"},
{"email": "signer2@example.com"}
],
"deadline": "2024-12-31T23:59:59.000Z",
"timestamp": "2024-12-04T10:30:00.000Z"
}signature.request.completed
Käivitatakse, kui kõik allkirjastajad on oma allkirjad andnud.
{
"event": "signature.request.completed",
"signatureRequestId": "req_21096b94498f4a2d9795e810edc2c9a9",
"documentId": "86840ee4-8bf2-4a91-a289-e99d8307ec25",
"completedAt": "2024-12-04T10:32:00.000Z",
"timestamp": "2024-12-04T10:32:00.000Z"
}signature.request.rejected
Käivitatakse, kui allakirjutaja lükkab allkirja taotluse tagasi.
{
"event": "signature.request.rejected",
"signatureRequestId": "req_21096b94498f4a2d9795e810edc2c9a9",
"documentId": "86840ee4-8bf2-4a91-a289-e99d8307ec25",
"rejectedBy": "signer1@example.com",
"reason": "Terms not acceptable",
"timestamp": "2024-12-04T10:30:00.000Z"
}Turvalisus
Allkirja kontrollimine
Chaindoc allkirjastab kõik veebihooki andmed HMAC SHA256 abil. Kontrollige alati allkirju, et tagada autentsus ja vältida kordusrünnakuid.
Kuidas allkirja kontrollimine toimib
1Chaindoc loob allkirjaChaindoc loob HMAC-allkirja, kasutades teie veebihooki salajast võtit
2Allkiri saadetud päisesAllkiri saadetakse X-Webhook-Signature päises
3Teie server kontrollibTeie server arvutab allkirja uuesti ja võrdleb seda ajaliselt turvalise funktsiooni abil.
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(JSON.stringify(payload)).digest('hex');
// Use timing-safe comparison to prevent timing attacks
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
// Usage
const isValid = verifyWebhookSignature(
req.body,
req.headers['x-webhook-signature'],
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}Korrata loogikat
Chaindoc proovib ebaõnnestunud webhooki edastusi automaatselt uuesti eksponentsiaalse tagasilükkamisega.
- 1. korduskatse: 1 minuti pärast
- 2. korduskatse: 5 minuti pärast (kokku: 6 minutit)
- 3. korduskatse: 15 minuti pärast (kokku: 21 minutit)
Veebihookide testimine
Kohalik arendus
Kasutage ngrok-i taolisi tööriistu, et avada oma kohalik server veebihookide testimiseks:
# Install ngrok
npm install -g ngrok
# Start your local server
node server.js
# Expose port 3000
ngrok http 3000
# Use the ngrok URL as your webhook endpoint
# Example: https://abc123.ngrok.io/webhooks/chaindocKäsitsi testimine
Testige oma webhooki lõpppunkti näidisandmetega:
curl -X POST https://yourapp.com/webhooks/chaindoc \
-H "Content-Type: application/json" \
-H "X-Webhook-Event: document.created" \
-H "X-Webhook-Signature: test_signature" \
-d '{
"event": "document.created",
"documentId": "test-123",
"name": "Test Document",
"timestamp": "2024-12-04T10:30:00.000Z"
}'Parimad tavad
- Kontrollige alati veebihooki allkirju enne töötlemist
- Vastake kiiresti (alla 30 sekundi), et vältida ajalõpu ületamist
- Töötle veebihookeid asünkroonselt järjekorras
- Rakendage idempotentsust, et käsitleda dubleeritud sündmusi
- Logige kõik veebihooki sündmused veaotsinguks ja auditeerimiseks
- Jälgige veebihookide edastamise ebaõnnestumisi oma juhtpaneelis
- Kasutage turvalisuse tagamiseks HTTPS-lõpppunkte
- Käsitlege kõiki sündmustüüpe viisakalt (ignoreerige tundmatud sündmused)
Täielik näide
Siin on tootmisvalmis veebihooki käitleja koos andmebaasi integratsiooniga:
import express from 'express';
import crypto from 'crypto';
import { PrismaClient } from '@prisma/client';
const app = express();
const prisma = new PrismaClient();
app.use(express.json());
app.post('/webhooks/chaindoc', async (req, res) => {
const signature = req.headers['x-webhook-signature'] as string;
const eventType = req.headers['x-webhook-event'] as string;
const payload = req.body;
// 1. Verify signature
if (!verifySignature(payload, signature, process.env.WEBHOOK_SECRET!)) {
console.error('Invalid webhook signature');
return res.status(401).json({ error: 'Invalid signature' });
}
// 2. Check for duplicate events (idempotency)
const eventId = `${eventType}-${payload.timestamp}`;
const existing = await prisma.webhookEvent.findUnique({
where: { eventId },
});
if (existing) {
console.log('Duplicate event, skipping:', eventId);
return res.status(200).json({ status: 'duplicate' });
}
// 3. Store event
await prisma.webhookEvent.create({
data: {
eventId,
eventType,
payload,
processedAt: new Date(),
},
});
// 4. Process event asynchronously
processWebhookAsync(eventType, payload).catch((error) => {
console.error('Error processing webhook:', error);
});
// 5. Respond immediately
res.status(200).json({ status: 'received' });
});
async function processWebhookAsync(eventType: string, payload: any) {
switch (eventType) {
case 'document.verified':
await handleDocumentVerified(payload);
break;
case 'signature.request.completed':
await handleSignatureCompleted(payload);
await sendNotificationEmail(payload);
break;
case 'signature.request.rejected':
await handleSignatureRejected(payload);
break;
}
}
async function handleDocumentVerified(payload: any) {
await prisma.document.update({
where: { id: payload.documentId },
data: {
status: 'verified',
blockchainTxHash: payload.txHash,
verifiedAt: new Date(payload.timestamp),
},
});
}
async function handleSignatureCompleted(payload: any) {
await prisma.signatureRequest.update({
where: { id: payload.signatureRequestId },
data: {
status: 'completed',
completedAt: new Date(payload.completedAt),
},
});
}
function verifySignature(payload: any, signature: string, secret: string): boolean {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(JSON.stringify(payload)).digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));
}
app.listen(3000);