Outbound Webhooks

While the REST API allows you to pull data or push messages, Webhooks allow Wamebo to push real-time events (like new messages or completed orders) directly to your external servers the moment they happen.

Configuration

You can configure your Webhook Endpoint URL and subscribe to specific events from your dashboard under Settings > App Integrations > Webhooks. You will be provided with a Signing Secret to verify incoming requests.

Security & Signature Verification

To ensure that incoming webhooks are genuinely originating from Wamebo and have not been tampered with, every payload includes an X-Webhook-Signature header. This is an HMAC SHA-256 hash of the raw JSON body generated using your Signing Secret.

<?php
// 1. Grab your secret from the Wamebo Dashboard
$signingSecret = 'wh_sec_your_super_secret_string';

// 2. Read the raw payload and the signature header
$payload = file_get_contents('php://input');
$signatureHeader = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

// The header format is usually: sha256=a1b2c3d4e5f6...
$expectedSignature = str_replace('sha256=', '', $signatureHeader);

// 3. Generate the HMAC hash
$calculatedSignature = hash_hmac('sha256', $payload, $signingSecret);

// 4. Use hash_equals to prevent timing attacks
if (hash_equals($calculatedSignature, $expectedSignature)) {
    // Verified! Process the event.
    http_response_code(200);
    echo "Verified";
} else {
    // Spoofed request. Reject.
    http_response_code(403);
    echo "Invalid Signature";
}
?>
const crypto = require('crypto');
const express = require('express');
const app = express();

const SIGNING_SECRET = 'wh_sec_your_super_secret_string';

// Ensure you get the raw body for signature verification
app.use(express.json({
    verify: (req, res, buf) => { req.rawBody = buf; }
}));

app.post('/webhook', (req, res) => {
    const signatureHeader = req.headers['x-webhook-signature'];
    const expectedSignature = signatureHeader.replace('sha256=', '');
    
    const calculatedSignature = crypto
        .createHmac('sha256', SIGNING_SECRET)
        .update(req.rawBody)
        .digest('hex');

    // Use timingSafeEqual to prevent timing attacks
    if (crypto.timingSafeEqual(Buffer.from(calculatedSignature), Buffer.from(expectedSignature))) {
        // Verified!
        res.status(200).send('Verified');
    } else {
        res.status(403).send('Invalid Signature');
    }
});

Incoming Messages

Fired immediately when a customer sends a message to your WhatsApp Business number. Triggered by message.received.

Payload Example
{
  "event": "message.received",
  "timestamp": "2026-05-27T10:15:00Z",
  "data": {
    "message_id": 10452,
    "contact": {
      "id": 8502,
      "name": "Jane Doe",
      "phone_number": "919876543210"
    },
    "message": {
      "type": "text",
      "body": "Hi, do you have this in stock?",
      "direction": "incoming"
    }
  }
}

E-Commerce Orders

Fired when a customer completes the checkout flow directly inside WhatsApp using your synced Meta Catalog. Use this event to push the order into WooCommerce, Shopify, or your ERP. Triggered by order.created.

Payload Example
{
  "event": "order.created",
  "timestamp": "2026-05-27T14:30:22Z",
  "data": {
    "order_id": 5542,
    "meta_order_id": "wamid.HBgLOTE...",
    "customer": {
      "name": "Michael Smith",
      "phone_number": "15551234567"
    },
    "financials": {
      "total_amount": 250.00,
      "currency": "USD"
    },
    "items": [
      {
        "sku": "PROD-A1",
        "quantity": 2,
        "unit_price": 100.00
      },
      {
        "sku": "PROD-B2",
        "quantity": 1,
        "unit_price": 50.00
      }
    ]
  }
}

Retry Policy

Your webhook endpoint must return a 2XX HTTP Status Code (e.g., 200 OK) within 3 seconds to acknowledge receipt. If your server returns an error (4XX or 5XX), or if the request times out, Wamebo will attempt to resend the payload up to 3 times over the next 24 hours using exponential backoff.