Skip to main content

Webhooks and Events

Real-time notifications from Debitura when important events occur in your cases.

Overview

Webhooks enable Debitura to push real-time notifications to your application when events occur, eliminating the need for constant polling.

Benefits:

  • Real-time updates
  • Reduced API calls
  • Lower latency
  • Event-driven architecture
  • Reliable delivery with retries

How Webhooks Work

Basic Flow

  1. Event occurs in Debitura (e.g., payment received)
  2. Webhook triggered for registered endpoints
  3. HTTP POST sent to your endpoint URL
  4. Your server processes the webhook payload
  5. Acknowledgment returned (HTTP 200-299 response)
  6. Retry if failed (automatic retry logic)

Webhook Anatomy

HTTP Request:

POST /webhooks/debitura HTTP/1.1
Host: your-server.com
Content-Type: application/json
X-Debitura-Signature: sha256=abc123...
X-Debitura-Event: payment.received
X-Debitura-Webhook-Id: whk_xyz789

{
"id": "evt_abc123",
"type": "payment.received",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"case_id": "case_xyz789",
"payment_id": "pmt_abc456",
"amount": 10000,
"currency": "EUR"
}
}

Event Types

Case Events

Case lifecycle:

  • case.created - New case submitted
  • case.status_changed - Case status updated
  • case.assigned - Case assigned to Collection Partner
  • case.suspended - Case suspended
  • case.resumed - Case resumed from suspension
  • case.closed - Case closed

Case updates:

  • case.updated - Case information modified
  • case.note_added - Note added to case
  • case.document_uploaded - Document attached

Payment Events

Payment processing:

  • payment.received - Payment received from debtor
  • payment.allocated - Payment allocated to invoices
  • payment.failed - Payment processing failed
  • payment.refunded - Payment refunded

Payment plans:

  • payment_plan.created - Installment plan established
  • payment_plan.payment_due - Installment due soon
  • payment_plan.payment_missed - Installment payment missed
  • payment_plan.completed - All installments paid
  • payment_plan.defaulted - Payment plan failed

Payout Events

Creditor payouts:

  • payout.scheduled - Payout prepared
  • payout.processing - Transfer initiated
  • payout.completed - Funds sent successfully
  • payout.failed - Transfer failed

Communication Events

Debtor communications:

  • communication.sent - Message sent to debtor
  • communication.received - Response received from debtor
  • communication.bounced - Message delivery failed

Partner Events

For Referral Partners:

  • referral.case_submitted - Case submitted by your customer
  • referral.commission_earned - Commission generated

For Collection Partners:

  • assignment.received - New case assigned
  • assignment.updated - Assignment details changed
  • assignment.completed - Case work finished

Webhook Setup

Creating a Webhook

Via Portal:

  1. Navigate to Settings → Webhooks
  2. Click "Add Webhook Endpoint"
  3. Enter endpoint URL
  4. Select event types to receive
  5. Save and activate

Via API:

POST /v1/webhooks
{
"url": "https://your-server.com/webhooks/debitura",
"events": ["payment.received", "case.status_changed"],
"description": "Production webhook",
"secret": "whsec_your_secret_key"
}

Webhook Configuration

Required fields:

  • url - HTTPS endpoint (HTTP not allowed)
  • events - Array of event types to receive

Optional fields:

  • description - Internal label for webhook
  • secret - Custom signing secret (auto-generated if omitted)
  • metadata - Custom key-value data
  • enabled - Active status (default: true)

Security

Signature Verification

Every webhook includes a signature header to verify authenticity.

Header:

X-Debitura-Signature: sha256=abc123def456...

Verification steps:

  1. Extract components:

    • Timestamp from X-Debitura-Timestamp header
    • Signature from X-Debitura-Signature header
    • Webhook secret (from creation response)
  2. Construct signed payload:

    timestamp + "." + JSON body
  3. Compute HMAC:

    HMAC-SHA256(signed_payload, webhook_secret)
  4. Compare signatures:

    • Must match exactly
    • Use constant-time comparison

Example (Node.js):

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret, timestamp) {
// Construct signed payload
const signedPayload = `${timestamp}.${payload}`;

// Compute expected signature
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');

// Compare signatures (constant-time)
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expectedSignature}`)
);
}

Example (Python):

import hmac
import hashlib

def verify_webhook_signature(payload, signature, secret, timestamp):
# Construct signed payload
signed_payload = f"{timestamp}.{payload}"

# Compute expected signature
expected_signature = hmac.new(
secret.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()

# Compare signatures
return hmac.compare_digest(
signature,
f"sha256={expected_signature}"
)

Timestamp Validation

Prevent replay attacks by validating timestamps:

const WEBHOOK_TOLERANCE = 300; // 5 minutes

function isTimestampValid(timestamp) {
const now = Math.floor(Date.now() / 1000);
return Math.abs(now - timestamp) < WEBHOOK_TOLERANCE;
}

Best Practices

  1. Always verify signatures - Never trust unverified webhooks
  2. Validate timestamps - Prevent replay attacks
  3. Use HTTPS - Encrypt webhook data in transit
  4. Rotate secrets - Periodically update webhook secrets
  5. Validate payload structure - Check expected fields exist
  6. Handle duplicates - Use idempotency (event IDs)

Handling Webhooks

Endpoint Requirements

Your webhook endpoint must:

  • Accept POST requests
  • Use HTTPS (TLS 1.2+)
  • Respond within 5 seconds
  • Return HTTP 200-299 for success
  • Return HTTP 500+ for retryable failures

Response Codes

CodeMeaningDebitura Action
200-299SuccessMark as delivered
400-499Client errorMark as failed (no retry)
500-599Server errorRetry with backoff
TimeoutNo response in 5sRetry with backoff

Processing Pattern

Recommended approach:

app.post('/webhooks/debitura', async (req, res) => {
// 1. Verify signature FIRST
const isValid = verifyWebhookSignature(
req.body,
req.headers['x-debitura-signature'],
WEBHOOK_SECRET,
req.headers['x-debitura-timestamp']
);

if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}

// 2. Respond immediately (acknowledge receipt)
res.status(200).json({ received: true });

// 3. Process asynchronously
processWebhookAsync(req.body);
});

async function processWebhookAsync(webhook) {
try {
// Parse event
const { type, data } = webhook;

// Route to appropriate handler
switch (type) {
case 'payment.received':
await handlePaymentReceived(data);
break;
case 'case.status_changed':
await handleStatusChange(data);
break;
default:
console.log(`Unhandled event type: ${type}`);
}
} catch (error) {
console.error('Webhook processing failed:', error);
// Log for manual review
}
}

Retry Logic

Automatic Retries

If your endpoint fails, Debitura automatically retries:

Retry schedule:

  • Attempt 1: Immediately
  • Attempt 2: 5 seconds later
  • Attempt 3: 30 seconds later
  • Attempt 4: 2 minutes later
  • Attempt 5: 10 minutes later
  • Attempt 6: 1 hour later
  • Attempt 7: 6 hours later
  • Attempt 8: 24 hours later

Maximum attempts: 8

Backoff strategy: Exponential with jitter

Failed Webhooks

After all retries exhausted:

  • Webhook marked as failed in portal
  • Alert sent to account administrators
  • Event data retained for manual replay

Manual replay:

  • Available in webhook dashboard
  • Reprocesses failed event
  • Follows same retry schedule

Testing Webhooks

Webhook Testing Tool

Via Portal:

  1. Navigate to Webhooks → Test
  2. Select event type
  3. Customize payload (optional)
  4. Send test webhook
  5. View request/response

Via API:

POST /v1/webhooks/{webhook_id}/test
{
"event_type": "payment.received"
}

Local Development

Use ngrok or similar:

# Expose local server
ngrok http 3000

# Use ngrok URL in webhook configuration
https://abc123.ngrok.io/webhooks/debitura

Sandbox environment:

  • Test webhooks in sandbox
  • Same event types as production
  • No impact on live data

Monitoring Webhooks

Webhook Dashboard

Portal features:

  • Delivery success rates
  • Failed webhook alerts
  • Recent deliveries log
  • Retry status
  • Response times

Metrics tracked:

  • Total webhooks sent
  • Success rate (last 24h, 7d, 30d)
  • Average response time
  • Failed deliveries by endpoint
  • Event type distribution

Webhook Logs

Event details:

  • Timestamp
  • Event type
  • Payload
  • HTTP status received
  • Response body
  • Retry attempts

Log retention: 30 days

Export logs:

  • CSV export
  • API access: GET /v1/webhooks/{id}/deliveries

Best Practices

Development

  1. Start with sandbox - Test integration thoroughly
  2. Verify signatures - Security first
  3. Handle all event types - Unknown types may be added
  4. Idempotent processing - Use event IDs to prevent duplicates
  5. Respond quickly - Acknowledge within seconds
  6. Process asynchronously - Don't block webhook response

Production

  1. Monitor delivery rates - Set up alerts for failures
  2. Log webhook payloads - For debugging and audit
  3. Implement retry logic - On your side for critical operations
  4. Scale endpoint - Handle traffic spikes
  5. Use queue systems - Decouple receipt from processing
  6. Update webhook URLs - When deploying infrastructure changes

Error Handling

  1. Return proper status codes - Guide retry behavior
  2. Log errors thoroughly - Include context for debugging
  3. Alert on failures - Don't rely on manual checks
  4. Implement circuit breakers - Prevent cascading failures
  5. Manual replay capability - For failed critical events

Troubleshooting

Common Issues

Webhook not received:

  • Check endpoint is accessible (HTTPS, not firewalled)
  • Verify correct URL in configuration
  • Check event type is enabled
  • Review webhook dashboard for errors

Signature verification fails:

  • Ensure using correct webhook secret
  • Check timestamp tolerance
  • Verify payload not modified
  • Use raw body (not parsed JSON)

Timeouts:

  • Respond faster (< 5 seconds)
  • Process asynchronously
  • Optimize endpoint performance
  • Check for blocking operations

Duplicate events:

  • Implement idempotency using event IDs
  • Check for retry processing
  • Verify not configured multiple times

Next Steps