Webhooks Documentation

This document covers the webhook system for the Universal Bookshelf platform, allowing external systems to receive real-time notifications about platform events.

Overview

Webhooks provide a way for external systems to receive real-time notifications when specific events occur in the Universal Bookshelf platform. This enables seamless integration with third-party services, analytics platforms, and custom applications.

How Webhooks Work

  1. You register a webhook URL with the platform
  2. When an event occurs, the platform sends an HTTP POST request to your URL
  3. Your system processes the webhook payload and takes appropriate action
  4. The platform expects a successful response (2xx status code) to confirm delivery

Supported Webhook Events

User Events

  • user.registered - New user registration
  • user.updated - User profile updates
  • user.deleted - User account deletion
  • user.login - User login activity

Book Events

  • book.created - New book publication
  • book.updated - Book information updates
  • book.published - Book goes live
  • book.unpublished - Book taken offline
  • book.deleted - Book removal

Order Events

  • order.created - New order placement
  • order.paid - Order payment confirmation
  • order.shipped - Order shipping notification
  • order.delivered - Order delivery confirmation
  • order.cancelled - Order cancellation
  • order.refunded - Order refund processing

Payment Events

  • payment.succeeded - Successful payment
  • payment.failed - Failed payment attempt
  • payment.refunded - Payment refund
  • payment.disputed - Payment dispute

Download Events

  • download.started - eBook download initiated
  • download.completed - eBook download finished
  • download.failed - Download failure

Webhook Management

POST /api/webhooks

Create a new webhook subscription

Request Body:
{
    "url": "https://yourdomain.com/webhook",
    "events": ["order.created", "payment.succeeded"],
    "description": "Order and payment notifications",
    "secret": "your_webhook_secret"
}
Success Response (201):
{
    "status": true,
    "message": "Webhook created successfully",
    "webhook": {
        "id": 1,
        "url": "https://yourdomain.com/webhook",
        "events": ["order.created", "payment.succeeded"],
        "status": "active",
        "created_at": "2024-01-01T00:00:00.000000Z"
    }
}
GET /api/webhooks

List all webhook subscriptions

Headers:
Authorization: Bearer <your_jwt_token>
Success Response (200):
{
    "status": true,
    "webhooks": [
        {
            "id": 1,
            "url": "https://yourdomain.com/webhook",
            "events": ["order.created", "payment.succeeded"],
            "status": "active",
            "created_at": "2024-01-01T00:00:00.000000Z"
        }
    ]
}
PUT /api/webhooks/{id}

Update webhook subscription

Headers:
Authorization: Bearer <your_jwt_token>
Request Body:
{
    "events": ["order.created", "payment.succeeded", "book.published"],
    "description": "Updated webhook description"
}
DELETE /api/webhooks/{id}

Delete webhook subscription

Headers:
Authorization: Bearer <your_jwt_token>
Success Response (200):
{
    "status": true,
    "message": "Webhook deleted successfully"
}

Webhook Payload Structure

Standard Payload Format

All webhook payloads follow a consistent structure:

{
    "id": "webhook_event_id",
    "event": "order.created",
    "created_at": "2024-01-01T00:00:00.000000Z",
    "data": {
        // Event-specific data
    },
    "api_version": "1.0"
}

Event-Specific Examples

Order Created Webhook

{
    "id": "evt_123456789",
    "event": "order.created",
    "created_at": "2024-01-01T00:00:00.000000Z",
    "data": {
        "order_id": 12345,
        "user_id": 67890,
        "total_amount": 29.99,
        "currency": "USD",
        "items": [
            {
                "book_id": 111,
                "title": "Sample Book",
                "format": "ebook",
                "price": 29.99
            }
        ],
        "status": "pending"
    },
    "api_version": "1.0"
}

Payment Succeeded Webhook

{
    "id": "evt_987654321",
    "event": "payment.succeeded",
    "created_at": "2024-01-01T00:00:00.000000Z",
    "data": {
        "payment_id": "pi_123456789",
        "order_id": 12345,
        "amount": 29.99,
        "currency": "USD",
        "payment_method": "stripe",
        "status": "succeeded"
    },
    "api_version": "1.0"
}

Security & Authentication

Security Requirements

  • Always use HTTPS for webhook URLs in production
  • Implement webhook signature verification
  • Use unique secrets for each webhook
  • Validate webhook payloads before processing

Webhook Signature Verification

The platform sends webhooks with a signature header for verification:

// Webhook signature header
X-Webhook-Signature: sha256=abc123def456...

Signature Verification Example

// PHP example
function verifyWebhookSignature($payload, $signature, $secret) {
    $expectedSignature = 'sha256=' . hash_hmac('sha256', $payload, $secret);
    return hash_equals($expectedSignature, $signature);
}

// Verify the webhook
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$secret = 'your_webhook_secret';

if (!verifyWebhookSignature($payload, $signature, $secret)) {
    http_response_code(400);
    exit('Invalid signature');
}

Webhook Delivery & Retry

Delivery Process

  1. Event occurs in the platform
  2. Webhook is queued for delivery
  3. HTTP POST request sent to your URL
  4. Platform waits for response
  5. If successful (2xx), webhook marked as delivered
  6. If failed, webhook is retried

Retry Logic

  • Initial Attempt - Immediate delivery
  • 1st Retry - After 5 minutes
  • 2nd Retry - After 15 minutes
  • 3rd Retry - After 1 hour
  • Final Retry - After 24 hours

Response Requirements

Successful Responses (2xx)

Return any 2xx status code to confirm successful webhook processing:

  • 200 OK - Standard success response
  • 201 Created - Resource created successfully
  • 202 Accepted - Request accepted for processing

Failed Responses (4xx, 5xx)

Any 4xx or 5xx status code will trigger a retry:

  • 400 Bad Request - Invalid payload
  • 500 Internal Server Error - Server error
  • 503 Service Unavailable - Service temporarily unavailable

Testing Webhooks

Test Webhook Endpoint

POST /api/webhooks/test

Send a test webhook to verify your endpoint

Headers:
Authorization: Bearer <your_jwt_token>
Request Body:
{
    "webhook_id": 1,
    "test_event": "order.created"
}

Local Testing with ngrok

For local development, use ngrok to expose your local server:

# Install ngrok
npm install -g ngrok

# Expose local server
ngrok http 8000

# Use the ngrok URL as your webhook endpoint
# https://abc123.ngrok.io/webhook

Webhook Monitoring

Delivery Logs

Monitor webhook delivery status and history:

GET /api/webhooks/{id}/logs

Get webhook delivery logs

Response:
{
    "status": true,
    "logs": [
        {
            "id": 1,
            "event": "order.created",
            "status": "delivered",
            "response_code": 200,
            "response_time": 150,
            "created_at": "2024-01-01T00:00:00.000000Z"
        }
    ]
}

Webhook Statistics

  • Delivery success rate
  • Average response time
  • Failed delivery count
  • Retry attempts

Best Practices

Webhook Best Practices

  • Process webhooks asynchronously when possible
  • Implement idempotency to handle duplicate webhooks
  • Log all webhook events for debugging
  • Set appropriate timeouts for webhook processing
  • Monitor webhook delivery success rates
  • Have a fallback mechanism for failed webhooks

Need Help?

For additional support or questions about webhooks, please contact our development team.

Back to Documentation