# Webhooks

## Overview

Webhooks allow you to receive real-time notifications when verifications are completed. Instead of polling our API for status updates, we'll automatically send verification results to your specified URL endpoint as soon as they're available.

***

### How Webhooks Work

#### The Webhook Flow

1. **Setup**: You configure a webhook URL in the Partner Portal
2. **Verification Process**: A user completes their verification
3. **Automatic Notification**: We immediately send the verification results to your webhook URL
4. **Processing**: Your application receives and processes the verification data

#### Benefits of Using Webhooks

* **Real-time Updates**: Get notified instantly when verifications complete
* **Reduced API Calls**: No need to continuously poll for status updates
* **Better User Experience**: Process results immediately and update your application
* **Reliable Delivery**: Automatic retry mechanism ensures delivery

***

### Creating a Webhook in the Partner Portal

#### Step-by-Step Setup

**1. Navigate to Webhook Management**

1. **Log into the Partner Portal**
   * Go to your partner dashboard
   * Navigate to the main menu
2. **Access Webhook Settings**
   * Click on **"Webhooks"** in the sidebar
   * You'll see your existing webhooks (if any) and options to create new ones

**2. Create Your First Webhook**

1. **Start Webhook Creation**
   * Click the **"Create Webhook"** button
   * This opens the webhook configuration form
2. **Configure Basic Settings**

   **Webhook URL** (Required)

   * Enter your endpoint URL: `https://your-domain.com/webhook`
   * This is where we'll send verification notifications
   * Must be a valid HTTPS URL for security

   **Status**

   * Toggle **"Active"** to enable the webhook
   * You can create inactive webhooks and enable them later

**3. Advanced Configuration (Optional)**

**Webhook Authentication Header**

* Enter a key/value  header verification
* We'll add that header to each webhook request

**4. Save Your Webhook**

1. **Review Settings**
   * Double-check your webhook URL
   * Ensure all settings are correct
2. **Create Webhook**
   * Click **"Save Webhook"** or **"Create"**
   * Your webhook is now active and ready to receive notifications

#### Example Webhook Configuration

```
Webhook URL: https://api.yourcompany.com/webhooks/cr3dentials
Status: Active
Header: secret: your-secure-secret-key-here
```

***

### Managing Your Webhooks

#### Viewing Webhook Details

In the Webhooks section, you can see:

* **Webhook URL**: The endpoint we're sending notifications to
* **Status**: Active/Inactive status
* **Created Date**: When the webhook was set up
* **Last Delivery**: Timestamp of the most recent notification
* **Success Rate**: Percentage of successful deliveries

#### Webhook Actions

For each webhook, you can:

* **Edit**: Modify the URL, secret, or payload template
* **Test**: Send a test notification to verify your endpoint
* **View Logs**: See delivery history and any errors
* **Deactivate**: Temporarily disable notifications
* **Delete**: Permanently remove the webhook

#### Monitoring Webhook Health

1. **Delivery Status**
   * Green: Webhook is delivering successfully
   * Yellow: Some delivery issues (temporary failures)
   * Red: Multiple delivery failures
2. **Troubleshooting Failed Deliveries**
   * Check webhook logs for error details
   * Verify your endpoint is responding with 2xx status codes
   * Ensure your server responds within 10 seconds

***

### Understanding Webhook Notifications

#### When Webhooks Are Triggered

We send webhook notifications when:

* ✅ A verification is **successfully completed**
* ✅ A verification **fails**
* ✅ A verification **expires**
* ✅ Manual review is **completed**

#### Default Webhook Payload

When a verification completes, your webhook will receive:

```json
{
  "type": "verification.completed",
  "status": "success",
  "data": {
    "verificationId": "ver_abc123",
    "sessionId": 123,
    "stepId": 456,
    "status": "VERIFIED",
    "proofData": {
      "income": {
        "monthlyAmount": 5000,
        "verified": true,
        "source": "chase-bank"
      }
    },
    "formattedData": {
      "incomeVerified": true,
      "verificationScore": 95
    },
    "metadata": {
      "dataSource": "chase-bank",
      "processingTimeMs": 15000,
      "verifiedAt": "2024-01-15T14:30:00Z"
    }
  }
}
```

#### Payload Fields Explained

| Field                 | Description                                            |
| --------------------- | ------------------------------------------------------ |
| `type`                | Event type (e.g., "verification.completed")            |
| `status`              | Overall result: "success" or "failed"                  |
| `data.verificationId` | Unique identifier for this verification                |
| `data.sessionId`      | Your session ID from when you created the verification |
| `data.status`         | Detailed verification status                           |
| `data.proofData`      | Raw verification data from the source                  |
| `data.formattedData`  | Processed, ready-to-use verification results           |
| `data.metadata`       | Additional information about the verification process  |

***

### Implementing Your Webhook Endpoint

#### Basic Webhook Handler Example

```javascript
// Node.js/Express example
app.post('/webhook/cr3dentials', (req, res) => {
  try {
    const webhook = req.body;
    
    // Process the verification result
    if (webhook.type === 'verification.completed') {
      handleVerificationCompleted(webhook.data);
    }
    
    // Always respond with 200 to acknowledge receipt
    res.status(200).json({ received: true });
    
  } catch (error) {
    console.error('Webhook processing error:', error);
    res.status(500).json({ error: 'Processing failed' });
  }
});

function handleVerificationCompleted(data) {
  // Update your database
  updateUserVerificationStatus(data.sessionId, data.status);
  
  // Send notification to user
  if (data.status === 'VERIFIED') {
    sendSuccessNotification(data.sessionId);
  } else {
    sendFailureNotification(data.sessionId);
  }
}
```

#### Security Best Practices

**1. Verify Webhook Signatures**

```javascript
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  const calculatedSignature = hmac
    .update(JSON.stringify(payload))
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(calculatedSignature)
  );
}

// Use in your webhook handler
app.post('/webhook/cr3dentials', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const isValid = verifyWebhookSignature(req.body, signature, 'your-secret');
  
  if (!isValid) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  
  // Process webhook...
});
```

**2. Handle Duplicate Deliveries**

```javascript
const processedWebhooks = new Set();

app.post('/webhook/cr3dentials', (req, res) => {
  const webhookId = req.body.data.verificationId;
  
  // Check if we've already processed this webhook
  if (processedWebhooks.has(webhookId)) {
    return res.status(200).json({ message: 'Already processed' });
  }
  
  // Process the webhook
  processVerification(req.body);
  
  // Mark as processed
  processedWebhooks.add(webhookId);
  
  res.status(200).json({ received: true });
});
```

***

### Webhook Best Practices

#### Response Requirements

Your webhook endpoint must:

✅ **Do:**

* Respond with a 2xx status code (200, 201, 204)
* Respond within 10 seconds
* Handle duplicate deliveries gracefully
* Verify webhook signatures when using secrets

❌ **Don't:**

* Return 3xx, 4xx, or 5xx status codes
* Take longer than 10 seconds to respond
* Process webhooks synchronously if they involve heavy operations

#### Error Handling and Retries

**Our Retry Policy:**

* We automatically retry failed deliveries
* Exponential backoff: 1s, 2s, 4s, 8s, 16s intervals
* After 5 failed attempts, the webhook is marked as inactive
* You can reactivate it once the issue is resolved

**Monitoring Delivery Issues:**

1. Check webhook logs in the Partner Portal
2. Look for patterns in failed deliveries
3. Verify your endpoint is responding correctly
4. Test your webhook with the built-in test feature

#### Performance Optimization

```javascript
// Good: Process webhooks asynchronously
app.post('/webhook/cr3dentials', (req, res) => {
  // Immediately acknowledge receipt
  res.status(200).json({ received: true });
  
  // Process asynchronously
  setImmediate(() => {
    processVerificationData(req.body);
  });
});

// Or use a queue for heavy processing
app.post('/webhook/cr3dentials', (req, res) => {
  // Add to processing queue
  verificationQueue.add('process-webhook', req.body);
  
  // Immediate response
  res.status(200).json({ received: true });
});
```

***

### Testing Your Webhook

#### Using the Test Feature

1. **Access Test Function**
   * Go to your webhook in the Partner Portal
   * Click **"Test Webhook"**
2. **Send Test Notification**
   * We'll send a sample verification payload to your endpoint
   * Check if your endpoint responds correctly
3. **Review Results**
   * Success: Your endpoint is working correctly
   * Failure: Check the error message and fix your endpoint

#### Manual Testing

```bash
# Test your webhook endpoint manually
curl -X POST https://your-domain.com/webhook \
  -H "Content-Type: application/json" \
  -H "x-webhook-signature: test-signature" \
  -d '{
    "type": "verification.completed",
    "status": "success",
    "data": {
      "verificationId": "test_123",
      "sessionId": 123,
      "status": "VERIFIED"
    }
  }'
```

***

### Troubleshooting Common Issues

#### Webhook Not Receiving Notifications

**Check:**

* \[ ] Webhook URL is correct and accessible
* \[ ] Webhook status is "Active"
* \[ ] Your server is running and responding
* \[ ] Firewall allows incoming HTTPS requests
* \[ ] SSL certificate is valid

#### Delivery Failures

**Common Causes:**

* Endpoint returns non-2xx status codes
* Server timeout (>10 seconds response time)
* SSL/TLS certificate issues
* Firewall blocking requests

**Solutions:**

1. Check webhook logs for specific error messages
2. Test your endpoint manually
3. Verify SSL certificate validity
4. Ensure quick response times

#### Security Issues

**If webhook signatures don't match:**

* Verify you're using the correct secret
* Check signature calculation algorithm
* Ensure you're signing the exact payload we send
