# Catálogo de eventos

Qué evento sale y cuándo.

Cada evento tiene `id`, `type`, `resource_id`, `sequence`, `api_version`, `data` y `created_at`. Se consultan en [`GET /v1/events`](/docs/operaciones/listar-eventos/) y llegan por webhook, con el mismo contenido.

> **Próximo.** En producción, la emisión de eventos se activa junto con la API. En la cuenta de prueba los eventos ya se emiten y se consultan en [`GET /sandbox/v1/events`](/docs/operaciones/listar-eventos/).

| Evento | Cuándo sale |
|---|---|
| [`payment.processing`](#paymentprocessing) | El pago se aceptó y sigue en curso, o se reabrió |
| [`payment.in_review`](#paymentin_review) | El pago está en revisión. No lo repitas |
| [`payment.completed`](#paymentcompleted) | El pago se confirmó |
| [`payment.failed`](#paymentfailed) | El pago no se hizo y no queda dinero en tránsito |
| [`payment.returned`](#paymentreturned) | El pago se devolvió. Puede llegar después de `payment.completed` |
| [`payment.canceled`](#paymentcanceled) | El pago se canceló |
| [`deposit.received`](#depositreceived) | El dinero ya está acreditado |
| [`deposit.in_review`](#depositin_review) | El depósito está en revisión |
| [`deposit.returned`](#depositreturned) | El depósito se devolvió |
| [`collection.paid`](#collectionpaid) | El cobro se pagó |
| [`collection.expired`](#collectionexpired) | El cobro venció sin pago |
| [`security.ip_allowlist.changed`](#securityip_allowlistchanged) | Cambió la lista de IP de una llave de producción |
| [`system.egress_ips.changing`](#systemegress_ipschanging) | Cambiará una IP de salida de webhooks. Actualiza tu firewall antes de `effective_at` |

Cada tipo está declarado en el contrato, y el cuerpo de cada uno en su sección `webhooks`. Aun así, la lista es extensible: ignora los tipos que no conozcas, sin fallar. Puedes filtrar con [`GET /v1/events?type=payment.completed`](/docs/operaciones/listar-eventos/).

**Enviar evento de prueba** en el panel entrega además un evento `webhook.test`, con `{"test": true}` en `data`. No entra a [`GET /v1/events`](/docs/operaciones/listar-eventos/).

## Cuerpo de cada evento

El sobre es igual en todos: sólo cambia `data`, y el webhook lleva los mismos campos que [`GET /v1/events`](/docs/operaciones/listar-eventos/), con `resource_id`. En la cuenta de prueba, `data` lleva además `livemode: false`. Un evento emitido con [`POST /sandbox/v1/webhooks/trigger`](/docs/operaciones/emitir-evento-de-prueba/) trae el `data` real de su tipo, con datos ficticios y además `simulated: true`.

### `payment.processing`

El pago se aceptó y sigue en curso, o se reabrió.

```json
{
  "id": "evt_0b16ae905ca3314bb3a098ed52717d82",
  "type": "payment.processing",
  "resource_id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
    "status": "processing",
    "amount": "1500.00",
    "currency": "MXN",
    "destination_currency": "MXN",
    "final_amount": null,
    "final_currency": null,
    "failure_code": null,
    "external_ref": "pedido-7731",
    "updated_at": "2026-11-04T18:01:30.000Z"
  }
}
```

### `payment.in_review`

El pago está en revisión. No lo repitas.

```json
{
  "id": "evt_710779698b77fbc43c44c63fff818f9e",
  "type": "payment.in_review",
  "resource_id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
    "status": "in_review",
    "amount": "1500.00",
    "currency": "MXN",
    "destination_currency": "MXN",
    "final_amount": null,
    "final_currency": null,
    "failure_code": null,
    "external_ref": "pedido-7731",
    "updated_at": "2026-11-04T18:01:30.000Z"
  }
}
```

### `payment.completed`

El pago se confirmó.

```json
{
  "id": "evt_9a57c9e59c247226e4d0f93e7a056f80",
  "type": "payment.completed",
  "resource_id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
    "status": "completed",
    "amount": "1500.00",
    "currency": "MXN",
    "destination_currency": "MXN",
    "final_amount": "1500.00",
    "final_currency": "MXN",
    "failure_code": null,
    "external_ref": "pedido-7731",
    "updated_at": "2026-11-04T18:01:30.000Z"
  }
}
```

### `payment.failed`

El pago no se hizo y no queda dinero en tránsito. `failure_code` siempre trae un código, y `payment_rejected` si no hay uno más específico.

```json
{
  "id": "evt_bc847fdf659accc4b12b0dfe43946fdd",
  "type": "payment.failed",
  "resource_id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
    "status": "failed",
    "amount": "1500.00",
    "currency": "MXN",
    "destination_currency": "MXN",
    "final_amount": null,
    "final_currency": null,
    "failure_code": "payment_rejected",
    "external_ref": "pedido-7731",
    "updated_at": "2026-11-04T18:01:30.000Z"
  }
}
```

### `payment.returned`

El pago se devolvió. Puede llegar después de `payment.completed`.

```json
{
  "id": "evt_a13d5adda1d245b713d9beaf26c5e1b5",
  "type": "payment.returned",
  "resource_id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
    "status": "returned",
    "amount": "1500.00",
    "currency": "MXN",
    "destination_currency": "MXN",
    "final_amount": "1500.00",
    "final_currency": "MXN",
    "failure_code": null,
    "external_ref": "pedido-7731",
    "updated_at": "2026-11-04T18:01:30.000Z"
  }
}
```

### `payment.canceled`

El pago se canceló.

```json
{
  "id": "evt_df140300d13fad354a4dfe3bb985d7b2",
  "type": "payment.canceled",
  "resource_id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "id": "pay_6nRtY1wKs3QzD8cL5mVhF2gB",
    "status": "canceled",
    "amount": "1500.00",
    "currency": "MXN",
    "destination_currency": "MXN",
    "final_amount": null,
    "final_currency": null,
    "failure_code": null,
    "external_ref": "pedido-7731",
    "updated_at": "2026-11-04T18:01:30.000Z"
  }
}
```

### `deposit.received`

El dinero ya está acreditado.

```json
{
  "id": "evt_73511a9d0102bfc0c51fedc7b0a7892e",
  "type": "deposit.received",
  "resource_id": "dpt_7bTcF2qXe9WmL4sD1nHrY6vK",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "id": "dpt_7bTcF2qXe9WmL4sD1nHrY6vK",
    "status": "received",
    "amount": "1250.00",
    "currency": "MXN",
    "credited_amount": "1250.00",
    "credited_currency": "MXN",
    "received_at": "2026-11-04T18:00:00.000Z",
    "reference": "7731",
    "concept": "Pedido 7731",
    "tracking_key": "CLAVE-DE-RASTREO-DEMO",
    "receipt_url": null,
    "payer": {
      "name": "CLIENTE FICTICIO SA DE CV",
      "address": null,
      "bank": "Banco de ejemplo",
      "clabe": "999180000000000022",
      "rfc": "XAXX010101000"
    }
  }
}
```

### `deposit.in_review`

El depósito está en revisión.

```json
{
  "id": "evt_da9fa1e2dad8c4828327a51743ed7188",
  "type": "deposit.in_review",
  "resource_id": "dpt_7bTcF2qXe9WmL4sD1nHrY6vK",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "id": "dpt_7bTcF2qXe9WmL4sD1nHrY6vK",
    "status": "in_review",
    "amount": "1250.00",
    "currency": "MXN",
    "credited_amount": null,
    "credited_currency": null,
    "received_at": "2026-11-04T18:00:00.000Z",
    "reference": "7731",
    "concept": "Pedido 7731",
    "tracking_key": "CLAVE-DE-RASTREO-DEMO",
    "receipt_url": null,
    "payer": {
      "name": "CLIENTE FICTICIO SA DE CV",
      "address": null,
      "bank": "Banco de ejemplo",
      "clabe": "999180000000000022",
      "rfc": "XAXX010101000"
    }
  }
}
```

### `deposit.returned`

El depósito se devolvió.

```json
{
  "id": "evt_e856a9e6dc10f6808b6e393a042f5297",
  "type": "deposit.returned",
  "resource_id": "dpt_7bTcF2qXe9WmL4sD1nHrY6vK",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "id": "dpt_7bTcF2qXe9WmL4sD1nHrY6vK",
    "status": "returned",
    "amount": "1250.00",
    "currency": "MXN",
    "credited_amount": null,
    "credited_currency": null,
    "received_at": "2026-11-04T18:00:00.000Z",
    "reference": "7731",
    "concept": "Pedido 7731",
    "tracking_key": "CLAVE-DE-RASTREO-DEMO",
    "receipt_url": null,
    "payer": {
      "name": "CLIENTE FICTICIO SA DE CV",
      "address": null,
      "bank": "Banco de ejemplo",
      "clabe": "999180000000000022",
      "rfc": "XAXX010101000"
    }
  }
}
```

### `collection.paid`

El cobro se pagó.

```json
{
  "id": "evt_d4b75d0d0e379b0d9930fc46035c1d5d",
  "type": "collection.paid",
  "resource_id": "col_4hQvN8sLd1ZxK6tB2mYpR7cW",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "id": "col_4hQvN8sLd1ZxK6tB2mYpR7cW",
    "status": "paid",
    "amount": "1250.00",
    "destination_amount": null,
    "currency": "MXN",
    "method": "spei",
    "external_ref": "pedido-7731"
  }
}
```

### `collection.expired`

El cobro venció sin pago.

```json
{
  "id": "evt_9830df4e0486f72e0d83ce3d304b50f4",
  "type": "collection.expired",
  "resource_id": "col_4hQvN8sLd1ZxK6tB2mYpR7cW",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "id": "col_4hQvN8sLd1ZxK6tB2mYpR7cW",
    "status": "expired",
    "amount": "1250.00",
    "destination_amount": null,
    "currency": "MXN",
    "method": "spei",
    "external_ref": "pedido-7731"
  }
}
```

### `security.ip_allowlist.changed`

Cambió la lista de IP de una llave de producción. `resource_id` es el nombre del evento, y `key` el identificador interno de la llave. Se publica sólo en producción.

```json
{
  "id": "evt_c39f4bb5885e3e522e4d22cb831c4c09",
  "type": "security.ip_allowlist.changed",
  "resource_id": "security.ip_allowlist.changed",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "key": "3f0c2d1e-7a54-4b1f-9c0e-1a2b3c4d5e6f",
    "added": [
      "198.51.100.10/32"
    ],
    "removed": []
  }
}
```

### `system.egress_ips.changing`

Cambiará una IP de salida de webhooks. Actualiza tu firewall antes de `effective_at`. `change` es `added` si la IP empezará a usarse y `retiring` si dejará de usarse. `resource_id` empieza con `egr_` y `sequence` es `1`. Mientras un cambio esté pendiente, llega una vez a cada destino activo y suscrito, también al que se activa después del anuncio, hasta una hora antes de `effective_at`. Uno activado en esa última hora puede no recibirlo: el aviso sigue en [`GET /v1/events`](/docs/operaciones/listar-eventos/). Ver [IP de webhooks](/docs/seguridad/ip-webhooks/).

```json
{
  "id": "evt_1fc117ce1c2d350a5a1e5dc452ef30ef",
  "type": "system.egress_ips.changing",
  "resource_id": "egr_5f0c2a9e7d3b41c68a2e9f10",
  "api_version": "2026-11-01",
  "created_at": "2026-11-04T18:01:30.000000Z",
  "sequence": 1,
  "data": {
    "ip": "198.51.100.10",
    "change": "added",
    "effective_at": "2026-11-20T18:00:00.000Z"
  }
}
```

## Montos

El monto de un evento es el mismo que responde `GET` sobre ese recurso, con el formato de [Montos y fechas](/docs/montos-y-fechas/).

## Orden

`sequence` crece por recurso. Si recibes `sequence` menor al último que guardaste, ignora ese evento para el estado.

Un `sequence` mayor manda aunque el estado vaya hacia atrás. Los retrocesos reales de un pago se publican: `payment.processing` después de `payment.canceled` significa que se reabrió. Una lectura parcial no publica nada, salvo un rechazo ya cerrado.

## Errores comunes

- Tratar `deposit.in_review` como dinero disponible. Sólo `deposit.received` significa acreditado.
- Asumir que `completed` es definitivo: puede llegar `payment.returned`.
- Descartar un evento porque el pago ya estaba en un estado terminal. Compara `sequence`, no el estado.
- Esperar que toda devolución llegue por evento. Ver [Vigilancia de un pago completado](/docs/conceptos/#vigilancia-de-un-pago-completado).

## Qué sigue

[Conciliar](/docs/recetas/conciliar/).
