# Webhook - Monitoring Notifications

#### Managing Webhook Endpoints

* Webhook endpoints are created and deleted by PayShield **upon request** (contact your PayShield Account Manager)
* Only **one** webhook endpoint is supported per account

**Get Webhook Details**

```bash
curl -X GET {baseurl}/api/v1/user-webhooks/{id} \
  -H "Authorization: Bearer <token>"
```

**Update Webhook**

```bash
curl -X PATCH {baseurl}/api/v1/user-webhooks/{id} \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/new-endpoint",
    "enabled": true
  }'
```

**Regenerate Secret**

If your webhook secret is compromised, regenerate it immediately:

```bash
curl -X POST {baseurl}/api/v1/user-webhooks/{id}/regenerate-secret \
  -H "Authorization: Bearer <token>"
```

**Response:**

```json
{
  "message": "Webhook secret regenerated successfully",
  "warning": "Store the new secret securely. It will not be shown again.",
  "data": {
    "secret": "whsec_new123..."
  }
}
```

#### Webhook Payload Format

All webhook events follow this structure:

```json
{
  "event": "business-closed",
  "description": "Business appears to be closed based on verification data",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "domainId": "550e8400-e29b-41d4-a716-446655440000",
    "domain": "example.com",
    "status": "active",
    "provider": "truebiz"
  }
}
```

**Payload Fields**

| Field           | Type          | Required | Description                                                                                                      |
| --------------- | ------------- | -------- | ---------------------------------------------------------------------------------------------------------------- |
| `event`         | string        | Yes      | The event type that triggered this webhook (e.g., `business-closed`, `sentiment`, `website`, `business-profile`) |
| `description`   | string        | No       | Human-readable description of the event (may be `null`)                                                          |
| `timestamp`     | string        | Yes      | ISO 8601 timestamp when the event occurred                                                                       |
| `data`          | object        | Yes      | Event-specific data                                                                                              |
| `data.domainId` | string (UUID) | Yes      | UUID of the domain associated with this event                                                                    |
| `data.domain`   | string        | Yes      | The domain name                                                                                                  |
| `data.status`   | string        | Yes      | Current domain status (`active` or `inactive`)                                                                   |
| `data.provider` | string        | Yes      | The provider that triggered this event (e.g., `truebiz`)                                                         |

#### Webhook Delivery Logs

Monitor webhook deliveries to debug issues and track reliability.

**View Deliveries for Specific Endpoint**

```bash
curl -X GET "{baseurl}/api/v1/user-webhooks/{id}/deliveries?limit=50" \
  -H "Authorization: Bearer <token>"
```

**List All Delivery Logs**

View deliveries across all webhook endpoints:

```bash
curl -X GET "{baseurl}/api/v1/user-webhooks/deliveries?status=failed&limit=100" \
  -H "Authorization: Bearer <token>"
```

**Query Parameters:**

| Parameter  | Type              | Default | Description                                                                     |
| ---------- | ----------------- | ------- | ------------------------------------------------------------------------------- |
| `page`     | integer           | 1       | Page number (min: 1)                                                            |
| `limit`    | integer           | 100     | Items per page (min: 1, max: 1000)                                              |
| `status`   | string            | -       | Filter by status: `pending`, `success`, `failed`, `retrying`                    |
| `userId`   | string (UUID)     | -       | Filter by user ID (superadmin/reseller only)                                    |
| `domainId` | string (UUID)     | -       | Filter by domain ID                                                             |
| `dateFrom` | string (ISO 8601) | -       | Filter deliveries from this date (e.g., `2025-01-01` or `2025-01-01T00:00:00Z`) |
| `dateTo`   | string (ISO 8601) | -       | Filter deliveries until this date (must be >= `dateFrom`)                       |

**Delivery Status Values**

| Status     | Description                           |
| ---------- | ------------------------------------- |
| `pending`  | Delivery queued but not yet sent      |
| `success`  | Delivered successfully (2xx response) |
| `failed`   | All retry attempts failed             |
| `retrying` | Delivery failed, will retry           |

***

#### Webhook Retry Policy

Failed webhook deliveries are automatically retried:

* **Retry attempts:** 3 attempts total
* **Retry schedule:**
  * 1st retry: After 1 minute
  * 2nd retry: After 5 minutes
  * 3rd retry: After 15 minutes
* **Timeout:** 10 seconds per delivery attempt
* **Success criteria:** Any 2xx HTTP response code

***

#### Webhook Security

All webhook requests include a cryptographic signature that you **must verify** to ensure authenticity.

**Webhook Request Headers**

Each webhook delivery includes these headers:

| Header                  | Description              | Example                     |
| ----------------------- | ------------------------ | --------------------------- |
| `X-Webhook-Signature`   | HMAC-SHA256 signature    | `sha256=a1b2c3d4...`        |
| `X-Webhook-Event`       | Event type               | `business-closed`           |
| `X-Webhook-Delivery-Id` | Unique delivery ID       | `550e8400-e29b-41d4...`     |
| `User-Agent`            | Always set to this value | `DomainMonitor-Webhook/1.0` |

**Signature Verification**

To verify the webhook signature:

1. Get your webhook signing secret (from creation or regeneration)
2. Retrieve the raw request body as received (don't parse it first)
3. Compute HMAC-SHA256 hash using your secret as the key
4. Format as `sha256={hex_digest}`
5. Compare with `X-Webhook-Signature` header using timing-safe comparison

function to verify signature

```
function verifyWebhookSignature(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(JSON.stringify(payload));
  const expectedSignature = `sha256=${hmac.digest('hex')}`;

  // Use timing-safe comparison to prevent timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.payshield.ai/merchant-monitoring-api/webhook-monitoring-notifications.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
