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

# Webhooks

### What are Webhooks?

Webhooks are HTTP-based real-time push notifications sent by Pesaswap to your server. They allow immediate communication of payment status and other events, which is critical for:

* Preventing lost business due to delayed payment confirmation (e.g., bookings or time-sensitive purchases).
* Avoiding reconciliation issues when payment statuses change (e.g., from "Failed" to "Succeeded").
* Improving user experience by triggering immediate fulfillment after payment success.

***

## Configuring Webhooks

### 1. Create an Endpoint on Your Server

Set up an **HTTP or HTTPS endpoint** that accepts POST requests. This endpoint will receive webhook notifications from Pesaswap, with JSON payloads.

***

### 2. Register the Webhook URL in Pesaswap

Go to your **Pesaswap Dashboard**:

* Navigate to **Developer → Payment Settings**
* Select your **Business Profile**
* Under the **Webhook Setup** section, provide the endpoint URL

***

### 3. Add Custom HTTP Headers (Optional)

<img height="400" noZoom src="https://mintlify.s3.us-west-1.amazonaws.com/pesaswap/logo/pesa30.png" />

If you want to verify incoming requests with additional security, you can add **custom HTTP headers** to your webhook. This helps ensure only trusted sources can send requests.

> You must provide a valid webhook URL before custom headers can be added.

<img height="400" noZoom src="https://mintcdn.com/pesaswap/plqQ00Qv-PMLK3qg/logo/image.png?fit=max&auto=format&n=plqQ00Qv-PMLK3qg&q=85&s=61bba06b020d8b28871ece4c85df24cb" data-path="logo/image.png" />

***

### 4. Update Pesaswap Webhook Endpoints on Connectors

To allow **connectors** (e.g., Stripe, PayPal) to send updates to Pesaswap:

* Add **Pesaswap's webhook endpoints** to their dashboards instead of your own.

#### Endpoint format:

| Environment | Endpoint                                                                     |
| ----------- | ---------------------------------------------------------------------------- |
| Sandbox     | `https://sandbox.Pesaswap.io/webhooks/{merchant_id}/{merchant_connector_id}` |
| Production  | `https://api.Pesaswap.io/webhooks/{merchant_id}/{merchant_connector_id}`     |

You can also retrieve this from the dashboard under the **Processors** tab.

***

## Webhook Events

You may receive webhooks for the following events:

```
payment_succeeded
payment_failed
payment_processing
payment_cancelled
payment_authorized
payment_captured
action_required
refund_succeeded
refund_failed
dispute_opened
dispute_expired
dispute_accepted
dispute_cancelled
dispute_challenged
dispute_won
dispute_lost
mandate_active
mandate_revoked
```

[Click here](#) to view webhook payload structures for each event type.

***

## Webhook Signature Verification

To validate that webhook requests are authentic:

### Signature Key

When creating a business profile, you can:

* Provide your own secret via `payments_response_hash_key`
* Or let Pesaswap generate a secure 64-character key

Ensure this key is stored securely and accessible to your server.

### Signature Generation (Outgoing Webhook)

1. JSON encode the webhook payload
2. Generate an **HMAC-SHA512** digest using the `payments_response_hash_key`
3. Pesaswap includes this as a header: `x-webhook-signature-512`

***

## Validating the Webhook Signature

1. Retrieve and encode the received payload
2. Use HMAC-SHA512 with your secret key to compute the signature
3. Compare with the `x-webhook-signature-512` in the header
4. If they match → the webhook is **authentic**

***

## Troubleshooting Signature Verification

* **Use the correct header:** `x-webhook-signature-512` (preferred)
* **Use the right algorithm:**

  * For SHA-512: `x-webhook-signature-512`
  * For SHA-256: `x-webhook-signature-256` (fallback)
* Ensure the payload is **unaltered** before validation

***

## Webhook Retry Behavior

Pesaswap considers a delivery **successful** only if your server responds with an **HTTP 2XX** code.

If not, webhook retries are attempted for up to **24 hours** using **exponential backoff**:

| Retry Attempt | Delay      |
| ------------- | ---------- |
| 1st           | 1 minute   |
| 2nd–3rd       | 5 minutes  |
| 4th–8th       | 10 minutes |
| 9th–13th      | 1 hour     |
| 14th–16th     | 6 hours    |

> The delay is counted from the **previous attempt**, not the original delivery time.

***

## Handling Duplicate Webhooks

Webhook retries may result in **duplicate deliveries**.

To ensure **idempotency**:

1. Read the `event_id` from the webhook payload
2. Check if it’s already processed (store it in a DB or cache like Redis)
3. If new → process it; if duplicate → skip it
4. Retain `event_id`s for at least **24 hours**

***

## Handling Out-of-Order Webhooks

Due to retries and network delays, webhook events may arrive **out of order**.

Use the `updated` timestamp in the resource payload to determine if the event is **more recent** than what your system currently holds:

```pseudo theme={"system"}
if updated_timestamp_from_webhook > existing_timestamp_on_record:
    process_event()
else:
    ignore_as_stale()
```
