Skip to main content

Receiving Webhooks from Dora

Overview

When you configure a webhook URL in your Custom Website integration, Dora will automatically send HTTP POST requests to your endpoint whenever delivery events occur.

Setup

  1. Configure Webhook URL
    • Go to Integrations → Custom Website
    • Enter your webhook endpoint URL (e.g., https://yoursite.com/webhooks/dora)
    • Select which events you want to receive
    • Save the configuration
  2. Implement Webhook Endpoint
    • Create an endpoint on your server to receive POST requests
    • Verify the webhook signature (see below)
    • Process the event data

Webhook Events

Dora sends the following events:
EventDescription
delivery.createdNew delivery created
delivery.assignedDelivery assigned to a rider
delivery.picked_upRider picked up the package
delivery.in_transitPackage is in transit
delivery.completedDelivery completed successfully
delivery.cancelledDelivery was cancelled
delivery.failedDelivery attempt failed

Webhook Payload

json
{
  "event": "delivery.completed",
  "timestamp": "2025-11-25T16:30:00Z",
  "data": {
    "delivery_id": "uuid-here",
    "order_number": "ORDER-12345",
    "status": "delivered",
    "receiver_detail": [
      {
        "uuid": "receiver-uuid",
        "delivery_uuid": "delivery-uuid",
        "status": "delivered",
        "dropoff_photo": "https://...",
        "customer_name": "John Doe",
        "customer_email": "[email protected]",
        "customer_phone_number": "1234567890",
        "customer_phone_code": "+1",
        "customer_address": "123 Main St, City, State",
        "created_at": "2025-11-25T10:00:00Z",
        "items": [
          {
            "uuid": "item-uuid",
            "name": "Product A",
            "quantity": 2,
            "price": 75.00,
            "description": "Product description"
          }
        ]
      }
    ],
    "sender_detail": [
      {
        "uuid": "sender-uuid",
        "sender_name": "ABC Store",
        "sender_phone": "0987654321",
        "sender_email": "[email protected]",
        "sender_phonecode": "+1",
        "sender_address": "456 Business Ave, City",
        "business_owned": true,
        "created_at": "2025-11-25T10:00:00Z",
        "updated_at": "2025-11-25T10:00:00Z"
      }
    ],
    "delivery_fee": 10.00,
    "payment_status": "paid",
    "note": "Handle with care",
    "created_at": "2025-11-25T10:00:00Z",
    "updated_at": "2025-11-25T16:30:00Z",
    "picked_up_at": "2025-11-25T15:00:00Z",
    "dropoff_at": "2025-11-25T16:30:00Z",
    "rider": {
      "name": "Jane Smith",
      "phone": "+0987654321"
    }
  }
}

HTTP Headers

Dora includes the following headers with each webhook request:
Content-Type: application/json
X-Dora-Signature: sha256_hash_here
X-Dora-Event: delivery.completed
X-Dora-Delivery-ID: uuid-here

Signature Verification

IMPORTANT: Always verify the webhook signature to ensure the request came from Dora. The X-Dora-Signature header contains an HMAC SHA256 hash of the payload using your API key as the secret.

Code Example

php
<?php

function verifyDoraWebhook($payload, $signature, $apiKey) {
    $computedSignature = hash_hmac('sha256', $payload, $apiKey);
    return hash_equals($signature, $computedSignature);
}

// Webhook endpoint
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_DORA_SIGNATURE'] ?? '';
$apiKey = 'your_dora_api_key_here';

if (!verifyDoraWebhook($payload, $signature, $apiKey)) {
    http_response_code(401);
    die('Invalid signature');
}

$event = json_decode($payload, true);

// Process the event
switch ($event['event']) {
    case 'delivery.completed':
        // Update your database
        updateOrderStatus($event['data']['order_number'], 'delivered');
        
        // Access receiver details
        foreach ($event['data']['receiver_detail'] as $receiver) {
            $customerName = $receiver['customer_name'];
            $customerPhone = $receiver['customer_phone_number'];
            $customerAddress = $receiver['customer_address'];
            
            // Process items
            foreach ($receiver['items'] as $item) {
                logItem($item['name'], $item['quantity']);
            }
        }
        break;
    
    case 'delivery.picked_up':
        // Send notification to customer
        $receiver = $event['data']['receiver_detail'][0] ?? null;
        if ($receiver) {
            notifyCustomer(
                $receiver['customer_phone_code'] . $receiver['customer_phone_number'], 
                'Your package is on the way!'
            );
        }
        break;
    
    // Handle other events...
}

http_response_code(200);
echo json_encode(['status' => 'received']);

Retry Logic

If your endpoint returns a non-2xx status code or times out, Dora will retry the webhook:
  • Attempt 1: Immediate
  • Attempt 2: After 1 minute
  • Attempt 3: After 5 minutes
  • Attempt 4: After 15 minutes
After 3 failed attempts, the webhook will be marked as failed.

Best Practices

  1. Respond Quickly
    • Return a 200 status code immediately
    • Process the event asynchronously (queue it)
    • Don’t perform long-running operations in the webhook handler
  2. Verify Signatures
    • Always verify the X-Dora-Signature header
    • Use constant-time comparison to prevent timing attacks
  3. Handle Duplicates
    • Webhooks may be sent multiple times
    • Use delivery_id to detect and ignore duplicates
  4. Monitor Failures
    • Log all webhook requests
    • Set up alerts for repeated failures
    • Check the webhook events log in Dora dashboard
  5. Use HTTPS
    • Always use HTTPS for your webhook endpoint
    • Dora will not send webhooks to HTTP URLs

Testing Webhooks

You can test your webhook endpoint using tools like:
  • ngrok: Expose your local server to the internet
  • RequestBin: Inspect webhook payloads
  • Postman: Manually send test requests
Example test payload:
curl -X POST https://yoursite.com/webhooks/dora \
  -H "Content-Type: application/json" \
  -H "X-Dora-Signature: your_computed_signature" \
  -H "X-Dora-Event: delivery.completed" \
  -d '{
    "event": "delivery.completed",
    "timestamp": "2025-11-25T16:30:00Z",
    "data": {
      "delivery_id": "test-uuid",
      "order_number": "TEST-001",
      "status": "delivered"
    }
  }'

Troubleshooting

Webhooks not being received?
  • Check that your URL is publicly accessible
  • Verify your server is running and responding
  • Check firewall rules
  • Review server logs for errors
Signature verification failing?
  • Ensure you’re using the correct API key
  • Verify you’re hashing the raw request body
  • Check for encoding issues
Need help?