---
url: >-
  https://docs.corbitaltech.dev/products/whatsmark-saas/ref-docs/WHATSAPP_WEBHOOK_FORWARDING_FEATURE.md
---
# WhatsApp Webhook Forwarding Feature - Complete Documentation

## Table of Contents

* [Overview](#overview)
* [Architecture & Flow](#architecture--flow)
* [Key Components](#key-components)
* [Configuration Guide](#configuration-guide)
* [N8N Format Structure](#n8n-format-structure)
* [Event Types](#event-types)
* [Implementation Details](#implementation-details)
* [Security Features](#security-features)
* [Troubleshooting](#troubleshooting)
* [Code References](#code-references)

***

## Overview

The **WhatsApp Webhook Forwarding** feature allows your application to automatically forward incoming WhatsApp webhook events to external endpoints (primarily N8N automation workflows) in a standardized, structured format.

### What It Does

* Receives WhatsApp webhook events (messages, status updates, etc.)
* Transforms raw WhatsApp payloads into N8N-compatible structured format
* Forwards selected events to configured external webhook URLs
* Includes signature verification for security
* Supports multi-tenancy (tenant-specific configurations)
* Filters events by field types (messages, statuses, templates, etc.)

### Use Cases

* Integrate with N8N for automation workflows
* Send WhatsApp events to third-party systems
* Build custom integrations without modifying core code
* Create multi-step automation based on WhatsApp events
* Analytics and monitoring of WhatsApp interactions

***

## Architecture & Flow

```

  WhatsApp API    (Meta/Facebook)
   (Webhooks)

          1. Webhook Event


  WhatsAppWebhookController
  (/webhook/whatsapp)

 • Receives raw WhatsApp payload
 • Verifies webhook authenticity
 • Processes messages/statuses
 • Checks duplicate messages

          2. Process Webhook


  forwardWebhookData()

 • Check if forwarding enabled
 • Filter by enabled event fields
 • Check webhook URL validity

          3. Transform Data


  WhatsAppWebhookN8NTransformer

 • Detect event type
 • Extract resource data
 • Structure payload for N8N
 • Add tenant context
 • Include original payload

          4. N8N Formatted Payload


  HTTP Request to External Endpoint

 • Add signature header (HMAC-SHA256)
 • Add event type header
 • Add timestamp header
 • POST/GET/Custom method

          5. Forward to N8N


  N8N Workflow    (or any external endpoint)
  (Automation)

```

***

## Key Components

### 1. WhatsAppWebhookController

**File:** `app/Http/Controllers/Whatsapp/WhatsAppWebhookController.php`

**Main Method:** `forwardWebhookData(string $feedData, array $payload)`

**Responsibilities:**

* Retrieve tenant-specific webhook settings
* Filter events based on configured field types
* Call transformer for payload conversion
* Send HTTP request to external endpoint
* Log forwarding success/failure

**Settings Used:**

* `enable_webhook_resend` - Enable/disable forwarding
* `whatsapp_data_resend_to` - Target webhook URL
* `webhook_resend_method` - HTTP method (POST/GET)
* `webhook_selected_fields` - Event types to forward

### 2. WhatsAppWebhookN8NTransformer

**File:** `app/Transformers/WhatsAppWebhookN8NTransformer.php`

**Main Method:** `transform(array $whatsappPayload, int $tenantId): array`

**Responsibilities:**

* Detect WhatsApp event type from payload structure
* Extract message/status/account data
* Structure data in N8N-compatible format
* Add tenant information
* Include metadata for tracing

**Key Methods:**

* `detectEventType()` - Identifies the webhook event type
* `extractResourceData()` - Extracts relevant data based on event
* `getResourceType()` - Determines resource type (message, status, etc.)
* `getTenantData()` - Fetches tenant context
* `generateEventId()` - Creates unique event identifier

### 3. Webhook Configuration UI

**File:** `resources/views/livewire/tenant/settings/whats-mark/web-hooks-settings.blade.php`

**Features:**

* Toggle to enable/disable webhook forwarding
* URL input for webhook endpoint
* HTTP method selector (GET/POST)
* Event field selector with:
  * Multi-select dropdown
  * Search functionality
  * Select all/Clear all options
  * Visual tag display for selected events

***

## Configuration Guide

### Step 1: Enable Webhook Forwarding

1. **Navigate to Settings**

   * Go to: **Tenant Settings → WhatsApp → Webhooks**

2. **Enable Webhook Resend**

   * Toggle **"Enable Webhooks Resend"** to ON

3. **Configure Webhook URL**

   * Enter your N8N webhook URL or external endpoint
   * Example: `https://your-n8n-instance.com/webhook/whatsapp-events`
   * Must be a valid HTTPS URL (recommended for production)

4. **Select HTTP Method**

   * **POST** (Recommended) - Sends data in request body
   * **GET** - Sends data as query parameters
   * Other methods available for custom integrations

5. **Select Event Fields**

   * Choose which WhatsApp event types to forward:
     * `messages` - Incoming messages
     * `message_echoes` - Sent messages
     * `message_status` - Status updates (sent, delivered, read, failed)
     * `account_alerts` - Account alerts
     * `account_review_update` - Account review updates
     * `business_capability_update` - Business capability changes
     * `message_template_status_update` - Template status changes
     * `message_template_quality_update` - Template quality updates
     * `phone_number_quality_update` - Phone quality updates
     * And more...

6. **Save Configuration**

### Step 2: Set Up N8N Webhook (If using N8N)

1. **Create N8N Workflow**

   * Add a **Webhook** node as the trigger

2. **Configure Webhook Node**

   * HTTP Method: `POST`
   * Path: `/webhook/whatsapp-events` (or custom path)
   * Authentication: None (or configure based on your needs)
   * Response: Return immediately

3. **Copy Webhook URL**

   * Get the production webhook URL from N8N
   * Paste it in your WhatsApp webhook settings

4. **Activate Workflow**
   * Ensure the workflow is active to receive events

***

## N8N Format Structure

### Complete Payload Example

Based on the sample JSON you provided, here's the standardized structure:

```json
{
  "event": {
    "id": "evt_1767263928_7KGQvXqbFF",
    "type": "whatsapp.message.received",
    "timestamp": "2026-01-01T10:38:48+00:00",
    "version": "1.0"
  },
  "tenant": {
    "id": 3,
    "name": "vatsal"
  },
  "data": {
    "resource": {
      "type": "message",
      "id": "wamid.HBgMOTE5OTI1MTE5Mjg0FQIAEhgWM0VCMDE1NDRCMTFBMDQ1RTlFM0NFMwA=",
      "attributes": {
        "message_id": "wamid.HBgMOTE5OTI1MTE5Mjg0FQIAEhgWM0VCMDE1NDRCMTFBMDQ1RTlFM0NFMwA=",
        "from": "919925119284",
        "timestamp": "1767263926",
        "type": "text",
        "text": "Hello",
        "context": null
      }
    },
    "relationships": {
      "contact": {
        "wa_id": "919925119284",
        "name": "Team Corbital Technologies"
      },
      "metadata": {
        "phone_number_id": "339141689277134",
        "display_phone_number": "919428735270"
      }
    }
  },
  "whatsapp": {
    "original_payload": {
      "object": "whatsapp_business_account",
      "entry": [
        {
          "id": "315064115026195",
          "changes": [
            {
              "value": {
                "messaging_product": "whatsapp",
                "metadata": {
                  "display_phone_number": "919428735270",
                  "phone_number_id": "339141689277134"
                },
                "contacts": [
                  {
                    "profile": {
                      "name": "Team Corbital Technologies"
                    },
                    "wa_id": "919925119284"
                  }
                ],
                "messages": [
                  {
                    "from": "919925119284",
                    "id": "wamid.HBgMOTE5OTI1MTE5Mjg0FQIAEhgWM0VCMDE1NDRCMTFBMDQ1RTlFM0NFMwA=",
                    "timestamp": "1767263926",
                    "text": {
                      "body": "Hello"
                    },
                    "type": "text"
                  }
                ]
              },
              "field": "messages"
            }
          ]
        }
      ]
    }
  },
  "metadata": {
    "source": "whatsapp_webhook_forward",
    "environment": "production",
    "request_id": "595bbcf8-93bf-418b-8209-3343c76ad852"
  }
}
```

### Payload Structure Breakdown

#### 1. Event Object

Contains event metadata and identification:

```json
{
  "id": "evt_1767263928_7KGQvXqbFF", // Unique event ID
  "type": "whatsapp.message.received", // Event type
  "timestamp": "2026-01-01T10:38:48+00:00", // ISO 8601 timestamp
  "version": "1.0" // Format version
}
```

#### 2. Tenant Object

Multi-tenancy context:

```json
{
  "id": 3, // Tenant ID
  "name": "vatsal" // Tenant name/company name
}
```

#### 3. Data Object

Contains the actual event data:

##### Resource

The main entity (message, status, etc.):

```json
{
  "type": "message", // Resource type
  "id": "wamid...", // Resource ID (message ID)
  "attributes": {
    // Resource-specific data
    "message_id": "...",
    "from": "919925119284",
    "timestamp": "1767263926",
    "type": "text",
    "text": "Hello",
    "context": null
  }
}
```

##### Relationships

Related entities:

```json
{
  "contact": {
    "wa_id": "919925119284",
    "name": "Team Corbital Technologies"
  },
  "metadata": {
    "phone_number_id": "339141689277134",
    "display_phone_number": "919428735270"
  }
}
```

#### 4. WhatsApp Object

Original webhook payload from Meta:

```json
{
  "original_payload": {
    // Complete raw WhatsApp webhook data
  }
}
```

#### 5. Metadata Object

Tracking and debugging information:

```json
{
  "source": "whatsapp_webhook_forward",
  "environment": "production",
  "request_id": "595bbcf8-93bf-418b-8209-3343c76ad852"
}
```

***

## Event Types

### Supported Event Types

The transformer automatically detects and categorizes events:

#### Message Events

* `whatsapp.message.received` - Incoming message from user
* `whatsapp.message.sent` - Message sent by business (echo)
* `whatsapp.message.delivered` - Message delivered to recipient
* `whatsapp.message.read` - Message read by recipient
* `whatsapp.message.failed` - Message delivery failed

#### Status Events

* `whatsapp.status.updated` - Generic status update

#### Account Events

* `whatsapp.account.alert` - Account alert notification
* `whatsapp.account.review_updated` - Account review status changed
* `whatsapp.account.updated` - Account information updated

#### Business Events

* `whatsapp.business.capability_updated` - Business capabilities changed
* `whatsapp.business.status_updated` - Business status changed

#### Template Events

* `whatsapp.template.status_updated` - Template approval status
* `whatsapp.template.quality_updated` - Template quality score changed

#### Phone Events

* `whatsapp.phone.quality_updated` - Phone number quality changed
* `whatsapp.phone.name_updated` - Display name updated

#### Other Events

* `whatsapp.call.received` - Incoming WhatsApp call
* `whatsapp.flow.event` - Flow-related event

### Event Detection Logic

The transformer uses the following logic to detect event types:

```php
// 1. Check the 'field' from webhook changes
$field = $payload['entry'][0]['changes'][0]['field'];

// 2. Based on field and data structure:
if ($field === 'messages') {
    // Check if it's a received message
    return 'whatsapp.message.received';
}

if ($field === 'message_echoes') {
    return 'whatsapp.message.sent';
}

// 3. Check for status updates
if (isset($payload['entry'][0]['changes'][0]['value']['statuses'])) {
    $status = $statuses[0]['status'];
    // Map to specific event type
    return 'whatsapp.message.delivered|read|sent|failed';
}

// 4. Map other fields directly
return match($field) {
    'account_alerts' => 'whatsapp.account.alert',
    'calls' => 'whatsapp.call.received',
    // ... etc
};
```

***

## Implementation Details

### Core Logic Flow

#### 1. Webhook Reception (WhatsAppWebhookController)

```php
protected function processWebhookPayload()
{
    $feedData = file_get_contents('php://input');
    $payload = json_decode($feedData, true);

    // Extract business & phone number IDs
    $business_id = $payload['entry'][0]['id'];
    $phoneNumberId = $payload['entry'][0]['changes'][0]['value']['metadata']['phone_number_id'];

    // Get tenant ID from WhatsApp details
    $this->tenant_id = getTenantIdFromWhatsappDetails($business_id, $phoneNumberId);

    // Process webhook...

    // Forward webhook data if enabled
    $this->forwardWebhookData($feedData, $payload);
}
```

#### 2. Forward Decision Making

```php
protected function forwardWebhookData(string $feedData, array $payload)
{
    // 1. Get tenant settings
    $enabled = get_tenant_setting_by_tenant_id('whats-mark', 'enable_webhook_resend', '', $this->tenant_id);
    $url = get_tenant_setting_by_tenant_id('whats-mark', 'whatsapp_data_resend_to', '', $this->tenant_id);
    $method = get_tenant_setting_by_tenant_id('whats-mark', 'webhook_resend_method', 'POST', $this->tenant_id);

    // 2. Extract fields from webhook
    $fields = collect($payload['entry'] ?? [])
        ->flatMap(fn($entry) => collect($entry['changes'] ?? []))
        ->pluck('field')
        ->filter()
        ->unique();

    // 3. Get enabled fields from settings
    $enabled_fields = collect(get_tenant_setting_by_tenant_id('whats-mark', 'webhook_selected_fields', [], $this->tenant_id));

    // 4. Check if field is allowed
    $isFieldAllowed = $fields->intersect($enabled_fields)->isNotEmpty();

    if (!$isFieldAllowed) {
        whatsapp_log('Webhook Forward Skipped', 'info', [
            'reason' => 'No enabled fields found for resend',
            'fields' => $fields,
        ]);
        return;
    }

    // 5. Proceed with forwarding...
}
```

#### 3. Data Transformation

```php
// Transform to N8N format
$n8nPayload = \App\Transformers\WhatsAppWebhookN8NTransformer::transform(
    $payload,
    $this->tenant_id
);
```

#### 4. Signature Generation

```php
// Generate HMAC-SHA256 signature
$secret = config('ApiWebhookManager.signing_secret', config('app.key'));
$signature = hash_hmac('sha256', json_encode($n8nPayload), $secret);
```

#### 5. HTTP Request

```php
$headers = [
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'User-Agent' => 'whatsmark-Webhook/1.0',
    'X-Webhook-Signature' => $signature,
    'X-Webhook-Event' => $n8nPayload['event']['type'] ?? 'unknown',
    'X-Webhook-Timestamp' => now()->toIso8601String(),
    'X-Webhook-Format' => 'n8n',
];

switch ($method) {
    case 'POST':
        $response = \Http::withHeaders($headers)->post($url, $n8nPayload);
        break;
    case 'GET':
        $response = \Http::withHeaders($headers)->get($url, $n8nPayload);
        break;
    default:
        $response = \Http::withHeaders($headers)
            ->withBody(json_encode($n8nPayload), 'application/json')
            ->send($method, $url);
        break;
}
```

#### 6. Logging

```php
whatsapp_log('Webhook Forwarded (N8N Format)', 'info', [
    'url' => $url,
    'method' => $method,
    'event_type' => $n8nPayload['event']['type'] ?? 'unknown',
    'status_code' => $response->status(),
    'success' => $response->successful(),
]);
```

***

## Security Features

### 1. Signature Verification

Every forwarded webhook includes a signature for verification:

```php
// Generation (in application)
$secret = config('ApiWebhookManager.signing_secret', config('app.key'));
$signature = hash_hmac('sha256', json_encode($payload), $secret);
```

**Verification Example (in N8N or receiving endpoint):**

```javascript
// 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)
  );
}

// In your webhook handler
const signature = req.headers['x-webhook-signature'];
const isValid = verifySignature(
  req.body,
  signature,
  process.env.WEBHOOK_SECRET
);

if (!isValid) {
  return res.status(403).send('Invalid signature');
}
```

### 2. Custom Headers

Every request includes identifying headers:

```
X-Webhook-Signature: <hmac-sha256-signature>
X-Webhook-Event: whatsapp.message.received
X-Webhook-Timestamp: 2026-01-01T10:38:48+00:00
X-Webhook-Format: n8n
User-Agent: whatsmark-Webhook/1.0
```

### 3. URL Validation

```php
if ($enabled && filter_var($url, FILTER_VALIDATE_URL)) {
    // Only proceed if URL is valid
}
```

### 4. Duplicate Prevention

The controller checks for duplicate message processing:

```php
$message_id = $payload['entry'][0]['changes'][0]['value']['messages'][0]['id'] ?? '';
if (!empty($message_id)) {
    $found = $this->checkMessageProcessed($message_id);
    if ($found) {
        whatsapp_log('Duplicate Message Detected', 'warning', ['message_id' => $message_id]);
        return;
    }
}
```

### 5. Tenant Isolation

All settings and data are tenant-specific:

```php
$enabled = get_tenant_setting_by_tenant_id('whats-mark', 'enable_webhook_resend', '', $this->tenant_id);
```

***

## Troubleshooting

### Webhooks Not Being Forwarded

**Check 1: Verify Settings**

```php
// Check if forwarding is enabled
get_tenant_setting_by_tenant_id('whats-mark', 'enable_webhook_resend', '', $tenant_id);

// Verify URL is configured
get_tenant_setting_by_tenant_id('whats-mark', 'whatsapp_data_resend_to', '', $tenant_id);
```

**Check 2: Field Filtering**

* Ensure the event field is in the selected fields list
* Check logs: "Webhook Forward Skipped - No enabled fields found"

**Check 3: URL Validity**

* Must be a valid URL format
* HTTPS recommended for production
* Check for typos in configuration

### N8N Not Receiving Data

**Check 1: N8N Workflow Status**

* Ensure workflow is activated
* Check webhook node configuration
* Verify path matches configuration

**Check 2: Firewall/Network**

* Check if N8N endpoint is accessible
* Test with curl:

```bash
curl -X POST https://your-n8n.com/webhook/test \
  -H "Content-Type: application/json" \
  -d '{"test": "data"}'
```

**Check 3: Response Status**

* Check application logs for response status
* Look for "Webhook Forwarded" log entries

### Signature Verification Failing

**Issue:** Signature mismatch in receiving endpoint

**Solution:**

1. Ensure secret matches on both sides
2. Verify you're computing signature on the same payload
3. Check that payload hasn't been modified in transit
4. Use `json_encode($payload)` exactly as sent

### Logs to Check

```bash
# Check webhook forward logs
php artisan tinker
>>> \DB::table('whatsapp_logs')->where('title', 'like', '%Webhook Forward%')->latest()->get();

# Check for skipped webhooks
>>> \DB::table('whatsapp_logs')->where('title', 'Webhook Forward Skipped')->latest()->get();

# Check for errors
>>> \DB::table('whatsapp_logs')->where('title', 'Webhook Forward Error')->latest()->get();
```

***

## Code References

### Primary Files

1. **Controller Logic**

   * File: `app/Http/Controllers/Whatsapp/WhatsAppWebhookController.php`
   * Method: `forwardWebhookData()` (lines 820-900)
   * Handles: Settings retrieval, field filtering, HTTP forwarding

2. **Transformer Logic**

   * File: `app/Transformers/WhatsAppWebhookN8NTransformer.php`
   * Method: `transform()` (lines 1-315)
   * Handles: Event detection, data extraction, N8N formatting

3. **Configuration UI**

   * File: `resources/views/livewire/tenant/settings/whats-mark/web-hooks-settings.blade.php`
   * Handles: User interface for webhook configuration

4. **Admin Configuration**
   * File: `resources/views/livewire/admin/whats-app/webhook-configuration.blade.php`
   * Handles: Admin-level webhook settings

### Related Files

* `Modules/ApiWebhookManager/Config/config.php` - Webhook config
* `Modules/ApiWebhookManager/Enums/WebhookEventType.php` - Event type definitions
* `Modules/ApiWebhookManager/Services/WebhookService.php` - Webhook service utilities

### Configuration Keys

```php
// Settings keys used:
'whats-mark.enable_webhook_resend'      // Boolean: Enable forwarding
'whats-mark.whatsapp_data_resend_to'    // String: Webhook URL
'whats-mark.webhook_resend_method'      // String: HTTP method (POST/GET)
'whats-mark.webhook_selected_fields'    // Array: Enabled event fields
```

### Database Tables

```sql
-- Settings stored in:
settings (tenant-specific settings)

-- Logs stored in:
whatsapp_logs (webhook forward logs)
```

***

## Example N8N Workflow

### Basic Workflow Structure

```

  Webhook Node    (Trigger)
  (POST)




 Function Node    (Verify Signature)





  Switch Node     (Route by event.type)



          whatsapp.message.received
                 Save to DB / Send Notification

          whatsapp.message.delivered
                 Update message status

          Other event types...
```

### Signature Verification (Function Node)

```javascript
// items[0].json contains the webhook payload
const payload = items[0].json;
const signature = $node['Webhook'].context['headers']['x-webhook-signature'];
const secret = 'your-secret-key-here'; // Or from environment

const crypto = require('crypto');
const expectedSignature = crypto
  .createHmac('sha256', secret)
  .update(JSON.stringify(payload))
  .digest('hex');

if (signature !== expectedSignature) {
  throw new Error('Invalid signature');
}

return items;
```

### Event Routing (Switch Node)

```javascript
// Route based on event type
return [
  payload.event.type === 'whatsapp.message.received' ? 0 : -1,
  payload.event.type === 'whatsapp.message.delivered' ? 0 : -1,
  payload.event.type === 'whatsapp.message.read' ? 0 : -1,
  // ... other event types
];
```

***

## Best Practices

### 1. Selective Event Forwarding

* Only forward events you actually need
* Reduces bandwidth and processing overhead
* Easier to debug and maintain

### 2. Error Handling

* Implement retry logic in N8N for failed webhooks
* Monitor webhook forward logs regularly
* Set up alerts for high error rates

### 3. Security

* Always use HTTPS endpoints
* Implement signature verification
* Rotate secrets periodically
* Restrict webhook endpoint access

### 4. Performance

* Use asynchronous processing in N8N when possible
* Avoid long-running operations in webhook handlers
* Consider queuing for heavy processing

### 5. Testing

* Test webhook forwarding in development first
* Use N8N's test webhook feature
* Verify all event types you need
* Check signature verification works

### 6. Monitoring

* Log all webhook forwards
* Track success/failure rates
* Monitor response times
* Set up alerts for issues

***

## Migration Notes

### From Previous Version (If Applicable)

If migrating from an older webhook system:

1. **Settings Migration**: Old settings may need to be converted
2. **Event Field Mapping**: Ensure field names match new structure
3. **Signature Method**: Update signature verification if changed
4. **Testing**: Thoroughly test all event types after migration

***

## Support & References

### Additional Documentation

* [WHATSAPP_N8N_WEBHOOK_GUIDE.md](/products/whatsmark-saas/integrations/n8n-webhook-integration) - Comprehensive N8N integration guide
* [WHATSAPP_N8N_WEBHOOK_REFERENCE.md](/products/whatsmark-saas/integrations/webhook-format-reference) - Quick reference for event types and payload structure

### Commits Reference

* Main implementation: `74a9907c` - "feat: Implement WhatsApp Webhook Transformer for N8N integration"
* Enhancements: `984b8440` - "Enhance multi-tenancy support and improve webhook processing"

### Related Features

* **ApiWebhookManager Module** - Generic webhook management
* **Multi-tenancy** - Tenant-specific webhook configurations
* **WhatsApp Integration** - Core WhatsApp Business API integration

***

## Changelog

### Version 1.6.0 (Current)

* N8N format transformer implemented
* Multi-tenant webhook forwarding
* Signature verification
* Selective event field filtering
* Comprehensive logging
* Admin and tenant configuration UI

### Future Enhancements (Planned)

* \[ ] Webhook retry mechanism
* \[ ] Webhook forward queue for reliability
* \[ ] Webhook analytics dashboard
* \[ ] Custom transformation templates
* \[ ] Webhook event batching
* \[ ] Webhook rate limiting

***

## Summary

The WhatsApp Webhook Forwarding feature provides a robust, secure, and flexible way to integrate WhatsApp events with external automation systems like N8N. With its standardized format, comprehensive event coverage, and tenant-specific configuration, it enables powerful automation workflows while maintaining security and multi-tenancy support.

**Key Benefits:**

* Easy integration with N8N and other webhook consumers
* Secure with signature verification
* Selective event forwarding for efficiency
* Multi-tenant support
* Comprehensive logging and debugging
* Flexible configuration per tenant

For questions or issues, refer to the application logs or contact the development team.
