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

# normalizeIntent

> Mapea el envelope PaymentIntent de la API al shape StatusInfo que consume el widget/poller.

```ts theme={null}
import { normalizeIntent } from "@zopay/js";

const status = normalizeIntent(apiResponse);
// status: StatusInfo
```

`normalizeIntent` toma el envelope crudo que devuelve `GET /connect/v1/payment-intents/{id}` y lo convierte al shape `StatusInfo` que `mountPaymentWidget` y `createPoller` esperan en el callback `checkStatus`.

Internamente se encarga de:

* Mapear `status` del intent (`pending` / `completed` / `expired` / `failed`) a la fase del poller.
* Extraer los campos del `deposit` (cuando existe) y exponerlos como `txHash`, `amountReceived`, `addressReceiver`, etc.
* Aplicar fallbacks para campos opcionales (status desconocido → tratamiento conservador).

## Por qué usarlo

El envelope `PaymentIntent` que sirve Connect API tiene una superficie amplia (addresses, cumulative-amount fields, deposit details, metadata). El widget no necesita la mayoría — sólo el suficiente para decidir entre "esperar", "mostrar progreso parcial", "celebrar éxito", "mostrar error". `normalizeIntent` hace ese mapeo para que tu callback `checkStatus` sea trivial.

## Patrón canónico

```ts theme={null}
checkStatus: async () => {
  const res = await fetch(`/api/zopay/status/${intent.id}`);
  return normalizeIntent(await res.json());
},
```

Tu backend devuelve el body verbatim de Connect API (no lo transformes). `normalizeIntent` hace el resto.

## Si tu backend ya devuelve un shape custom

Si por razones de tu arquitectura tu endpoint de status devuelve un shape ya transformado (no el envelope de Connect), entonces NO llames a `normalizeIntent` — construye un `StatusInfo` a mano que cumpla con el contrato. En la mayoría de las integraciones el patrón canónico de arriba es lo correcto.
