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

# Event types & structures

> The webhook envelope, the events Zerocash sends, and the transaction types you will see.

## Base structure

Every webhook shares the same envelope:

```json theme={null}
{
  "event": "string",
  "data": {
    // event-specific fields
  },
  "timestamp": "ISO-8601 timestamp"
}
```

## Event types

| Event                 | Fires when                                                     |
| :-------------------- | :------------------------------------------------------------- |
| `transaction_created` | A transaction has been created.                                |
| `transaction_updated` | A transaction's status changed, or a further step is required. |
| `payout_created`      | A payout has been created.                                     |
| `payout_updated`      | A payout's status changed.                                     |

<Note>
  Charges and payouts both create transactions, so a charge integration will mostly see
  `transaction_created` and `transaction_updated`. Payout flows also emit the `payout_*` pair —
  see [Sending payouts](/guides/payouts/payouts) for those payloads.
</Note>

## Transaction types

The `type` field inside `data` tells you what kind of movement the transaction represents:

| `type`       | Meaning                                                                             |
| :----------- | :---------------------------------------------------------------------------------- |
| `deposit`    | A payment received via card, mobile money, or bank.                                 |
| `withdrawal` | A payout sent from your balance. Also appears as `withdrew` on transaction records. |
| `refund`     | A refund created against an earlier deposit.                                        |

<Info>
  Refund status updates include `originalTransactionId` in `data`, linking the refund back to the
  deposit it reverses.
</Info>

## Status values

| `status`     | Meaning                                             |
| :----------- | :-------------------------------------------------- |
| `pending`    | The transaction is being processed. Not an outcome. |
| `successful` | The transaction completed. Funds moved.             |
| `failed`     | The transaction failed.                             |

<Warning>
  `pending` is not a resting state — it means "still in flight". Only `successful` means money
  moved. Do not release value on `pending`, and do not treat a `stepRequired` webhook as a
  failure.
</Warning>

## Fields inside `data`

`transaction_updated` carries the richest payload. Optional fields appear only when relevant:

| Field                   | Always present | Description                                           |
| :---------------------- | :------------: | :---------------------------------------------------- |
| `transactionId`         |       Yes      | Zerocash's ID for the transaction                     |
| `status`                |       Yes      | `pending`, `successful`, or `failed`                  |
| `type`                  |       Yes      | `deposit`, `withdrawal`, or `refund`                  |
| `externalReference`     |       Yes      | The unique ID you supplied                            |
| `stepRequired`          |        —       | Customer action needed, e.g. `otp`, `redirect`, `pin` |
| `redirectUrl`           |        —       | Present when `stepRequired` is `redirect`             |
| `method`                |        —       | The rail used, e.g. `momo`, `bank`, `card`            |
| `thirdPartyReference`   |        —       | The provider's reference, e.g. an M-Pesa code         |
| `note`                  |        —       | Human-readable detail, often the failure reason       |
| `originalTransactionId` |        —       | Present on refund updates only                        |

## Reading events safely

<AccordionGroup>
  <Accordion title="Do not assume ordering" icon="shuffle">
    Retries and network conditions mean a `successful` update can arrive before the
    `transaction_created` event. Key on `transactionId` and treat terminal statuses as final —
    never let a late `pending` overwrite a `successful`.
  </Accordion>

  <Accordion title="Expect fields to be absent" icon="circle-question">
    Optional fields are omitted, not sent as `null`. Read defensively rather than assuming a shape.
  </Accordion>

  <Accordion title="Handle unknown events gracefully" icon="shield">
    New event types may be added. Return `2xx` for events you do not recognise rather than
    erroring, which would trigger pointless retries.
  </Accordion>
</AccordionGroup>

<Card title="Transaction events in detail" icon="receipt" href="/guides/webhooks/transaction-events" horizontal>
  Full example payloads for every transaction event.
</Card>
