> ## Documentation Index
> Fetch the complete documentation index at: https://docs.digifist.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks Reference

> Complete payload reference for all Shopify and Meta webhooks registered and received by Galantis.

This page is the authoritative payload reference for every webhook Galantis registers with Shopify and every webhook event it receives from Meta. It covers the topic, the expected payload structure, and what the webhook drives in Galantis.

For the processing behavior and downstream effects of each webhook, see [Integrations — Shopify Webhooks](/whatsapp/integrations/shopify/webhooks) and [Integrations — Meta Webhooks](/whatsapp/integrations/meta-whatsapp/meta-webhooks). This page focuses on payload structure for developer reference.

## Security

**Shopify webhooks** — All incoming Shopify webhooks are validated via HMAC signature verification using the `X-Shopify-Hmac-Sha256` header before processing. Requests with invalid or missing signatures are rejected with a `401` response and never reach the handler.

**Meta webhooks** — All incoming Meta webhooks are validated via signature verification using the `X-Hub-Signature-256` header before processing. Invalid signatures are rejected.

Both verifications use the app secret for their respective platform. Webhook payloads are never processed without a valid signature.

***

## Shopify webhooks

### Customer webhooks

**`customers/create`**

```json theme={null}
{
  "id": 123456789,
  "email": "customer@example.com",
  "first_name": "Jane",
  "last_name": "Smith",
  "phone": "+521234567890",
  "tags": "vip, newsletter",
  "accepts_marketing": true,
  "email_marketing_consent": {
    "state": "subscribed",
    "opt_in_level": "single_opt_in"
  },
  "sms_marketing_consent": {
    "state": "subscribed",
    "opt_in_level": "single_opt_in"
  },
  "locale": "es",
  "created_at": "2025-01-15T10:00:00-05:00",
  "updated_at": "2025-01-15T10:00:00-05:00"
}
```

***

**`customers/update`**

Same structure as `customers/create`. All fields are included in the payload — Galantis diffs the incoming data against the stored record to identify changes.

***

**`customers/delete`**

```json theme={null}
{
  "id": 123456789
}
```

Only the customer ID is included. Galantis uses the ID to locate and remove the corresponding contact record.

***

**`customers/marketing_consent_updated`**

```json theme={null}
{
  "id": 123456789,
  "email_marketing_consent": {
    "state": "subscribed",
    "opt_in_level": "single_opt_in",
    "consent_updated_at": "2025-01-15T10:05:00-05:00"
  },
  "sms_marketing_consent": {
    "state": "subscribed",
    "opt_in_level": "single_opt_in",
    "consent_updated_at": "2025-01-15T10:05:00-05:00"
  },
  "phone": "+521234567890",
  "updated_at": "2025-01-15T10:05:00-05:00"
}
```

Galantis maps the SMS/phone marketing consent state to the corresponding internal consent status on the contact record.

***

**`customer_tags/added`**

```json theme={null}
{
  "customer_id": 123456789,
  "tags_added": ["vip", "loyalty-gold"]
}
```

***

**`customer_tags/removed`**

```json theme={null}
{
  "customer_id": 123456789,
  "tags_removed": ["loyalty-silver"]
}
```

***

### Order webhooks

**`orders/create`**

```json theme={null}
{
  "id": 987654321,
  "order_number": 1042,
  "customer": {
    "id": 123456789,
    "phone": "+521234567890"
  },
  "total_price": "149.00",
  "currency": "MXN",
  "line_items": [
    {
      "id": 111111,
      "title": "Running Shoes",
      "quantity": 1,
      "price": "149.00",
      "product_id": 555555,
      "variant_id": 666666,
      "vendor": "NikeMX",
      "properties": []
    }
  ],
  "tags": "",
  "fulfillment_status": null,
  "financial_status": "paid",
  "created_at": "2025-01-15T11:00:00-05:00"
}
```

***

**`orders/cancelled`**

Same structure as `orders/create` with `cancelled_at` and `cancel_reason` fields added:

```json theme={null}
{
  "id": 987654321,
  "order_number": 1042,
  "customer": { "id": 123456789 },
  "total_price": "149.00",
  "cancelled_at": "2025-01-16T09:00:00-05:00",
  "cancel_reason": "customer"
}
```

***

**`orders/updated`** (used for shipping)

```json theme={null}
{
  "id": 987654321,
  "order_number": 1042,
  "customer": { "id": 123456789 },
  "fulfillment_status": "fulfilled",
  "fulfillments": [
    {
      "id": 222222,
      "status": "success",
      "tracking_company": "DHL",
      "tracking_number": "1234567890",
      "tracking_url": "https://track.dhl.com/...",
      "created_at": "2025-01-16T14:00:00-05:00"
    }
  ]
}
```

Galantis interprets `orders/updated` payloads to drive the relevant automation triggers (for example, `ORDER_SHIPPED` when fulfillment data indicates a successful shipment). See [Automations — triggers](/galantis/whatsapp/automations/triggers) for the available triggers.

***

### Product and collection webhooks

**`products/create`**

```json theme={null}
{
  "id": 555555,
  "title": "Running Shoes",
  "body_html": "<p>Full product description...</p>",
  "vendor": "NikeMX",
  "tags": "shoes, running, sport",
  "images": [
    { "id": 777777, "src": "https://cdn.shopify.com/...", "width": 1000, "height": 1000 }
  ],
  "variants": [
    {
      "id": 666666,
      "title": "Size 42 / Blue",
      "price": "149.00",
      "compare_at_price": "180.00",
      "sku": "RUN-42-BLU",
      "inventory_quantity": 15,
      "option1": "42",
      "option2": "Blue",
      "image_id": 777777
    }
  ],
  "options": [
    { "name": "Size", "values": ["40", "41", "42", "43"] },
    { "name": "Color", "values": ["Blue", "Black", "White"] }
  ],
  "status": "active",
  "created_at": "2025-01-15T09:00:00-05:00"
}
```

***

**`products/update`**

Same structure as `products/create`. Galantis processes the full payload — updated fields overwrite stored values, and `inventory_quantity` changes are checked for the 0→>0 Back-in-Stock restock pattern.

***

**`products/delete`**

```json theme={null}
{
  "id": 555555
}
```

***

**`collections/create`**, **`collections/update`**

```json theme={null}
{
  "id": 888888,
  "title": "Running Gear",
  "handle": "running-gear",
  "products_count": 24,
  "updated_at": "2025-01-15T12:00:00-05:00"
}
```

***

**`collections/delete`**

```json theme={null}
{
  "id": 888888
}
```

***

### Billing and app lifecycle webhooks

**`app_subscriptions/update`**

```json theme={null}
{
  "app_subscription": {
    "admin_graphql_api_id": "gid://shopify/AppSubscription/123",
    "name": "Galantis Pro Plan",
    "status": "ACTIVE",
    "created_at": "2025-01-01T00:00:00Z",
    "updated_at": "2025-01-15T00:00:00Z",
    "currency": "USD"
  }
}
```

***

**`app/uninstalled`**
Handler: Tenant deactivation

```json theme={null}
{
  "id": 12345678,
  "myshopify_domain": "your-store.myshopify.com"
}
```

***

### GDPR webhooks

**`customers/redact`**

```json theme={null}
{
  "shop_id": 12345678,
  "shop_domain": "your-store.myshopify.com",
  "customer": {
    "id": 123456789,
    "email": "customer@example.com",
    "phone": "+521234567890"
  },
  "orders_to_redact": [987654321, 987654322]
}
```

***

**`shop/redact`**

```json theme={null}
{
  "shop_id": 12345678,
  "shop_domain": "your-store.myshopify.com"
}
```

***

## Meta webhooks

**`messages` (inbound)**

```json theme={null}
{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "{waba_id}",
    "changes": [{
      "value": {
        "messaging_product": "whatsapp",
        "metadata": {
          "display_phone_number": "521234567890",
          "phone_number_id": "{phone_number_id}"
        },
        "contacts": [{
          "profile": { "name": "Jane Smith" },
          "wa_id": "521234567890"
        }],
        "messages": [{
          "from": "521234567890",
          "id": "wamid.{message_id}",
          "timestamp": "1705320000",
          "type": "text",
          "text": { "body": "Hello, I have a question about my order" }
        }]
      },
      "field": "messages"
    }]
  }]
}
```

For `QUICK_REPLY` button responses, the `messages[0].type` is `"interactive"` and the payload includes:

```json theme={null}
"interactive": {
  "type": "button_reply",
  "button_reply": {
    "id": "{button_id}",
    "title": "{button_label}"
  }
}
```

***

**`message_status` (status update)**

```json theme={null}
{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "{waba_id}",
    "changes": [{
      "value": {
        "messaging_product": "whatsapp",
        "metadata": {
          "display_phone_number": "521234567890",
          "phone_number_id": "{phone_number_id}"
        },
        "statuses": [{
          "id": "wamid.{message_id}",
          "status": "delivered",
          "timestamp": "1705320030",
          "recipient_id": "521234567890"
        }]
      },
      "field": "messages"
    }]
  }]
}
```

`"status"` values: `"sent"`, `"delivered"`, `"read"`, `"played"`, `"failed"`.

For `"failed"` status, an `"errors"` array is included:

```json theme={null}
"errors": [{
  "code": 131047,
  "title": "Re-engagement message",
  "message": "Message failed to send because more than 24 hours have passed since the customer last replied to this number.",
  "error_data": { "details": "..." }
}]
```

***

**`message_template_status_update`**

```json theme={null}
{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "{waba_id}",
    "changes": [{
      "value": {
        "event": "APPROVED",
        "message_template_id": 123456,
        "message_template_name": "order_confirmation_es",
        "message_template_language": "es",
        "reason": null
      },
      "field": "message_template_status_update"
    }]
  }]
}
```

`"event"` values: `"APPROVED"`, `"REJECTED"`, `"PAUSED"`, `"DISABLED"`.

For `"REJECTED"`, the `"reason"` field contains Meta's rejection explanation.

***

## Related guides

* [Integrations — Shopify webhooks](/galantis/whatsapp/integrations/shopify/webhooks) — Processing behavior and downstream effects
* [Integrations — Meta webhooks](/galantis/whatsapp/integrations/meta-whatsapp/meta-webhooks) — Processing behavior for Meta webhook events
* [Automations — triggers](/galantis/whatsapp/automations/triggers) — Which webhook events drive which automation triggers
