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

# Webhooks

> Understand ClickPesa Webhooks (Callbacks) and how to integrate them in your application

Webhooks are HTTP `POST` callbacks that deliver notification messages for events.

ClickPesa uses webhooks to inform your systems when transactional events occur. This way, your servers are always up to date with transaction information.

<Note>Webhook events are published from actions in any of the ClickPesa products, including the ClickPesa Dashboard, Hosted Integrations, Embedded Solutions and APIs.</Note>

## Webhook Levels

ClickPesa supports webhooks at two levels:

| Level                    | Scope                                   | When Used                                                                                                                                                                           |
| ------------------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Merchant webhooks**    | All transactions for the merchant       | Dashboard payments and other activity not linked to a specific application                                                                                                          |
| **Application webhooks** | Transactions for a specific application | Collection API, Disbursement API, [BillPay API](/bill-pay/billpay-api-overview), [CRDB Direct Debit](/crdb-direct-debit/api-overview) payments, and hosted checkout or payout links |

<Info>
  For payments and payouts tied to an application (including [USSD push](/api-reference/collection/ussd-push-requests/initiate-ussd-push-request) and card payments via the Collection API, [BillPay](/bill-pay/billpay-api-overview) control numbers created via API, [CRDB Direct Debit](/crdb-direct-debit/api-overview) installments, and [Hosted Checkout](/checkout/checkout-overview) links), if the application has a webhook URL configured for the event, the callback is sent to the **application webhook only** — the merchant webhook is not used. If the application has no webhook for the event, the merchant webhook is used instead.
</Info>

## Webhook Events

### `PAYMENT RECEIVED`

When a payment is received successfully, this event is triggered. This event provides you with key information about the payment, including identifiers, amounts, and customer details.

* **Description** - This event is triggered whenever a customer makes a successful payment. The webhook will send details of the transaction, including the amount, payer information, and transaction status.

* **Sample Payload Data**

```json [expandable] theme={null}
{
  "event": "PAYMENT RECEIVED",
  "data": {
    "id": "ORD123456LCP7890",
    "status": "SUCCESS",
    "paymentReference": "abc123def456ghi789",
    "orderReference": "ORD123456",
    "collectedAmount": "10000",
    "collectedCurrency": "TZS",
    "message": "success",
    "channel": "CRDB DIRECT DEBIT MANDATE",
    "updatedAt": "2024-04-10T18:22:56.153Z",
    "createdAt": "2024-04-10T18:22:16.949Z",
    "customer": {
      "customerName": "John Doe",
      "customerEmail": "john@example.com",
      "customerPhoneNumber": "255700000000"
    }
  }
}
```

<Note>
  For `PAYMENT RECEIVED` webhooks, the `collectedAmount` field is always zero or more. If our internal calculation ever ends up with a negative value, we send `"0"` instead so that you never receive a negative collected amount.
</Note>

### `PAYMENT FAILED`

* **Description** - This event is triggered when a payment attempt fails. The webhook will include information about the failure reason, the attempted transaction, and any relevant error codes.

* **Sample Payload Data**

```json [expandable] theme={null}
{
  "event": "PAYMENT FAILED",
  "data": {
    "id": "ORD123456LCP7890",
    "status": "FAILED",
    "channel": "CRDB DIRECT DEBIT MANDATE",
    "orderReference": "ORD123456",
    "message": "Insufficient balance",
    "updatedAt": "2024-04-11T04:58:31.036Z",
    "createdAt": "2024-04-11T04:58:31.036Z",
    "clientId": "ID1234XHYAJK"
  }
}
```

<Note>
  For **CRDB Direct Debit** installments, `channel` is `CRDB DIRECT DEBIT MANDATE` and `orderReference` is the **mandate reference** from CRDB (also returned on mandate status callbacks as `mandateReference`). Mandate status changes (**ACTIVE**, **REJECTED**, **CANCELLED**) are sent to the `mandateCallbackUrl` you provide when requesting mandate approval — not to these payment webhook URLs. See the [CRDB Direct Debit API overview](/crdb-direct-debit/api-overview#mandate-status-callbacks).
</Note>

### `PAYOUT INITIATED`

* **Description** - This event is triggered when a payout process is initiated. The webhook will provide details such as the payout amount, recipient information, and the initial status of the payout.

* **Sample Payload Data**

```json [expandable] theme={null}
{
  "event": "PAYOUT INITIATED",
  "data": {
    "updatedAt": "2024-09-02T10:15:30.000Z",
    "createdAt": "2024-09-01T14:22:10.000Z",
    "id": "PAY17072CD",
    "orderReference": "order_123456",
    "amount": "20000.00",
    "currency": "TZS",
    "fee": "2360.00",
    "status": "SUCCESS",
    "channel": "BANK TRANSFER", // or MOBILE MONEY
    "channelProvider": "Equity Bank Tanzania Limited",
    "transferType": "ACH", // or RTGS // if available
    "notes": "Payment for invoice no. 123456", // if available
    "beneficiary": {
      "accountNumber": "123456789",
      "accountName": "John Doe",
      "swiftNumber": "ABC1234XYZ", // if available
      "routingNumber": "110000000", // if available
      "beneficiaryMobileNumber": "255600000000", // if available
      "beneficiaryEmail": "johndoe@example.com" // if available
    },
    "clientId": "ID1234XHYAJK"
  }
}
```

### `PAYOUT REFUNDED`

* **Description** - This event occurs when a payout is refunded, due to an issue with the payout process. The webhook will include the refund details and the original payout information.

* **Sample Payload Data**

```json [expandable] theme={null}
{
  "event": "PAYOUT REFUNDED",
  "data": {
    "updatedAt": "2024-09-02T10:15:30.000Z",
    "createdAt": "2024-09-01T14:22:10.000Z",
    "id": "PAY17072CD",
    "orderReference": "order_123456",
    "amount": "20000.00",
    "currency": "TZS",
    "fee": "2360.00",
    "status": "REFUNDED",
    "channel": "BANK TRANSFER", // or MOBILE MONEY
    "channelProvider": "Equity Bank Tanzania Limited",
    "transferType": "ACH", // or RTGS // if available
    "notes": "Payment for invoice no. 123456", // if available
    "refund": {
      // reverse details
      "message": "The payout was refunded due to insufficient balance.",
      "refundedAt": "2024-09-02T09:30:00.000Z"
    },
    "beneficiary": {
      "accountNumber": "123456789",
      "accountName": "John Doe",
      "swiftNumber": "ABC1234XYZ", // if available
      "routingNumber": "110000000", // if available
      "beneficiaryMobileNumber": "255600000000", // if available
      "beneficiaryEmail": "johndoe@example.com" // if available
    },
    "clientId": "ID1234XHYAJK"
  }
}
```

### `PAYOUT REVERSED`

* **Description**: This event is triggered when a payout is reversed, typically due to an error or a dispute. The webhook will contain details about the reversal, the original payout, and any related information.

* **Sample Payload Data**

```json [expandable] theme={null}
{
  "event": "PAYOUT REVERSED",
  "data": {
    "updatedAt": "2024-09-02T10:15:30.000Z",
    "createdAt": "2024-09-01T14:22:10.000Z",
    "id": "PAY17072CD",
    "orderReference": "order_123456",
    "amount": "20000.00",
    "currency": "TZS",
    "fee": "2360.00",
    "status": "REVERSED",
    "channel": "BANK TRANSFER", // or MOBILE MONEY
    "channelProvider": "Equity Bank Tanzania Limited",
    "transferType": "ACH", // or RTGS // if available
    "notes": "Payment for invoice no. 123456", // if available
    "reverse": {
      // reverse details
      "message": "The payout was reversed due to invalid account information.",
      "reversedAt": "2024-09-02T09:30:00.000Z",
      "reversedWithFee": true // whether funds were returned with fee or not
    },
    "beneficiary": {
      "accountNumber": "123456789",
      "accountName": "John Doe",
      "swiftNumber": "ABC1234XYZ", // if available
      "routingNumber": "110000000", // if available
      "beneficiaryMobileNumber": "255600000000", // if available
      "beneficiaryEmail": "johndoe@example.com" // if available
    },
    "clientId": "ID1234XHYAJK"
  }
}
```

### `DEPOSIT RECEIVED`

* **Description**: This event is triggered when a deposit is received. The webhook will contain details about the deposit and any related information.

* **Sample Payload Data**

```json [expandable] theme={null}
{
  "event": "DEPOSIT RECEIVED",
  "data": {
    "id": "DEP17C9LPL",
    "status": "SUCCESS",
    "paymentReference": "1982813f15938863",
    "orderReference": "DEP17C9LPL",
    "depositAmount": "2000",
    "depositCurrency": "TZS",
    "channel": "CRDB COLLECTION",
    "updatedAt": "2025-07-20T13:44:22.902Z",
    "createdAt": "2025-07-20T13:44:13.893Z",
    "message": "Payment from Payclick Co Ltd",
  }
}
```

## Setting Up Webhooks

### Merchant-Level Webhooks

Merchant webhooks apply to all transactions unless an application webhook is used (see below).

1. **Access webhook settings**
   * Log in to your [ClickPesa Dashboard](https://merchant.clickpesa.com)
   * Navigate to **Settings** → **Developers**
   * Locate the **Webhooks** section

2. **Add webhook URLs**
   * Select event types: `PAYOUT INITIATED`, `PAYOUT REVERSED`, `PAYOUT REFUNDED`, `PAYMENT RECEIVED`, `PAYMENT FAILED`, or `DEPOSIT RECEIVED`
   * Set the webhook URL for each event

### Application-Level Webhooks

Application webhooks let you receive events per application for transactions tied to that application. This includes:

* **Collection API** — USSD push, card, and other payments you initiate through the API
* **Disbursement API** — mobile money and bank payouts you create through the API
* **BillPay API** — when a customer pays against an [order or customer control number](/bill-pay/billpay-api-overview) you created through the API
* **Hosted integrations** — payments and payouts through hosted links for your application, such as [Hosted Checkout](/checkout/checkout-overview)

Use application webhooks when you have multiple applications (e.g. different apps or environments) and want separate webhook endpoints per application.

<Note>
  Application webhooks do **not** apply to offline BillPay references that were not created through the BillPay API. Payments made only from the dashboard use merchant webhooks instead.
</Note>

<Note>
  An optional `callbackUrl` on [Generate Checkout Link](/api-reference/collection/generate-checkout-link/generate-checkout-link) is separate from application webhooks. Application webhooks are configured in the dashboard and apply to all qualifying payments for that application, whether or not you also set `callbackUrl` on a link.
</Note>

**Supported events:** `PAYMENT RECEIVED`, `PAYMENT FAILED`, `PAYOUT INITIATED`, `PAYOUT REFUNDED`, `PAYOUT REVERSED`

<Note>`DEPOSIT RECEIVED` is only available at the merchant level.</Note>

1. **Access application settings**
   * Log in to your [ClickPesa Dashboard](https://merchant.clickpesa.com)
   * Navigate to **Settings** → **Developers**
   * Click on an application to open its details

2. **Configure application webhooks**
   * In the **Application Webhooks** section, add webhook URLs for the events you need
   * Each application can have its own URLs per event

### Receiving Webhook Calls

* The gateway sends HTTP POST requests to the provided URL upon an event
* Your system should respond with a **2xx HTTP status code** to acknowledge receipt
* Payloads can include a `checksum` and `checksumMethod` for verification (see [Checksum documentation](/home/checksum))

<Note>This status code only indicates receipt, not successful processing.<br />Extra data in the response is ignored.</Note>
