Iconus Tech/Documentation

Webhooks

Receive real-time notifications for check verifications, fraud alerts, and other events.

Overview

Webhooks allow your application to receive real-time notifications when events occur in the Iconus Tech system.

Available Events:

  • check.registered - New check registered
  • check.verified - Check verification completed
  • fraud.detected - Fraud detected
  • oauth.connected - OAuth connection established
  • oauth.sync_completed - OAuth sync completed

Setup Webhooks

Configure Webhook URL

Configure Webhook
curl -X POST https://api.iconustech.com/v1/partners/partner_abc123/webhooks \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://yourapp.com/webhooks/iconus",
"events": ["check.verified", "fraud.detected"],
"secret": "your_webhook_secret"
}'

Response:

json
{
"success": true,
"data": {
"webhookId": "webhook_abc123",
"url": "https://yourapp.com/webhooks/iconus",
"events": ["check.verified", "fraud.detected"],
"secret": "whsec_abc123def456",
"status": "ACTIVE",
"createdAt": "2025-11-12T10:30:00Z"
}
}

Webhook Events

check.verified

Sent when a check verification is completed.

json
{
"event": "check.verified",
"timestamp": "2025-11-12T10:30:00Z",
"data": {
"checkId": "check_abc123",
"checkNumber": "1001",
"amount": 1500.00,
"payeeName": "Acme Corp",
"fraudDetected": false,
"fraudScore": 5,
"riskLevel": "LOW",
"verificationCount": 1
}
}

fraud.detected

Sent when fraud is detected during verification.

json
{
"event": "fraud.detected",
"timestamp": "2025-11-12T10:35:00Z",
"data": {
"checkId": "check_def456",
"checkNumber": "1002",
"fraudScore": 85,
"riskLevel": "HIGH",
"reasons": [
"Check has been voided",
"Multiple verification attempts"
],
"recommendation": "REJECT"
}
}

Implementing Webhooks

Node.js/Express

webhook-handler.js
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
// Verify webhook signature
function verifySignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
// Webhook endpoint
app.post('/webhooks/iconus', (req, res) => {
const signature = req.headers['x-iconus-signature'];
const payload = JSON.stringify(req.body);
// Verify signature
if (!verifySignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const { event, data } = req.body;
// Handle events
switch (event) {
case 'check.verified':
handleCheckVerified(data);
break;
case 'fraud.detected':
handleFraudDetected(data);
break;
default:
console.log('Unknown event:', event);
}
res.status(200).send('OK');
});
function handleCheckVerified(data) {
console.log('βœ… Check Verified:', data.checkId);
console.log('Risk Level:', data.riskLevel);
// Update your database
// Send notifications
// Process payment
}
function handleFraudDetected(data) {
console.log('🚨 FRAUD DETECTED:', data.checkId);
console.log('Reasons:', data.reasons);
// Alert security team
// Block check
// Log incident
}
app.listen(3000);

Python/Flask

webhook_handler.py
from flask import Flask, request, jsonify
import hmac
import hashlib
app = Flask(__name__)
def verify_signature(payload, signature, secret):
"""Verify webhook signature"""
mac = hmac.new(
secret.encode(),
msg=payload.encode(),
digestmod=hashlib.sha256
)
return hmac.compare_digest(mac.hexdigest(), signature)
@app.route('/webhooks/iconus', methods=['POST'])
def handle_webhook():
# Get signature
signature = request.headers.get('X-Iconus-Signature')
payload = request.get_data(as_text=True)
# Verify signature
if not verify_signature(payload, signature, os.getenv('WEBHOOK_SECRET')):
return jsonify({'error': 'Invalid signature'}), 401
# Parse event
event_data = request.json
event = event_data['event']
data = event_data['data']
# Handle events
if event == 'check.verified':
handle_check_verified(data)
elif event == 'fraud.detected':
handle_fraud_detected(data)
return jsonify({'status': 'success'}), 200
def handle_check_verified(data):
print(f"βœ… Check Verified: {data['checkId']}")
print(f"Risk Level: {data['riskLevel']}")
# Update database
# Send notifications
def handle_fraud_detected(data):
print(f"🚨 FRAUD DETECTED: {data['checkId']}")
print(f"Reasons: {data['reasons']}")
# Alert security team
# Block check
if __name__ == '__main__':
app.run(port=3000)

Security

Verify Signatures

Always verify webhook signatures to ensure requests are from Iconus Tech:

verify-signature.js
const crypto = require('crypto');
function verifyWebhookSignature(req) {
const signature = req.headers['x-iconus-signature'];
const payload = JSON.stringify(req.body);
const secret = process.env.WEBHOOK_SECRET;
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
// Usage
app.post('/webhooks', (req, res) => {
if (!verifyWebhookSignature(req)) {
return res.status(401).send('Unauthorized');
}
// Process webhook
res.status(200).send('OK');
});

Testing Webhooks

Test Webhook Endpoint

Test Webhook
curl -X POST https://yourapp.com/webhooks/iconus \
-H "Content-Type: application/json" \
-H "X-Iconus-Signature: test_signature" \
-d '{
"event": "check.verified",
"timestamp": "2025-11-12T10:30:00Z",
"data": {
"checkId": "check_test123",
"fraudScore": 5,
"riskLevel": "LOW"
}
}'

Best Practices

1. Return 200 Quickly

async-processing.js
app.post('/webhooks/iconus', async (req, res) => {
// Verify signature
if (!verifySignature(req)) {
return res.status(401).send('Unauthorized');
}
// Return 200 immediately
res.status(200).send('OK');
// Process asynchronously
processWebhookAsync(req.body).catch(console.error);
});
async function processWebhookAsync(data) {
// Handle webhook processing
// Update database
// Send notifications
}

2. Implement Retry Logic

retry-logic.js
async function processWebhook(data, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
await handleWebhook(data);
return;
} catch (error) {
console.error(`Attempt ${i + 1} failed:`, error);
if (i === retries - 1) {
// Log to dead letter queue
await logFailedWebhook(data, error);
}
// Exponential backoff
await new Promise(resolve =>
setTimeout(resolve, Math.pow(2, i) * 1000)
);
}
}
}

3. Log All Events

event-logging.js
async function logWebhookEvent(event) {
await db.webhookLogs.create({
event: event.event,
checkId: event.data.checkId,
timestamp: event.timestamp,
processed: true,
createdAt: new Date(),
});
}

Next Steps

Support