Documentation Index Fetch the complete documentation index at: https://docs-kfhye.zochil.dev/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Webhooks allow you to receive real-time notifications when specific events occur in the Zochil API. Instead of polling our API for changes, webhooks push data to your application as events happen.
How Webhooks Work
Configure : Set up webhook endpoints in your application
Subscribe : Register your webhook URL for specific events
Receive : Get instant notifications when events occur
Process : Handle the webhook payload in your application
Webhook Events
User Events
Event Description user.createdNew user registration user.updatedUser profile changes user.deletedUser account deletion user.verifiedEmail verification completed
Order Events
Event Description order.createdNew order placed order.updatedOrder status changed order.cancelledOrder cancelled order.completedOrder fulfilled order.payment_succeededPayment processed successfully order.payment_failedPayment processing failed
Product Events
Event Description product.createdNew product added product.updatedProduct information changed product.deletedProduct removed inventory.updatedProduct inventory changed
Cart Events
Event Description cart.item_addedItem added to cart cart.item_removedItem removed from cart cart.abandonedCart abandoned (no activity for 24h)
Setting Up Webhooks
1. Create a Webhook Endpoint
Create an HTTP endpoint in your application to receive webhook notifications:
Node.js/Express
Python/Flask
const express = require ( "express" );
const crypto = require ( "crypto" );
const app = express ();
app . use ( express . json ());
app . post ( "/webhooks/zochil" , ( req , res ) => {
const signature = req . get ( "X-Zochil-Signature" );
const payload = JSON . stringify ( req . body );
// Verify webhook signature (recommended)
if ( ! verifySignature ( payload , signature )) {
return res . status ( 401 ). send ( "Unauthorized" );
}
const { event , data } = req . body ;
// Handle the event
switch ( event ) {
case "user.created" :
console . log ( "New user:" , data . user );
// Send welcome email, create user profile, etc.
break ;
case "order.created" :
console . log ( "New order:" , data . order );
// Update inventory, send confirmation, etc.
break ;
default :
console . log ( "Unhandled event:" , event );
}
res . status ( 200 ). send ( "OK" );
});
function verifySignature ( payload , signature ) {
const webhookSecret = process . env . ZOCHIL_WEBHOOK_SECRET ;
const expectedSignature = crypto
. createHmac ( "sha256" , webhookSecret )
. update ( payload )
. digest ( "hex" );
return crypto . timingSafeEqual (
Buffer . from ( signature ),
Buffer . from ( `sha256= ${ expectedSignature } ` )
);
}
app . listen ( 3000 );
2. Register Your Webhook
Register your webhook endpoint using the Admin API:
curl -X POST "https://api.zochil.io/admin/webhooks" \
-H "access-token: YOUR_ACCESS_TOKEN" \
-H "device-id: YOUR_DEVICE_ID" \
-H "merchant-id: YOUR_MERCHANT_ID" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/zochil",
"events": ["user.created", "order.created", "order.updated"],
"active": true,
"secret": "your-webhook-secret-key"
}'
Webhook Payload Structure
All webhook payloads follow this structure:
{
"id" : "evt_1234567890abcdef" ,
"event" : "user.created" ,
"created" : 1640995200 ,
"data" : {
"user" : {
"id" : "123e4567-e89b-12d3-a456-426614174000" ,
"email" : "user@example.com" ,
"name" : "John Doe" ,
"created_at" : "2023-01-01T00:00:00Z"
}
},
"api_version" : "v1"
}
Payload Fields
Example Event Payloads
User Created Event
{
"id" : "evt_user_created_123" ,
"event" : "user.created" ,
"created" : 1640995200 ,
"data" : {
"user" : {
"id" : "123e4567-e89b-12d3-a456-426614174000" ,
"email" : "user@example.com" ,
"name" : "John Doe" ,
"phone" : "+1234567890" ,
"is_verified" : false ,
"created_at" : "2023-01-01T00:00:00Z"
}
},
"api_version" : "v1"
}
Order Created Event
{
"id" : "evt_order_created_456" ,
"event" : "order.created" ,
"created" : 1640995200 ,
"data" : {
"order" : {
"id" : "order_123e4567e89b12d3" ,
"order_number" : "ORD-2023-001" ,
"user_id" : "123e4567-e89b-12d3-a456-426614174000" ,
"status" : "pending" ,
"total" : 299.99 ,
"currency" : "USD" ,
"items" : [
{
"product_id" : "prod_123" ,
"quantity" : 2 ,
"price" : 149.99
}
],
"created_at" : "2023-01-01T00:00:00Z"
}
},
"api_version" : "v1"
}
Inventory Updated Event
{
"id" : "evt_inventory_updated_789" ,
"event" : "inventory.updated" ,
"created" : 1640995200 ,
"data" : {
"product" : {
"id" : "prod_123e4567e89b12d3" ,
"sku" : "PWH-001" ,
"name" : "Premium Wireless Headphones"
},
"inventory" : {
"previous_quantity" : 100 ,
"current_quantity" : 95 ,
"reserved" : 5 ,
"available" : 90
}
},
"api_version" : "v1"
}
Security
Signature Verification
All webhooks include an X-Zochil-Signature header for verification:
const crypto = require ( "crypto" );
function verifyWebhookSignature ( payload , signature , secret ) {
const expectedSignature = crypto
. createHmac ( "sha256" , secret )
. update ( payload , "utf8" )
. digest ( "hex" );
const receivedSignature = signature . replace ( "sha256=" , "" );
return crypto . timingSafeEqual (
Buffer . from ( expectedSignature ),
Buffer . from ( receivedSignature )
);
}
IP Whitelisting
Webhook requests come from these IP ranges:
198.51.100.0/24
203.0.113.0/24
Handling Failures
Retry Logic
If your webhook endpoint returns a non-2xx status code, we’ll retry:
Immediate retry : After 1 second
Exponential backoff : 5s, 25s, 125s, 300s
Maximum attempts : 5 retries
Timeout : 30 seconds per attempt
Failed Webhook Dashboard
Monitor failed webhooks in your admin dashboard:
GET /admin/webhooks/{webhook_id}/deliveries
Best Practices
1. Idempotency
Handle duplicate webhook deliveries gracefully:
const processedEvents = new Set ();
app . post ( "/webhooks/zochil" , ( req , res ) => {
const eventId = req . body . id ;
// Check if we've already processed this event
if ( processedEvents . has ( eventId )) {
return res . status ( 200 ). send ( "Already processed" );
}
// Process the event
handleEvent ( req . body );
// Mark as processed
processedEvents . add ( eventId );
res . status ( 200 ). send ( "OK" );
});
2. Async Processing
Process webhooks asynchronously to respond quickly:
const Queue = require ( "bull" );
const webhookQueue = new Queue ( "webhook processing" );
app . post ( "/webhooks/zochil" , ( req , res ) => {
// Add to queue for async processing
webhookQueue . add ( "process-webhook" , req . body );
// Respond immediately
res . status ( 200 ). send ( "OK" );
});
webhookQueue . process ( "process-webhook" , ( job ) => {
const { event , data } = job . data ;
// Process the webhook data
return handleWebhookEvent ( event , data );
});
3. Error Handling
Log errors and return appropriate status codes:
app . post ( "/webhooks/zochil" , async ( req , res ) => {
try {
await processWebhook ( req . body );
res . status ( 200 ). send ( "OK" );
} catch ( error ) {
console . error ( "Webhook processing failed:" , error );
// Return 5xx for temporary failures (will be retried)
if ( error . temporary ) {
return res . status ( 503 ). send ( "Temporary failure" );
}
// Return 4xx for permanent failures (won't be retried)
res . status ( 400 ). send ( "Invalid webhook data" );
}
});
Testing Webhooks
Local Development
Use tools like ngrok to expose your local server:
# Install ngrok
npm install -g ngrok
# Expose your local server
ngrok http 3000
# Use the HTTPS URL for webhook registration
# https://abc123.ngrok.io/webhooks/zochil
Create a simple webhook tester:
const express = require ( "express" );
const app = express ();
app . use ( express . json ());
app . post ( "/test-webhook" , ( req , res ) => {
console . log ( "Received webhook:" );
console . log ( "Headers:" , req . headers );
console . log ( "Body:" , JSON . stringify ( req . body , null , 2 ));
res . status ( 200 ). send ( "Webhook received" );
});
app . listen ( 3000 , () => {
console . log ( "Webhook tester running on port 3000" );
});
Managing Webhooks
List Webhooks
Update Webhook
PATCH /admin/webhooks/{webhook_id}
Delete Webhook
DELETE /admin/webhooks/{webhook_id}
Test Webhook
Trigger a test webhook delivery:
POST /admin/webhooks/{webhook_id}/test
Next Steps
Admin API Learn about webhook management endpoints
Error Handling Handle webhook errors gracefully