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

# Webhook cash_in

> Notificaciones del ciclo de vida de un SPEI cash-in

## Cuándo se dispara

El webhook del tipo `cash_in` recibe los eventos del ciclo de vida de un cobro creado vía `POST /api/spei/cash-in`:

| `event`                        | `status`     | Significado                                                       |
| ------------------------------ | ------------ | ----------------------------------------------------------------- |
| `transaction.cash_in.settled`  | `LIQUIDATED` | La transferencia SPEI llegó a la CLABE desechable y fue liquidada |
| `transaction.cash_in.rejected` | `REJECTED`   | La red SPEI rechazó la transferencia                              |
| `transaction.cash_in.expired`  | `EXPIRED`    | La CLABE expiró (\~24h) sin recibir la transferencia              |
| `transaction.cash_in.pending`  | `PENDING`    | Actualización intermedia de procesamiento                         |

<Info>
  La **devolución** de un cash-in ya liquidado (`transaction.cash_in.returned`) se entrega en el webhook del tipo [`refund_in`](/es/guides/webhooks/refund-in), no en el `cash_in`.
</Info>

## Payload

```json theme={"system"}
{
  "event": "transaction.cash_in.settled",
  "transactionId": "12345",
  "amount": 50000,
  "currency": "MXN",
  "status": "LIQUIDATED",
  "destinationClabe": "012180001234567890",
  "sourceClabe": "646180123456789012",
  "payerName": "Juan Perez",
  "reference": "1234567",
  "voucher": "CEP20260512A1B2C3",
  "occurredAt": "2026-05-12T14:31:05.000Z"
}
```

* `destinationClabe` — la CLABE desechable emitida al crear el cobro
* `sourceClabe` — la CLABE del pagador (cuando la red la informa)
* `amount` — monto en centavos MXN
* Los campos de referencia (`reference`, `voucher`) pueden venir `null` dependiendo del flujo

## Headers

| Header               | Valor                                     |
| -------------------- | ----------------------------------------- |
| `x-event-id`         | UUID único del evento (úsalo para dedupe) |
| `X-NTXPay-Signature` | `sha256=<hmac>` del cuerpo crudo          |

## Respuesta Esperada

Responde `200 OK` en menos de 10 segundos. Ante cualquier status distinto de `2xx`, NTX Pay reintenta hasta 5 veces con backoff exponencial.

```http theme={"system"}
HTTP/1.1 200 OK
Content-Type: application/json

{"received": true}
```

## Procesamiento

Marca la orden como pagada solamente cuando `event` sea `transaction.cash_in.settled` (o `status: LIQUIDATED`):

```typescript theme={"system"}
const event = JSON.parse(rawBody.toString());
if (event.event === 'transaction.cash_in.settled') {
  await markOrderPaid(event.transactionId, event.amount);
}
```

Para el handler completo con validación HMAC y dedupe en Node.js, Python, Java y Go, consulta [Implementación](/es/guides/webhooks/implementation).
