> For the complete documentation index, see [llms.txt](https://docs.xtrakit.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xtrakit.com/overview/payments/webhook.md).

# Webhook

## Endpoint

<mark style="color:$warning;">**`POST`**</mark> `{YOUR CALLBACK URL}`

**How to set up a signed webhook**

Log in to your [XtraPay Account ](https://pay.xtrakit.com/)and go to:

Settings → Developers → [API Keys & Webhooks](https://pay.xtrakit.com/settings/developers).

Find the Callback Secret field, click to update, enter your secret key (without spaces), and then click Save.

<figure><img src="/files/KvFss5SNOYO4XDZXkwGC" alt=""><figcaption></figcaption></figure>

<mark style="color:$warning;">**`NOTE:`**</mark> After configuring your webhook, every callback sent to your server will include an **HMAC-SHA256 signature**. You should verify this signature to confirm that the webhook originated from XtraPay and that the payload has not been altered during transmission.

## Headers

`Authorization: Bearer API_KEY`

<table><thead><tr><th width="210.1875">Name</th><th width="149.828125">Key</th><th>Description</th></tr></thead><tbody><tr><td>Signature</td><td><code>signature</code></td><td><p>The <mark style="color:$warning;"><strong>signature</strong></mark> is an HMAC SHA256 hash of the raw webhook payload, generated using your <mark style="color:$warning;"><strong>Merchant Callback Secret</strong></mark>. It is included in the request header to verify the source and integrity of the webhook.</p><p>The signature header is present <strong>only when a secret is configured</strong>; otherwise, it is not included.</p></td></tr><tr><td>Content Type</td><td>Content Type</td><td><code>application/json</code></td></tr></tbody></table>

## **Request Body**

<table><thead><tr><th width="289">Parameters</th><th width="100">Type</th><th>Description</th></tr></thead><tbody><tr><td><p>status</p><p><code>integer</code></p></td><td>Required</td><td>Custom Status Code. See <a href="https://docs.xtrakit.com/~/revisions/hMZmKtqdg32OuNOv1BWc/overview/payments/status-codes">Status Codes</a></td></tr><tr><td><p>message</p><p><code>string</code></p></td><td>Required</td><td>Payment Status Description</td></tr><tr><td><p>amount</p><p><code>string</code></p></td><td>Required</td><td>Payment Amount</td></tr><tr><td><p>transaction_id</p><p><code>string</code></p></td><td>Required</td><td>Payment Transaction ID</td></tr><tr><td><p>currency</p><p><code>string</code></p></td><td>Required</td><td>Payment Currency</td></tr><tr><td><p>business_code</p><p><code>string</code></p></td><td>Required</td><td>Your business code</td></tr></tbody></table>

## How to Validate Webhook <a href="#sample-requests" id="sample-requests"></a>

{% tabs %}
{% tab title="PHP" %}
{% code fullWidth="true" %}

```php
signature = request.headers["signature"]

if signature exists:
    payload = request.raw_body
    secret  = "YOUR_MERCHANT_CALLBACK_SECRET"

    computed = HMAC_SHA256(payload, secret)

    if secure_compare(computed, signature) is false:
        return HTTP 401 Unauthorized

process webhook
return HTTP 200 OK
```

{% endcode %}
{% endtab %}
{% endtabs %}
