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
- Respond quickly: Return 200 OK within 5 seconds
- Process asynchronously: Queue events for background processing
- Handle duplicates: Use eventId for idempotency
- Log everything: Keep detailed logs for debugging
- Monitor failures: Alert on webhook delivery failures
Event Processing
- Verify signatures: Always validate webhook signatures
- Handle unknown events: Gracefully ignore unknown event types
- Store events: Persist events before processing
- Retry processing: Implement your own retry logic for processing failures
- Order independence: Don't assume events arrive in order
Security
- Use HTTPS: Never use HTTP endpoints
- Keep secrets safe: Store webhook secrets securely
- Rotate secrets: Periodically update webhook secrets
- Validate payloads: Check all fields before processing
- Rate limiting: Implement rate limiting on your endpoint
Monitoring
- Track delivery rates: Monitor successful vs failed deliveries
- Alert on failures: Set up alerts for webhook failures
- Log processing times: Monitor event processing performance
- 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
Related Resources
Webhooks are the recommended approach for real-time integration. For development and testing, use our sandbox environment.