Skip to main content

Workflow: Webhooks

Configure webhooks to receive real-time notifications about case events, status changes, and important updates. This guide covers webhook setup, event types, security, and best practices.

Overview

Webhooks provide a powerful mechanism for receiving instant notifications when events occur in your debt collection cases. Instead of polling the API for updates, Debitura pushes event notifications directly to your application.

Benefits of Webhooks

  • Real-time updates: Receive notifications immediately when events occur
  • Reduced API calls: No need for constant polling
  • Better user experience: Update your UI instantly
  • Automated workflows: Trigger business processes automatically
  • Resource efficiency: Lower infrastructure costs

Webhook Setup

1. Register Your Endpoint

Configure your webhook endpoint in the Debitura platform:

Endpoint: POST /api/webhooks

POST /api/webhooks
Authorization: Bearer your-access-token
Content-Type: application/json

{
"url": "https://your-app.com/webhooks/debitura",
"events": [
"case.created",
"case.status.changed",
"payment.received",
"case.resolved"
],
"description": "Production webhook for case updates",
"active": true
}

Response:

{
"webhookId": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://your-app.com/webhooks/debitura",
"secret": "whsec_3kj4h5k3j4h5k3j4h5k3j4h5",
"events": ["case.created", "case.status.changed", "payment.received", "case.resolved"],
"active": true,
"createdAt": "2024-01-02T10:30:00Z"
}

2. Implement Endpoint Handler

Create an endpoint in your application to receive webhook events:

Requirements:

  • Accept POST requests
  • Return 200 OK response quickly
  • Process payloads asynchronously
  • Validate webhook signatures

Example endpoint:

app.post('/webhooks/debitura', (req, res) => {
// Verify webhook signature
const signature = req.headers['x-debitura-signature'];
if (!verifySignature(req.body, signature)) {
return res.status(401).send('Invalid signature');
}

// Acknowledge receipt immediately
res.status(200).send('OK');

// Process event asynchronously
processWebhookEvent(req.body);
});

Event Types

Case Events

case.created

{
"eventId": "evt_123",
"eventType": "case.created",
"timestamp": "2024-01-02T10:30:00Z",
"data": {
"caseId": "550e8400-e29b-41d4-a716-446655440000",
"caseNumber": "DEB-2024-12345",
"debtorName": "Example Company ApS",
"principalAmount": 15000.00,
"status": "Created"
}
}

case.status.changed

{
"eventId": "evt_124",
"eventType": "case.status.changed",
"timestamp": "2024-01-08T09:15:00Z",
"data": {
"caseId": "550e8400-e29b-41d4-a716-446655440000",
"caseNumber": "DEB-2024-12345",
"oldStatus": "Assigned",
"newStatus": "In Collection",
"subStatus": "First reminder sent",
"changedBy": "Partner Agent"
}
}

case.resolved

{
"eventId": "evt_125",
"eventType": "case.resolved",
"timestamp": "2024-02-15T14:30:00Z",
"data": {
"caseId": "550e8400-e29b-41d4-a716-446655440000",
"caseNumber": "DEB-2024-12345",
"resolution": "Paid in full",
"finalAmount": 15000.00,
"resolutionDate": "2024-02-15"
}
}

Payment Events

payment.received

{
"eventId": "evt_126",
"eventType": "payment.received",
"timestamp": "2024-01-25T11:00:00Z",
"data": {
"caseId": "550e8400-e29b-41d4-a716-446655440000",
"caseNumber": "DEB-2024-12345",
"paymentId": "pmt_789",
"amount": 5000.00,
"currency": "DKK",
"paymentDate": "2024-01-25",
"remainingBalance": 10000.00
}
}

payment.plan.created

{
"eventId": "evt_127",
"eventType": "payment.plan.created",
"timestamp": "2024-01-20T10:00:00Z",
"data": {
"caseId": "550e8400-e29b-41d4-a716-446655440000",
"paymentPlanId": "plan_456",
"totalAmount": 15000.00,
"installments": 6,
"monthlyAmount": 2500.00,
"startDate": "2024-02-01"
}
}

Communication Events

message.sent

{
"eventId": "evt_128",
"eventType": "message.sent",
"timestamp": "2024-01-10T14:30:00Z",
"data": {
"caseId": "550e8400-e29b-41d4-a716-446655440000",
"messageType": "email",
"subject": "Payment reminder",
"sentTo": "debtor@example.com",
"sentBy": "Collection Partner A"
}
}

message.received

{
"eventId": "evt_129",
"eventType": "message.received",
"timestamp": "2024-01-11T09:00:00Z",
"data": {
"caseId": "550e8400-e29b-41d4-a716-446655440000",
"messageType": "email",
"from": "debtor@example.com",
"subject": "Re: Payment reminder",
"hasAttachments": true
}
}

Security

Signature Verification

Every webhook request includes a signature in the X-Debitura-Signature header. Verify this signature to ensure the request came from Debitura:

Node.js example:

const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');

return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}

C# example:

using System.Security.Cryptography;
using System.Text;

public bool VerifySignature(string payload, string signature, string secret)
{
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
var expectedSignature = Convert.ToHexString(hash).ToLower();

return signature == expectedSignature;
}

HTTPS Requirement

  • Webhook URLs must use HTTPS
  • Valid SSL certificate required
  • Self-signed certificates not supported

IP Allowlisting

Optionally restrict webhook requests to Debitura IP addresses:

203.0.113.0/24
198.51.100.0/24

Error Handling

Retry Logic

If your endpoint returns an error or times out, Debitura will retry:

  • Retry schedule: Exponential backoff (1min, 5min, 15min, 1hr, 6hr)
  • Max retries: 5 attempts
  • Timeout: 30 seconds per request

Failure Notifications

After all retries are exhausted:

  • Webhook is marked as failed
  • You receive an email notification
  • Event is logged in webhook activity

Manual Replay

You can manually replay failed events:

Endpoint: POST /api/webhooks/{webhookId}/replay/{eventId}

POST /api/webhooks/550e8400-e29b-41d4-a716-446655440000/replay/evt_123
Authorization: Bearer your-access-token

Testing Webhooks

Test Events

Send test events to verify your endpoint:

Endpoint: POST /api/webhooks/{webhookId}/test

POST /api/webhooks/550e8400-e29b-41d4-a716-446655440000/test
Authorization: Bearer your-access-token
Content-Type: application/json

{
"eventType": "case.created"
}

Webhook Logs

View delivery history and debug issues:

Endpoint: GET /api/webhooks/{webhookId}/logs

{
"logs": [
{
"eventId": "evt_123",
"eventType": "case.created",
"timestamp": "2024-01-02T10:30:00Z",
"status": "delivered",
"responseCode": 200,
"attempts": 1
},
{
"eventId": "evt_124",
"eventType": "case.status.changed",
"timestamp": "2024-01-08T09:15:00Z",
"status": "failed",
"responseCode": 500,
"attempts": 5,
"lastError": "Connection timeout"
}
]
}

Best Practices

Endpoint Implementation

  1. Respond quickly: Return 200 OK within 5 seconds
  2. Process asynchronously: Queue events for background processing
  3. Handle duplicates: Use eventId for idempotency
  4. Log everything: Keep detailed logs for debugging
  5. Monitor failures: Alert on webhook delivery failures

Event Processing

  1. Verify signatures: Always validate webhook signatures
  2. Handle unknown events: Gracefully ignore unknown event types
  3. Store events: Persist events before processing
  4. Retry processing: Implement your own retry logic for processing failures
  5. Order independence: Don't assume events arrive in order

Security

  1. Use HTTPS: Never use HTTP endpoints
  2. Keep secrets safe: Store webhook secrets securely
  3. Rotate secrets: Periodically update webhook secrets
  4. Validate payloads: Check all fields before processing
  5. Rate limiting: Implement rate limiting on your endpoint

Monitoring

  1. Track delivery rates: Monitor successful vs failed deliveries
  2. Alert on failures: Set up alerts for webhook failures
  3. Log processing times: Monitor event processing performance
  4. Dashboard metrics: Display webhook health in dashboards

Managing Webhooks

Update Webhook Configuration

Endpoint: PUT /api/webhooks/{webhookId}

PUT /api/webhooks/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer your-access-token
Content-Type: application/json

{
"events": ["case.created", "case.status.changed", "payment.received"],
"active": true
}

Disable Webhook

Endpoint: PUT /api/webhooks/{webhookId}

{
"active": false
}

Delete Webhook

Endpoint: DELETE /api/webhooks/{webhookId}

DELETE /api/webhooks/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer your-access-token

Webhooks are the recommended approach for real-time integration. For development and testing, use our sandbox environment.