Chaindoc webhooks
Webhooks आपके सर्वर को तुरंत इवेंट डेटा भेजते हैं जब कुछ भी Chaindoc में होता है। कोई पोलिंग नहीं, कोई देरी नहीं। यहाँ बात यह है — इस पेज में सेटअप, इवेंट टाइप्स, HMAC वेरिफिकेशन, रीट्राई लॉजिक और टेस्टिंग सब कुछ कवर किया गया है।
Overview
API को पोल करने के बजाय, webhooks आपके सर्वर को बताते हैं कि क्या हुआ जैसे ही वह होता है। आप इन्हें document status sync करने, signatures के बाद workflows trigger करने, notifications भेजने और अपने database को sync रखने के लिए use करेंगे।
- 3 automatic retries के साथ instant delivery (exponential backoff)
- HMAC SHA256 signature verification हर payload पर
- सिर्फ उन्हीं event types को filter करें जिनकी आपको जरूरत है
- आपके dashboard में delivery status tracking
Setup
Step 1: API key बनाएं
अपने Chaindoc dashboard में Settings → API Access पर जाएं और एक API key बनाएं जिसमें webhook configuration enabled हो।
Step 2: Webhook URL configure करें
API use करके अपना webhook endpoint configure करें:
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"
}'Step 3: अपना endpoint implement करें
अपने सर्वर पर webhook events receive करने के लिए एक endpoint बनाएं। यहाँ अलग-अलग languages में examples हैं:
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);Event types
Chaindoc इन events के लिए webhooks भेजता है:
document.created
Trigger होता है जब API के जरिए कोई नया document बनता है।
{
"event": "document.created",
"documentId": "86840ee4-8bf2-4a91-a289-e99d8307ec25",
"name": "Service Agreement",
"timestamp": "2024-12-04T10:30:00.000Z"
}document.verified
Trigger होता है जब कोई document blockchain पर सफलतापूर्वक verified हो जाता है।
{
"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
Trigger होता है जब सभी जरूरी signatures एकत्र हो जाते हैं।
{
"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
Trigger होता है जब कोई नया signature request बनाया जाता है।
{
"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
Trigger होता है जब सभी signers अपने signatures complete कर लेते हैं।
{
"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
Trigger होता है जब कोई signer signature request reject कर देता है।
{
"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"
}Security
Signature verification
Chaindoc सभी webhook payloads को HMAC SHA256 use करके sign करता है। Authenticity सुनिश्चित करने और replay attacks रोकने के लिए हमेशा signatures verify करें।
Verification कैसे काम करता है
1Chaindoc signature बनाता हैChaindoc आपके webhook secret का use करके HMAC signature बनाता है
2Header में signature भेजा जाता हैSignature X-Webhook-Signature header में भेजा जाता है
3आपका सर्वर verify करता हैआपका सर्वर signature recalculate करता है और timing-safe function से compare करता है
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');
}Retry logic
Chaindoc failed webhook deliveries को exponential backoff के साथ automatic retry करता है।
- 1st retry: 1 minute बाद
- 2nd retry: 5 minutes बाद (total: 6 minutes)
- 3rd retry: 15 minutes बाद (total: 21 minutes)
Webhooks test करना
Local development
Webhook testing के लिए ngrok जैसे tools का इस्तेमाल करके अपने local server को expose करें:
# 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/chaindocManual testing
Sample payload के साथ अपने webhook endpoint को test करें:
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"
}'Best practices
- Process करने से पहले हमेशा webhook signatures verify करें
- Timeouts से बचने के लिए जल्दी respond करें (30 seconds से कम)
- Webhooks को queue में asynchronously process करें
- Duplicate events handle करने के लिए idempotency implement करें
- Debugging और audit के लिए सभी webhook events log करें
- अपने dashboard में webhook delivery failures monitor करें
- Security के लिए HTTPS endpoints use करें
- सभी event types को gracefully handle करें (unknown events ignore करें)
Production example
यहाँ database integration के साथ एक production-ready webhook handler है:
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: {
verifiedAt: new Date(),
txHash: payload.txHash,
},
});
}What to do next
- API integration — common patterns और workflow examples
- API documentation — full endpoint reference
- SDKs — Server SDK और Embed SDK guides
- Security — HMAC verification और key management
- Installation — सभी frameworks के लिए SDK setup