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

# Events & webhooks

> The events Broco sends to your server, what each one means, and where to find amount, currency and reference.

Broco notifies your server when an operation changes status. Your server updates orders and invoices from these events, not from the browser.

## Events

| Event | Use case | Meaning | Funds available to the receiver |
| - | - | - | - |
| `payment.succeeded` | Broco Pay | Customer debited, merchant credited | Yes |
| `cash_payment.succeeded` | Cash checkout | Cash validated at a cash point, merchant credited | Yes |
| `cash_payment.expired` | Cash checkout | Deadline passed without payment | No |
| `supplier_payment.succeeded` | Supplier payments | Business debited, supplier credited | Yes |
| `collection.collected` | Marketplace cash reconciliation | Recipient confirmed the handover. The carrier holds the cash. | No |
| `settlement.completed` | Marketplace cash reconciliation | Deposit validated, wholesaler credited | Yes |

<Warning>
  `collection.collected` and `settlement.completed` mean different things. Never show a collection as paid out on `collection.collected`.
</Warning>

## Event format

Every event has an `id`, a `type`, a `created_at` time and the object in `data`. The objects and their fields are described in the [API Reference](/api-reference/introduction).

Event examples in these guides are excerpts: `data` shows only the fields used in the step.

```json Event (excerpt) theme={null}
{
  "id": "evt_P3n8Tq1v",
  "type": "payment.succeeded",
  "created_at": "2026-10-12T10:02:41Z",
  "data": {
    "id": "pay_9Xc2LmQ7",
    "object": "payment",
    "status": "succeeded",
    "merchant_connection": "conn_mrc_4f7Kp2",
    "amount": 1250000,
    "currency": "DZD",
    "order_reference": "ORD-10482"
  }
}
```

## Where to check amount, currency and reference

| Event | Amount | Currency | Reference |
| - | - | - | - |
| `payment.succeeded` | `data.amount` | `data.currency` | `data.order_reference` |
| `cash_payment.succeeded` | `data.amount` | `data.currency` | `data.order_reference` |
| `cash_payment.expired` | `data.amount` | `data.currency` | `data.order_reference` |
| `supplier_payment.succeeded` | `data.amount` | `data.currency` | `data.invoice_reference` |
| `collection.collected` | `data.amount` | `data.currency` | `data.order_reference` |
| `settlement.completed` | `data.settlement.gross_amount`, `data.settlement.net_amount` | `data.settlement.currency` | `data.order_reference` |

For `settlement.completed`, `data.amount` is the amount of the collection and `data.settlement.gross_amount` is the amount deposited and settled. They are equal for a complete deposit.

## Handling events

```mermaid theme={null}
flowchart TD

  A["Broco records a status change"]:::step -.-> B["Broco sends the event"]:::notify
  B --> C{"Signature valid?"}:::check
  C -- "no" --> X["Reject the request.<br/>Do not process it."]:::step
  C -- "yes" --> D{"Event id already<br/>stored?"}:::check
  D -- "yes" --> Y["Respond 2xx.<br/>Do nothing else."]:::step
  D -- "no" --> E["Store the event and the work to do.<br/>Then respond 2xx."]:::step
  E --> F{"Object, account, attempt,<br/>amount, currency and<br/>reference match?"}:::check
  F -- "yes" --> G["Update the order or invoice.<br/>Mark the event processed."]:::step
  F -- "no" --> Z["Flag for review.<br/>Never revert an order<br/>already marked as paid."]:::step
  classDef check fill:#E8F4F7,stroke:#158FAB,color:#0E1C29
  classDef notify fill:#FFF6C2,stroke:#B89400,color:#0E1C29,stroke-dasharray:4 3
  classDef step fill:#FFFFFF,stroke:#C9D0D6,color:#0E1C29
```

In this diagram, light blue steps are validations and dashed yellow steps are notifications.

<Steps>
  <Step title="Verify the signature">
    Each event is signed by Broco. Verify the signature before you trust the content. Reject events that fail verification.
  </Step>

  <Step title="Ignore duplicates">
    Look up the event `id`. If you already stored it, respond with a `2xx` status and do nothing else. A repeated event never means a second payment or a second credit.
  </Step>

  <Step title="Store the event before you respond">
    Save the whole event and the work it requires in durable storage, marked as received. Then respond with a `2xx` status. A `2xx` response means you received the event, not that you processed it. If processing is short, you can also finish it before responding.
  </Step>

  <Step title="Process stored events">
    Process each stored event once. Lock the event or the order while it is processed, so two workers never handle it at the same time. Mark the event as processed only after your update succeeds. If processing fails, keep the event pending and resume it from your storage.
  </Step>

  <Step title="Match your records">
    Compare the event with the attempt you are tracking: the Broco object `id` you stored when you created it, the connection of the account involved, the amount, the currency and the reference. Use the fields in the table above. If they differ, do not update the order: flag it for review and retrieve the object to check its status.
  </Step>
</Steps>

## Repeated, late or out-of-order events

Treat events as independent notices that can arrive more than once and in any order.

* Apply an event only if it concerns the attempt you are tracking and moves your record forward.
* Never move an order or invoice back from paid to unpaid because of an event about an earlier attempt or an older status. Flag the difference for review instead.
* When in doubt, retrieve the object and use its current status.

## When an event is late

Retrieve the object to read its current status:

| Object | Operation |
| - | - |
| Payment | `GET /v1/payments/{id}` |
| Cash payment | `GET /v1/cash_payments/{id}` |
| Supplier payment | `GET /v1/supplier_payments/{id}` |
| Collection and settlement | `GET /v1/collections/{id}` |

For events that credit funds (`payment.succeeded`, `cash_payment.succeeded`, `supplier_payment.succeeded` and `settlement.completed`), the credit happens when Broco records the operation, not when your server receives the event. `cash_payment.expired` and `collection.collected` do not credit anyone.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.