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

# Webhook alerts

## What is a webhook?

A webhook is an HTTP-based callback function that allows lightweight, event-driven communication between two application programming interfaces (APIs). Events, such as adding a new customer, deleting a customer, and usage limit exceeded are raised on a source system, and destination systems *hooked* or subscribed to the events receive a payload of data. In our case, Zenskar is the source system that will send payload of data to all destination systems *hooked* or subscribed to events.

Three primary components are required for webhooks to function:

1. **Endpoint URL:** the destination endpoint where the payload will be transmitted from Zenskar via a `POST` HTTP method.
2. **Subscribed events:** the events that the destination system is hooked on to.
3. **Secret key:** to ensure that your system only processes webhook payloads delivered by Zenskar, and to ensure that the delivery was not tampered with, you should validate the webhook signature before processing the payload further.

> 🚧 Securing the secret key
>
> You must store your secret key in a secure location that only your system can access. You must never hardcode a key into an application or store a key in any source code repository.

## Creating a webhook

1. Click on the drop-up menu at the bottom left with your name.
2. Click on the **Webhook Alerts** tab on the **Settings** page.
3. Click on the **+ ADD WEBHOOK ALERT** button on the **Webhook Alerts** page.

<Image align="center" border={true} src="https://files.readme.io/dc85d8f-Screenshot_from_2024-03-11_15-56-56.png" className="border" />

4. Fill in the details on the following page:

<Image align="center" border={true} src="https://files.readme.io/fb19a1c-Screenshot_from_2024-03-11_15-58-51.png" className="border" />

* Details:
  * **Webhook name**: input any desired name for the webhook
  * **Add description (optional)**: add a description
  * **Endpoint URL**: the address URL of the destination system where Zenskar will send event data using `POST` HTTP method.
  * **Secret key**: enter a random string of text with [high entropy.](https://www.pleacher.com/mp/mlessons/algebra/entropy.html) This secret key will be hashed using the `SHA256` algorithm and added to the payload.
  * **Enable webhook alerts (selected by default)**: enables a webhook. If deselected, the webhook will be disabled.

<Image align="center" border={true} src="https://files.readme.io/c9e1dbf-Screenshot_from_2024-03-11_16-49-38.png" className="border" />

## Types of webhooks

| Webhook category | Event name          | Description                                                       |
| ---------------- | ------------------- | ----------------------------------------------------------------- |
| Customer         | customer.created    | Triggered when a new customer is created.                         |
|                  | customer.updated    | Triggered when customer metadata, phases, or pricing is modified. |
| Invoice          | invoice.created     | Triggered when a new invoice is created.                          |
|                  | invoice.updated     | Triggered when an invoice status is modified.                     |
|                  | invoice.deleted     | Triggered when a draft invoice is deleted.                        |
|                  | invoice.approved    | Triggered when an invoice is approved.                            |
|                  | invoice.regenerated | Triggered when an invoice is regenerated.                         |
| Contract         | contract.created    | Triggered when a new contract is created.                         |
|                  | contract.updated    | Triggered when contract metadata, phases, or pricing is modified. |
|                  | contract.activated  | Triggered when contract status changes to ACTIVE.                 |
|                  | contract.deleted    | Triggered when a contract is deleted.                             |
| Payment          | payment.created     | Triggered when a payment is created.                              |
|                  | payment.updated     | Triggered when a payment is updated.                              |
|                  | payment.succeeded   | Triggered when a payment succeeds.                                |
|                  | payment.failed      | Triggered when a payment fails.                                   |
|                  | payment.refunded    | Triggered when a payment is refunded.                             |

## Editing a webhook

1. Click on the drop-up menu at the bottom left with your name.
2. Click on the **Webhook Alerts** tab on the **Settings** page.

<Image align="center" border={true} src="https://files.readme.io/ae78c1b-Screenshot_from_2024-03-11_16-52-59.png" className="border" />

3. Click on the kebab menu at the end of the row containing the webhook you wish to edit, and proceed as shown below:

<Image align="center" border={true} src="https://files.readme.io/6838057-output.gif" className="border" />

4. Make the necessary edits.
5. Click on the UPDATE button to persist the changes.

## Deleting a webhook

1. Click on the drop-up menu at the bottom left with your name.
2. Click on the **Webhook Alerts** tab on the **Settings** page.
3. Click on the kebab menu at the end of the row containing the webhook you wish to delete, and proceed as shown below:

<Image align="center" border={true} src="https://files.readme.io/279832c-output.gif" className="border" />

## View webhook activity

1. Click on the drop-up menu at the bottom left with your name.
2. Click on the **Webhook Alerts** tab on the **Settings** page.
3. Click on the row containing the webhook whose details you wish to view.

### The **Alerts History** panel

You can view the history of the webhook alert in the **Alerts History** panel. In the case of the above figure, the webhook was triggered five times.

### **Event Information** panel

The event payload (JSON format) can be viewed in the **Event Information** panel:

```json theme={null}
{
  "event_info": {
    "id": "2446f64c-d3e8-4ce9-8d65-753690571134",
    "email": "john.doe@zenskar.com",
    "address": {
      "city": null,
      "line1": "483 E3, 40 Main Road",
      "line2": null,
      "line3": null,
      "state": null,
      "country": "USA",
      "zipCode": null
    },
    "tax_info": [],
    "created_at": "2024-02-29 05:18:23.104360",
    "deleted_at": null,
    "updated_at": null,
    "custom_data": {},
    "external_id": "cust_4178904715915710_5te_random",
    "organisation": "888ae523-8878-4ed7-85cc-6c0a54320568",
    "phone_number": "+91 9999999999",
    "customer_name": "John Doe",
    "ship_to_address": {
      "city": null,
      "line1": "483 E3, 40 Main Road",
      "line2": null,
      "line3": null,
      "state": null,
      "country": "USA",
      "zipCode": null
    },
    "auto_charge_enabled": true,
    "communications_enabled": true
  },
  "event_triggered": "customer.updated"
}
```

### **Triggered Webhook Details** panel

This panel shows the following details:

* **Webhook Id**: the Zenskar-enerated [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) of the webhook.
* **Status**: **Succeeded** or **Failed** as status.

> 🚧 Note
>
> The status shown in Zenskar is determined by the response received from the endpoint URL shared by you. If the response code is `200`, the status is **Succeeded**, else it is considered **Failed**. You must configure your system to return a `200` as response code to Zenskar when a payload from Zenskar is successfully delivered.

## Validating webhook deliveries

Zenskar will use the secret key to generate a hash signature. This hash signature will be included in the '*X-Signature*' header of each payload.

When validating webhook payloads, several important considerations should be noted:

* Zenskar employs an HMAC hex digest for computing the hash.
* The hash signature always starts with `sha256=`.
* The hash signature is generated using the secret token and the contents of the payload.

You can use your programming language of choice to implement HMAC verification in your code. For example, you can define the following `verify_signature` function and call it when you receive a webhook payload:

```python theme={null}
def verify_signature(payload_body, secret_token, signature_header):
    """Verify that the payload was sent from Zenskar by validating SHA256.

    Raise and return 403 if not authorized.

    Args:
        payload_body: original request body to verify (request.body())
        secret_token: Zenskar webhook token (WEBHOOK_SECRET)
        signature_header: header received from Zenskar (X-Signature)
    """
    if not signature_header:
        raise HTTPException(status_code=403, detail="X-Signature header is missing!")
    hash_object = hmac.new(secret_token.encode('utf-8'), msg=payload_body, digestmod=hashlib.sha256)
    expected_signature = "sha256=" + hash_object.hexdigest()
    if not hmac.compare_digest(expected_signature, signature_header):
        raise HTTPException(status_code=403, detail="Request signatures didn't match!")
```
