# Webhooks

## Event Payload

Every webhook is an HTTPS **POST** with a JSON body shaped like:

| Field        | Type     | Description                                          |
| ------------ | -------- | ---------------------------------------------------- |
| `event_type` | `string` | Machine-readable name of the event (see list below). |
| `data`       | `object` | Event-specific payload.                              |

### Common `event_type` Values

| Event                     | Trigger                                                                     |
| ------------------------- | --------------------------------------------------------------------------- |
| `payment_request.updated` | Payment request moves through `created → picked_up → completed / canceled`. |
| `onchain_tx.updated`      | On-chain withdrawal status changes.                                         |
| `chargeback.initiated`    | A dispute or MoMo reversal is opened on a completed payment.                |

***

## Example Payloads

**Payment request**

```json
{
  "event_type": "payment_request.updated",
  "data": {
    "id": "VHlwZXM6OkNhc2hyYW1wOjpBUEk6Ok1lcmNoYW50UGF5bWVudFJlcXVlc3QtOGI0OTdmZTYtOTljYS00MDQwLTkzNWQtMTY2OGJhNGUyNzU2",
    "reference": "test_ref_022",
    "status": "completed",
    "customer": {
      "id": "TWVyY2hhbnRDdXN0b21lci0xZmNiYTgzNi01MDNmLTQyMjYtYjgzYy02NzIzNjMxNDM0YWI=",
      "email": "engineering@useaccrue.com",
      "country": "GH",
      "currency": "GHS"
    },
    "p2p_payment": {
      "id": "UDJQUGF5bWVudC0xOGRmNmJiNC1hNmQ2LTQyMWUtYjQ0MS04YmFiMmE2YzQ5Yjc=",
      "exchange_rate": "7.95",
      "amount": "159.0",
      "amount_usd": "20.0",
      "fee": "0.3"
    },
    "created_at": "2025-05-02T12:43:40.914Z",
    "payment_link": "https://useaccrue.com/hosted/pay/..."
  }
}
```

**Onchain Withdrawal**

```json
{
  "event_type": "onchain_tx.updated",
  "data": {
    "id": "VHlwZXM6Ok9uY2hhaW5UeC1hYzNmODk2Mi1jNzRkLTRmNWMtYTQ5ZC1kYmIzMWM1MDc5Mzc=",
    "address": "TPy5hAiyWeKoUHAnAUSoK8YuqbTx75X8xX",
    "status": "completed",
    "quantity": 1000,
    "fee": 0,
    "symbol": "USDT",
    "network": "TRX",
    "txhash": "8efb22782c0a42047266aa6c3df1cfc60cd3ead4ba31075e5d6fccf833402e24"
  }
}
```

**Onchain Deposit**

```json
{
  "event_type": "onchain_payment.received",
  "data": {
    "id": "VHlwZXM6Ok9uY2hhaW5UeC1hYzNmODk2Mi1jNzRkLTRmNWMtYTQ5ZC1kYmIzMWM1MDc5Mzc=",
    "sender_address": "0xc2DC2eF356EBE18cCdA1D5B971eaBE7261027de1",
    "recipient_address": "0x9c7DCB324c602dA446987710Df00019ac6f9af2b",
    "status": "completed",
    "amount_usd": 36.68,
    "txhash": "0x52ca34f1569ddf9bcf5fc26e95de82e5420f940432ee9ab9780fe68ac60fae98"
  }
}
```

**Chargeback**

```json
{
  "event_type": "chargeback.initiated",
  "data": {
    "id": "TWVyY2hhbnRDaGFyZ2ViYWNrLWQ2MGVjMjI3LThhNTYtNDMxNS1hNWQ4LTk3N2JhNmFhNmE3Mw==",
    "status": "pending",
    "reason": "A MoMo reversal was initiated by your customer",
    "payment_request": {
      "id": "VHlwZXM6OkNhc2hyYW1wOjpBUEk6Ok1lcmNoYW50UGF5bWVudFJlcXVlc3QtYmMxYTMzMzktNTM5YS00Y2ZkLWE3ZmEtMTM1MzllZGVhNWQw",
      "reference": "c9b1082d49185da9",
      "amount": 100,
      "currency": "usd"
    }
  }
}
```

***

## Responding to Webhooks

{% hint style="danger" %}
Return **`200 OK` immediately**. Any non-2xx or timeout is treated as a delivery failure, and the event will be retried.
{% endhint %}

1. **Validate** – Compare the `X-CASHRAMP-TOKEN` header to the token in your dashboard.
2. **Confirm**: [Confirm the status of the payment request](/cashramp/cashramp-api/queries.md#transaction-status) (`completed`, `canceled`, etc.)
3. **Process** – Perform your business logic (credit user, update order, etc.).

***

## Best Practices

* **Verify the token** before trusting the payload—prevents spoofing.
* **Log the raw body** for audits and easier debugging.
* **Keep handlers fast**—offload heavy work to background jobs.
* **Rotate tokens** periodically or immediately on suspicion of compromise.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.cashramp.co/cashramp/introduction/webhooks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
