This guide shows you how to emit webhook events from your existing business logic.
In your payment processing code (e.g., PaymentController.ts):
import { webhookEventEmitter } from './WebhookEventEmitter';
import { WebhookEventType } from './WebhookEventEmitter';
// After successful payment
const payment = await processPaymentLogic();
// Emit webhook event
webhookEventEmitter.emitPaymentSuccess({
paymentId: payment.id,
userId: payment.userId,
billId: payment.billId,
amount: payment.amount,
method: payment.method,
transactionId: payment.transactionId,
timestamp: Date.now(),
});webhookEventEmitter.emitPaymentFailed({
paymentId: payment.id,
userId: payment.userId,
billId: payment.billId,
amount: payment.amount,
method: payment.method,
timestamp: Date.now(),
});In your bill creation code (e.g., BillingService.ts):
import { webhookEventEmitter } from './WebhookEventEmitter';
// After creating a bill
const bill = await createBillLogic();
webhookEventEmitter.emitBillCreated({
billId: bill.id,
userId: bill.userId,
utilityId: bill.utilityId,
amount: bill.amount.toNumber(),
dueDate: bill.dueDate.toISOString(),
status: bill.status,
timestamp: Date.now(),
});webhookEventEmitter.emitBillPaid({
billId: bill.id,
userId: bill.userId,
utilityId: bill.utilityId,
amount: bill.amount.toNumber(),
dueDate: bill.dueDate.toISOString(),
status: 'PAID',
timestamp: Date.now(),
});webhookEventEmitter.emitBillOverdue({
billId: bill.id,
userId: bill.userId,
utilityId: bill.utilityId,
amount: bill.amount.toNumber(),
dueDate: bill.dueDate.toISOString(),
status: 'OVERDUE',
timestamp: Date.now(),
});webhookEventEmitter.emitBillUpdated({
billId: bill.id,
userId: bill.userId,
utilityId: bill.utilityId,
amount: bill.amount.toNumber(),
dueDate: bill.dueDate.toISOString(),
status: bill.status,
timestamp: Date.now(),
});In your user registration code (e.g., auth.ts):
import { webhookEventEmitter } from './WebhookEventEmitter';
// After user creation
const user = await createUserLogic();
webhookEventEmitter.emitUserCreated({
userId: user.id,
email: user.email,
name: user.name,
timestamp: Date.now(),
});webhookEventEmitter.emitUserUpdated({
userId: user.id,
email: user.email,
name: user.name,
timestamp: Date.now(),
});In your document upload code (e.g., DocumentController.ts):
import { webhookEventEmitter } from './WebhookEventEmitter';
// After document upload
const document = await uploadDocumentLogic();
webhookEventEmitter.emitDocumentUploaded({
documentId: document.id,
userId: document.userId,
filename: document.filename,
mimeType: document.mimeType,
size: document.size,
timestamp: Date.now(),
});In your reporting code (e.g., AnalyticsController.ts):
import { webhookEventEmitter } from './WebhookEventEmitter';
// After report generation
const report = await generateReportLogic();
webhookEventEmitter.emitReportGenerated({
reportId: report.id,
userId: report.createdBy,
title: report.title,
type: report.type,
timestamp: Date.now(),
});- Import
webhookEventEmitterin controllers/services - Add webhook event emission after business logic completion
- Test webhook delivery with
/api/webhooks/testing/create-event - Verify webhook logs in
/api/webhooks/:webhookId/logs - Monitor delivery stats in
/api/webhooks/:webhookId/stats - Set up error handling for failed webhooks
- Configure retry policies based on use case
- Document webhook endpoints for API consumers
- Set up monitoring and alerting
- Test with staging environment
# Install ngrok
npm install -g ngrok
# Start ngrok tunnel
ngrok http 3000
# Use the ngrok URL in webhook registration
# Example: https://xxxx-xx-xx-xxx-xxx.ngrok-free.app/webhook# Test webhook signature verification
curl -X POST https://your-webhook-url.com/webhook \
-H "Content-Type: application/json" \
-H "X-Webhook-Signature: $(openssl dgst -sha256 -hmac 'your_secret' <<< '{\"test\":true}'|cut -d' ' -f2)" \
-H "X-Webhook-ID: webhook_123" \
-H "X-Event-Type: payment.success" \
-d '{"test":true}'- Webhook.cool - Test webhooks online
- RequestBin - Capture webhook requests
- Hookbin - Simple webhook testing
- ngrok - Local webhook tunnel
import { webhookEventEmitter } from './WebhookEventEmitter';
// 1. Wrap webhook events in try-catch
try {
webhookEventEmitter.emitPaymentSuccess(paymentData);
} catch (error) {
logger.error('Failed to emit webhook event', error);
// Continue with normal flow - webhook failures shouldn't block business operations
}
// 2. Use event listeners for debugging
webhookEventEmitter.on('error', (error) => {
logger.error('Webhook error:', error);
});
// 3. Test webhook delivery before deploying
const result = await webhookService.testWebhook(webhookId);
if (!result.success) {
logger.warn('Webhook test failed, check configuration');
}import { webhookMonitor } from './WebhookMonitor';
// Check webhook health periodically
setInterval(async () => {
try {
const health = await webhookMonitor.checkWebhookHealth(webhookId);
if (!health.isHealthy) {
// Alert on unhealthy webhook
notificationService.alertWebhookUnhealthy(webhookId, health);
}
} catch (error) {
logger.error('Health check failed:', error);
}
}, 5 * 60 * 1000); // Check every 5 minutes// Weekly performance report
const report = await webhookMonitor.generatePerformanceReport(userId);
console.log('Success Rate:', report.metrics.successRate);
console.log('Failed Events:', report.topFailedEvents);
console.log('Recommendations:', report.recommendations);-
Use Async Event Emission
- Don't wait for webhook delivery
- Let it run in background
-
Batch Event Processing
- Combine multiple events if possible
- Reduce API calls
-
Cache Webhook Configuration
- Store active webhooks in cache
- Reduce database queries
-
Configure Appropriate Timeouts
- Set timeouts based on expectation
- Balance between reliability and performance
-
Use Connection Pooling
- Improve HTTP performance
- Reuse connections
✅ Always verify webhook signatures on the receiving end ✅ Use HTTPS only - reject HTTP URLs ✅ Never log webhook secrets in plain text ✅ Validate all webhook payload data ✅ Implement rate limiting on webhook endpoints ✅ Use strong secrets (automatically generated) ✅ Rotate secrets regularly if compromised ✅ Sanitize sensitive data before sending
- Check webhook logs:
/api/webhooks/:webhookId/logs - Debug failed events:
/api/webhooks/testing/debug/:eventId - View delivery attempts: Event includes
deliveryAttemptsarray - Test webhook:
POST /api/webhooks/:webhookId/test