# Webhooks

## About Our Webhooks 📣

Inabit Terminal uses webhooks to notify your backend when key payment events occur. Webhooks are triggered per widget and can be configured globally at the organization level or overridden per widget.

Terminal supports two webhook types, based on widget type:

* **Customer Address Widgets** – for persistent payment addresses
* **Purchase Address Widgets** – for one-time payments

### Webhook Events Overview

<table><thead><tr><th>Widget Type</th><th width="336.2330322265625">Event Name</th><th>Description</th></tr></thead><tbody><tr><td>Customer Address</td><td><code>IncomingTransactionReceived</code></td><td>A new transaction is detected (“Unconfirmed” for UTXO blockchains, “Confirming” for non UTXO blockchains)</td></tr><tr><td>Customer Address</td><td><code>IncomingTransactionStatusUpdated</code></td><td>Transaction status changes (e.g., “Completed”)</td></tr><tr><td>Purchase Address</td><td><code>PurchaseInitiated</code></td><td>Widget is created and ready to receive payment, status=”Initiated”</td></tr><tr><td>Purchase Address</td><td><code>PurchaseUpdated</code></td><td>Purchase status or amount has changed</td></tr></tbody></table>

### Configuring Webhooks

#### Organization-Level Webhooks

Webhook URLs are registered during onboarding and apply to all widgets by default.\
To update these, contact <support@inabit.com>.

#### Widget-Level Webhooks

**API:** When [creating a widget](https://docs.inabit.com/inabit-terminal/terminal-guide/creating-widgets), you can override the default webhook URL:

```json
{
  "webhookUrl": "https://yourdomain.com/webhook/inabit"
}
```

**UI:** Upon widget creation, you'll be requested to insert a Webhook URL to receive notifications to:

<div align="left"><figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXey1Ni7K9L5-WfbtJzHcYYHOgmNN6pyOmTHQ8uIy-6eXtvtQK7inWJCcVwMLA6fF7m7TqhJgN9Q-DOExblZLsrU4Ci-aYMdaBRhEM9SuEzd4LlUcXD-8eyuOxBFkHq4680RndhD?key=qoEDREppj-ZPb8jYHbsufg" alt=""><figcaption></figcaption></figure></div>

### Webhook Event Payloads

#### IncomingTransactionStatusInitiated

Triggered when a new on-chain transaction is detected for a Customer Address widget.

```json
{
  "event": "IncomingTransactionStatusInitiated",
  "data": {
    "transactionId": "cmd62lqob00yre7014nj501zc",
    "transactionHash": "0xbb22...5011",
    "status": "Pending",
    "amount": 20,
    "sourceAddress": "0x0bf2...",
    "destinationAddress": "0x1973...",
    "asset": "USDT",
    "blockchain": "ethereum-sepolia",
    "customerIdentifier": "customer@gmail.com",
    "widgetId": "31ec71e3-26ed-4653-ad3b-c56f42330510",
    "targetConfirmations": "12"
  }
}
```

#### IncomingTransactionReceived

Triggered when a transaction is retrieved/received for the first time. (e.g., Confirming)

```json
{
  "event": "IncomingTransactionReceived",
  "data": {
    "transactionId": "cmdrdvuae01ytec01vtdf3wql",
    "transactionHash": "0x2a754742bce4786b4ca870ab5c15f53e108f56663b949fe570db0db36be3c4ab",
    "status": "Confirming",
    "amount": 5,
    "sourceAddress": "0x2dbcaac27274e0dc7835e0d6c1b3c6bce2712790",
    "destinationAddress": "0xc4870c59e649e1b66d6329e16c6d942cad8e59d4",
    "asset": "USDT",
    "blockchain": "ethereum-sepolia",
    "createdAt": "2025-07-31T12:41:28.093Z",
    "customerIdentifier": "tomtom@gmail.com",
    "widgetId": "9e37db44-0eea-465e-b35d-907d0a817b89",
    "widgetName": "test 20 customer address",
    "baseCurrency": "USD",
    "baseCurrencyAmount": 4.998749,
    "targetConfirmations": "12"
  }
}
```

#### IncomingTransactionStatusUpdated

Triggered when a transaction's status is updated (e.g., Confirmed).

```json
{
  "event": "IncomingTransactionStatusUpdated",
  "data": {
    "transactionId": "cmdrdvuae01ytec01vtdf3wql",
    "transactionHash": "0x2a754742bce4786b4ca870ab5c15f53e108f56663b949fe570db0db36be3c4ab",
    "status": "Completed",
    "amount": 5,
    "sourceAddress": "0x2dbcaac27274e0dc7835e0d6c1b3c6bce2712790",
    "destinationAddress": "0xc4870c59e649e1b66d6329e16c6d942cad8e59d4",
    "asset": "USDT",
    "blockchain": "ethereum-sepolia",
    "createdAt": "2025-07-31T12:41:28.093Z",
    "customerIdentifier": "tomtom@gmail.com",
    "widgetId": "9e37db44-0eea-465e-b35d-907d0a817b89",
    "widgetName": "test 20 customer address",
    "baseCurrency": "USD",
    "baseCurrencyAmount": 4.998749,
    "targetConfirmations": "12"
  }
}
```

#### PurchaseInitiated

Triggered when a Purchase Address widget is created (initiated).

```json
{
  "event": "PurchaseUpdated",
  "data": {
    "purchaseId": "5a7e6bad-8ad8-464f-9892-0f2df100b79c",
    "status": "Initiated",
    "amount": 0,
    "plannedAmount": 0.00000673,
    "asset": "BTC",
    "blockchain": "bitcoin",
    "address": "bc1q8pe73z...",
    "fiatCurrency": "USD",
    "fiatAmount": 0.8,
    "confirmationAmount": 6,
    "widgetId": "bd6510a0-ad66-4f95-ad50-1bc415bf97a6",
    "widgetName": "product widget purchase",
    "purchaseIdentifier": "customer@gmail.com",
    "title": "Payment",
    "subTitle": "The payment description",
    "siteName": "Merchant Site",
    "transactions": [],
    "currentDate": "2025-07-16T11:50:12.835Z",
    "expirationDate": "2025-07-16T12:35:12.388Z",
    "acceptPartialPayment": true,
    "redirectUrl": "http://www.inabit.com"
  }
}
```

#### PurchaseUpdated

Triggered when a purchase is updated (payment received, amount confirmed, status changed).

```json
{
  "event": "PurchaseUpdated",
  "data": {
    "purchaseId": "5a7e6bad-8ad8-464f-9892-0f2df100b79c",
    "status": "Completed",
    "amount": 0.000007,
    "plannedAmount": 0.00000673,
    "asset": "BTC",
    "blockchain": "bitcoin",
    "address": "bc1q8pe73z...",
    "fiatCurrency": "USD",
    "fiatAmount": 0.8,
    "confirmationAmount": 6,
    "widgetId": "bd6510a0-ad66-4f95-ad50-1bc415bf97a6",
    "transactions": [
      "e30e54115a76d52b2f857e1f0fa6888c76f2f04edc6095498107eebdf299dff9"
    ],
    "allocationDate": "2025-07-16T11:50:12.388Z",
    "expirationDate": "2025-07-16T12:35:12.388Z",
    "acceptPartialPayment": true,
    "redirectUrl": "http://www.inabit.com"
  }
}
```

### Security and Reliability

#### Retries

If a webhook delivery fails (e.g., due to a timeout or non-2xx response), Inabit Terminal will wait 30 seconds, then automatically retry the webhook up to 5 additional times, with 30 seconds between each retry

{% hint style="info" %}
**Signature Validation** (coming soon): HMAC-based signature header for payload verification.
{% endhint %}

{% hint style="success" %}

### Best Practices

* Acknowledge webhook events with HTTP 200 OK
* Validate the event type before handling the payload
* Store widgetId or purchaseId to associate the event with your system
* Log all webhook payloads for auditability and replay if needed
  {% endhint %}
