# Complete Guide: Setting Up Cloudflare Tunnels & Webhook Integration

This document outlines the step-by-step process of creating a public tunnel in the **Cloudflare Zero Trust Portal**, routing traffic to your backend, and how WooCommerce and WhatsApp webhooks are automatically integrated.

---

## Architecture Overview

```
+-------------------------------------------------------------+
|                     EXTERNAL SERVICES                       |
|   WooCommerce Store                WhatsApp / Meta API      |
|   (Orders, Products)               (Customer Carts, DMs)    |
+------------------------------+------------------------------+
                               |
                               v (HTTPS Webhooks)
+-------------------------------------------------------------+
|                  CLOUDFLARE ZERO TRUST                      |
|                  Public Domain / Tunnel                     |
|           https://api.yourdomain.com                        |
+------------------------------+------------------------------+
                               |
                               | (Secure Cloudflared Tunnel)
                               v
+-------------------------------------------------------------+
|                     LOCAL / HOST SERVER                     |
|                                                             |
|   Cloudflared Connector Agent                               |
|   Routes to -> http://localhost:8002                        |
|                                                             |
|   Docker Container: whatsapp_commerce_backend               |
|     • /webhooks/woocommerce/orders?businessId=...           |
|     • /webhooks/woocommerce/products?businessId=...         |
|     • /webhooks/whatsapp                                    |
|     • /webhooks/payments/pesepay                            |
+-------------------------------------------------------------+
```

---

## Part 1: Setting Up the Tunnel in the Cloudflare Portal

Follow these steps in the Cloudflare online dashboard:

### Step 1: Open Cloudflare Zero Trust
1. Log in to [Cloudflare Dashboard](https://dash.cloudflare.com/).
2. On the left sidebar, click **Zero Trust** (or navigate directly to [one.dash.cloudflare.com](https://one.dash.cloudflare.com/)).

### Step 2: Create a New Tunnel
1. In the Zero Trust dashboard, expand **Networks** on the left menu.
2. Click **Tunnels**.
3. Click the blue **Add a tunnel** button.
4. Select connector type: **Cloudflared** and click **Next**.
5. Give your tunnel a descriptive name (e.g., `whatsapp-commerce-tunnel`) and click **Save tunnel**.

### Step 3: Install & Run the Connector on Your Server
Cloudflare will display an installation command with your unique tunnel token for various operating systems.

- **Option A: Linux (systemd service - Recommended for persistent servers)**
  ```bash
  curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
  sudo dpkg -i cloudflared.deb
  sudo cloudflared service install <YOUR_TUNNEL_TOKEN>
  ```

- **Option B: Docker Compose**
  You can add `cloudflared` directly into your `docker-compose.yml`:
  ```yaml
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared_tunnel
    restart: always
    command: tunnel --no-autoupdate run --token <YOUR_TUNNEL_TOKEN>
  ```

Once installed, the status in the Cloudflare portal will turn green: **Connected**. Click **Next**.

### Step 4: Configure the Public Hostname (Routing)
In the **Public Hostname** tab:

1. **Public Hostname**:
   - **Subdomain**: `api` (or any subdomain of your choice)
   - **Domain**: Choose your active Cloudflare domain (e.g., `yourdomain.com`)
   - **Path**: Leave blank

2. **Service**:
   - **Type**: `HTTP`
   - **URL**: `localhost:8002` (or `127.0.0.1:8002` depending on your host port mapping)

3. **Additional Application Settings (Optional)**:
   - Under **TLS**, if your local service uses plain HTTP (standard for internal backend ports), leave **No TLS Verify** off.
   - Under **HTTP Settings**, keep standard timeouts.

4. Click **Save hostname**.

> Cloudflare will automatically provision an SSL certificate. Your backend is now securely reachable over the internet at `https://api.yourdomain.com`.

---

## Part 2: Backend Environment Variables

Once your Cloudflare tunnel domain is active, configure your backend environment variables (`.env` or `docker-compose.yml`) to tell the server its public domain:

```env
PORT=3001
PUBLIC_URL=https://api.yourdomain.com
BACKEND_URL=https://api.yourdomain.com
FRONTEND_URL=https://api.yourdomain.com
```

---

## Part 3: Webhook Endpoints & URLs

The WhatsApp Commerce Hub exposes the following webhook endpoints:

| Integration | Endpoint URL | Topics / Events Handled |
| :--- | :--- | :--- |
| **WooCommerce Orders** | `https://api.yourdomain.com/webhooks/woocommerce/orders?businessId=<ID>` | `order.created`, `order.updated` |
| **WooCommerce Products** | `https://api.yourdomain.com/webhooks/woocommerce/products?businessId=<ID>` | `product.created`, `product.updated`, `product.deleted` |
| **Meta WhatsApp API** | `https://api.yourdomain.com/webhooks/whatsapp` | Inbound text messages, native catalog carts, message receipts |
| **PesePay Gateway** | `https://api.yourdomain.com/webhooks/payments/pesepay` | Transaction confirmations, EcoCash/Card payment updates |

---

## Part 4: How Automatic Webhook Registration Works (In the Background)

When a merchant connects their store in the Hub dashboard (by entering Store Domain URL, Consumer Key, and Consumer Secret):

1. **Automatic Detection:** The backend detects the server's public domain (`https://api.yourdomain.com`) without asking the user to manually type anything.
2. **WooCommerce REST API Registration:** The backend makes authenticated calls to the store:
   - `GET /wp-json/wc/v3/webhooks`
   - Deletes any old or outdated webhooks pointing to expired URLs.
   - Registers all 5 webhooks:
     1. `WhatsApp Commerce Hub - Order Created` (`order.created`)
     2. `WhatsApp Commerce Hub - Order Updated` (`order.updated`)
     3. `WhatsApp Commerce Hub - Product Created` (`product.created`)
     4. `WhatsApp Commerce Hub - Product Updated` (`product.updated`)
     5. `WhatsApp Commerce Hub - Product Deleted` (`product.deleted`)
3. **Ping Handshake:** WooCommerce sends an initial verification ping (`{"webhook_id": ...}`). The backend acknowledges this ping with `HTTP 200 OK` to confirm the webhook is active.
4. **Instant Sync:** Whenever a product is added or an order changes status in WooCommerce, WooCommerce sends a POST request through Cloudflare directly to your backend.

---

## Part 5: Manual Webhook Setup in WooCommerce (Fallback / Verification)

If you ever need to manually verify or configure webhooks in WordPress:

1. Log in to your WordPress Admin dashboard.
2. Go to **WooCommerce** > **Settings**.
3. Click the **Advanced** tab at the top.
4. Click **Webhooks** (just below the tabs).
5. Click **Add webhook**.
6. Fill in the details:
   - **Name**: `WhatsApp Commerce Hub - Product Updated`
   - **Status**: Change from *Disabled* to **Active**
   - **Topic**: Select **Product updated**
   - **Delivery URL**: `https://api.yourdomain.com/webhooks/woocommerce/products?businessId=<YOUR_BUSINESS_ID>`
   - **Secret**: Leave blank
   - **API Version**: `WP REST API Integration v3`
7. Click **Save webhook**.
8. Repeat for:
   - `Product created`
   - `Product deleted`
   - `Order created` (URL: `.../webhooks/woocommerce/orders?businessId=...`)
   - `Order updated` (URL: `.../webhooks/woocommerce/orders?businessId=...`)

---

## Part 6: How the WhatsApp Chatbot Matches Catalog Orders

When a customer orders from the **WhatsApp Catalog**:
1. WhatsApp sends an order payload containing a `product_retailer_id` (e.g., `"236"`).
2. The backend resolves the product using a tiered fallback strategy:
   - **Tier 1:** Match by WooCommerce Product ID (`externalProductId`).
   - **Tier 2:** Match by SKU.
   - **Tier 3:** Match by Product Variant ID (`externalVariantId`).
   - **Tier 4 (Meta Catalog Real-Time Lookup):** If the ID does not match the database directly, the backend queries the Meta Graph API (`https://graph.facebook.com/v19.0/<CATALOG_ID>/products?filter={"retailer_id":{"eq":"<ID>"}}`). It retrieves the product name and price, finds the matching item in your store, selects the correct weight/variant, and places it into the WhatsApp shopping cart.
