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

# Descripción general de Widgets Embebidos

> Inserta un flujo hospedado de Fluz en tu propio producto para recopilar permisos del usuario, capturar datos sensibles dentro de nuestro alcance PCI y confirmar movimiento de dinero — luego ejecuta todo lo demás del lado del servidor sobre la API.

## Qué es realmente un widget

Un Widget de Fluz es un flujo hospedado y renderizado por Fluz que embeberás en tu propio sitio con unas pocas líneas de JavaScript. Se ejecuta en un modal sobre tu página, en tu dominio, bajo tu marca.

Existe para hacer tres trabajos que no deberías tener que construir tú mismo:

<CardGroup cols={3}>
  <Card title="Recopilar el permiso del usuario" icon="shield-check">
    El widget es cómo un usuario final crea o inicia sesión en su cuenta de Fluz y **otorga a tu aplicación los alcances que necesita para actuar sobre esa cuenta**. Sin otorgamiento, no hay acceso a la API.
  </Card>

  <Card title="Capturar datos sensibles" icon="lock">
    Números de tarjeta, SSN, documentos de identidad y PIN se recopilan por Fluz, dentro del entorno PCI DSS de Fluz, y se cifran de nuestro lado. Nunca tocan tus servidores.
  </Card>

  <Card title="Confirmar movimiento de dinero" icon="arrow-left-right">
    El usuario ve y aprueba el monto y la dirección de una transferencia en una superficie en la que puede confiar, lo que convierte un token preautorizado en una transacción completada.
  </Card>
</CardGroup>

Todo lo demás — emitir la tarjeta, extraer los fondos, consultar el saldo, leer transacciones — te corresponde hacerlo sobre la API, en tu propio tiempo, sin un usuario presente.

<Info>
  **El modelo mental:** el widget es una *superficie de consentimiento y datos sensibles*, no un producto. Es la parte estrecha y de alto cumplimiento del flujo. La API es donde sucede el trabajo.
</Info>

***

## La división del trabajo

| Trabajo                                                | Widget | API                                                                          |
| :----------------------------------------------------- | :----- | :--------------------------------------------------------------------------- |
| Crear la cuenta de Fluz del usuario                    | ✅      | ✅ [Registro de usuario](/docs/user-registration)                             |
| Verificar identidad (KYC)                              | ✅      | ✅ [Verificación KYC de usuario](/docs/user-kyc-verification)                 |
| Verificar un negocio (KYB)                             | —      | ✅ [Registro de negocio](/docs/business-registration)                         |
| Obtener otorgamientos de alcance del usuario           | ✅      | ✅ [Flujo de otorgamiento OAuth](/docs/grant-widget-user-permissions-todo)    |
| Capturar un PAN / CVV de tarjeta                       | ✅      | Solo tokenizado                                                              |
| Capturar un SSN o documento de identidad               | ✅      | Passthrough si ya lo posees                                                  |
| Configurar un PIN de transacción                       | ✅      | —                                                                            |
| Confirmar un monto de transferencia específico         | ✅      | —                                                                            |
| Vincular una cuenta bancaria vía Plaid                 | ✅      | ✅ [Fuentes de fondos](/features/funding-sources)                             |
| Emitir, editar, bloquear o revelar una tarjeta virtual | —      | ✅ [Tarjetas virtuales](/features/virtual-cards)                              |
| Depositar, retirar, transferir, enviar dinero          | —      | ✅ [Billeteras y transferencias](/features/move-funds-with-external-accounts) |
| Comprar tarjetas de regalo, leer el catálogo           | —      | ✅ [Catálogo de comercios](/merchant-catalog)                                 |
| Leer transacciones, anotar, ejecutar aprobaciones      | —      | ✅ [Transacciones](/features/get-all-transactions)                            |
| Emisión masiva de hasta 10,000 tarjetas                | —      | ✅ [Operaciones en lote](/features/virtual-cards)                             |

***

## Puedes ejecutar todo detrás de escena

Este es el punto que más suele pasarse por alto sobre el widget: **no es la única forma de usar Fluz, y no es la forma en que se hace la mayor parte del trabajo.**

Una vez que un usuario ha otorgado alcances a tu aplicación — ya sea a través del widget o mediante el [flujo de otorgamiento OAuth](/docs/grant-widget-user-permissions-todo) independiente — tu servidor posee un token de acceso de usuario. A partir de ese momento, todas las capacidades listadas en la página de [Funciones de la API](/features) están disponibles para ti de forma programática, sin widget abierto y sin usuario mirando:

<CardGroup cols={2}>
  <Card title="Fuentes de fondos" icon="coins" href="/features/funding-sources">
    Vincula tarjetas bancarias y cuentas bancarias Plaid, luego extrae fondos bajo demanda.
  </Card>

  <Card title="Billeteras y transferencias" icon="wallet" href="/features/move-funds-with-external-accounts">
    Abre cuentas de gasto, deposita, retira y mueve fondos internamente o entre cuentas.
  </Card>

  <Card title="Tarjetas virtuales" icon="credit-card" href="/features/virtual-cards">
    Controles de gasto, bloquear/desbloquear, PIN, aprovisionamiento a billeteras, emisión masiva.
  </Card>

  <Card title="Tarjetas open loop" icon="wallet-cards" href="/features/open-loop-cards/send-open-loop-cards">
    Genera enlaces de tarjeta hospedados que los destinatarios canjean, con control total del ciclo de vida del enlace.
  </Card>

  <Card title="Enviar dinero" icon="circle-dollar-sign" href="/features/account-to-account-transfers">
    Busca destinatarios por teléfono o email y transfiere a otras billeteras de Fluz.
  </Card>

  <Card title="Aprobaciones y usuarios autorizados" icon="users" href="/features/approvals-and-requests">
    Agrega miembros del equipo, emíteles tarjetas y enruta solicitudes de aprobación.
  </Card>
</CardGroup>

El trabajo del widget es llevarte al token. Lo que hagas después es completamente del lado del servidor.

***

## Elige cuánto del flujo nos entregas

No tienes que elegir “todo widget” o “toda la API”. La mayoría de las integraciones caen en un punto intermedio, y el factor decisivo suele ser **qué datos sensibles ya posees y quieres seguir poseyendo.**

<Tabs>
  <Tab title="Widget completo">
    **Nos entregas todo el recorrido del usuario.**

    El widget maneja la creación de cuenta, inicio de sesión con teléfono + 2FA, KYC, configuración de PIN, el otorgamiento de permisos y la confirmación de la transacción. Tú renderizas un botón y generas un token firmado.

    * Camino más rápido a producción — medido en horas, no sprints.
    * Cero alcance PCI, cero manejo de datos CIP de tu lado.
    * Menor control sobre el look and feel entre el clic y el callback.

    **Buen encaje:** flujos de payout y retiro, marketplaces, plataformas de gig, programas de recompensas — en cualquier lugar donde quieras que el dinero salga de tu sistema sin convertirte en una institución financiera.
  </Tab>

  <Tab title="Híbrido (el más común)">
    **Tú posees las partes que ya posees; nosotros las partes que prefieres no manejar.**

    Registra al usuario tú mismo con [`registerUser`](/docs/user-registration) usando los datos de perfil que ya recopilaste en el registro. Ejecuta KYC tú mismo con [`verifyUserInformation`](/docs/user-kyc-verification) si ya posees el SSN y la dirección. Luego abre el widget solo para los pasos que realmente lo necesitan:

    * el otorgamiento de permisos,
    * carga de documentos cuando KYC regresa `DECLINED` o necesita revisión,
    * captura del PAN de la tarjeta,
    * configuración de PIN,
    * la pantalla de confirmación de la transacción.

    Tu onboarding sigue siendo tuyo. El usuario nunca vuelve a tipear información que ya tienes. El widget aparece para un momento estrecho y obviamente financiero y luego se quita del medio.

    **Buen encaje:** plataformas con una base de usuarios ya KYC, fintechs, cualquiera que ya haya verificado identidad y no quiera hacer que el usuario lo haga dos veces.
  </Tab>

  <Tab title="Headless / solo API">
    **Sin widget en absoluto.**

    Registra usuarios, verifícalos, vincula fuentes de fondos, emite tarjetas y mueve dinero completamente sobre la API. Obtén otorgamientos de alcance mediante el [flujo de autorización OAuth](/docs/grant-widget-user-permissions-todo) independiente — un redirect, no un embed — u opera en tu propia cuenta de plataforma.

    * Control total sobre cada píxel.
    * **Tú** eres responsable del alcance PCI DSS si recopilas datos de tarjeta, y de la seguridad de cualquier dato CIP que manejes.
    * Algunos flujos aún requieren una superficie hospedada: revelar los detalles completos de una tarjeta a un usuario final y recopilar documentos de identidad suelen ser los que se mantienen.

    **Buen encaje:** emisión masiva, operaciones back-office, corridas de desembolsos, integraciones ERP y contables, y cualquier flujo sin usuario final en el circuito.
  </Tab>
</Tabs>

<Note>
  **Sobre registrar usuarios vía API:** si registras y haces KYC a un usuario tú mismo y *luego* abres el widget, pasa `externalId` en el token de transacción preaprobada para que podamos asociar la sesión con la cuenta que ya creaste en lugar de iniciar una nueva. También puedes pasar `phoneNumber`, `firstName`, `lastName`, `email` y `username` para omitir los pasos correspondientes en el widget. Consulta [Configura tu servidor](/developers/setting-up-your-server).
</Note>

***

## Cómo se relacionan los widgets con las aplicaciones OAuth

Un widget **es** una aplicación OAuth. No es un objeto separado con un modelo de permisos separado — es una app OAuth que incluye un front-end embebible.

<Steps>
  <Step title="Defines el techo (alcances de la app)">
    En la pestaña **Permissions** de tu app, seleccionas los alcances que tu aplicación puede solicitar. Este es el máximo que tu app podrá pedir, sin importar lo que cualquier usuario individual acepte. Los alcances sin los cuales un tipo de widget no puede funcionar están agrupados al final de la pestaña y no se pueden deseleccionar.

    Revisa [Alcances de la aplicación](/docs/application-scopes) para la lista completa — `MAKE_DEPOSIT`, `MAKE_WITHDRAW`, `LIST_PAYMENT`, `CREATE_VIRTUALCARD`, `REVEAL_VIRTUALCARD`, `PURCHASE_GIFTCARD` y el resto.
  </Step>

  <Step title="Configuras a dónde puede ir el otorgamiento (pestaña OAuth)">
    **Origin** — el dominio que hospeda el widget. **Redirect URIs** — a dónde nuestro servidor de autorización puede regresar al usuario, sin parámetros de query, y debe coincidir exactamente en el momento del intercambio. **Webhook URLs** — uno o varios endpoints REST, cada uno opcionalmente suscrito a eventos específicos; una URL sin eventos seleccionados se convierte en un catch-all.

    Consulta [Configurar App Widget](/developers/configure-app-widget).
  </Step>

  <Step title="El usuario establece el piso (alcances de usuario)">
    Cuando se abre el widget, se le muestran al usuario los alcances que solicitaste — agrupados bajo encabezados legibles de alto nivel en lugar de enumeraciones crudas — y los aprueba. Cualquier cosa que rechacen simplemente no se concede.
  </Step>

  <Step title="Ambos otorgamientos deben estar vigentes">
    Los permisos efectivos de una aplicación son la **intersección** del otorgamiento a nivel de app y el otorgamiento a nivel de usuario, y ambos deben no estar vencidos. Esto se aplica en `generateUserAccessToken`, no en tiempo de llamada — por lo que un otorgamiento revocado o caducado se manifiesta como una falla de token, no como un error misterioso a mitad de flujo.
  </Step>

  <Step title="El código se convierte en tokens">
    El otorgamiento produce un `code` de autorización en tu URI de redirección. Intercámbialo en `/token/exchange` con un header de autenticación Basic de `client_id:client_secret` por un `accessToken`, un `refreshToken` y el arreglo `scope` confirmado. Consulta [Intercambiando un código de autorización](/docs/exchanging-an-oauth-authorization-code) y [Actualizando un token de acceso](/docs/refreshing-an-oauth-access-token).
  </Step>
</Steps>

<Warning>
  El token de transacción preaprobada (`patToken`) y el token de acceso OAuth son **cosas diferentes** y hacen trabajos distintos. El `patToken` es un JWT de corta duración y para una sola transacción, firmado con tu `apiSecret`, que autoriza *un* movimiento de *un* monto. El `accessToken` de OAuth es lo que permite que tu servidor actúe sobre la cuenta de un usuario a lo largo del tiempo. Una sesión de widget normalmente involucra ambos.
</Warning>

***

## Cumplimiento PCI y datos sensibles

Cuando el widget está abierto, los campos sensibles dentro de él son de Fluz, no tuyos. El usuario está escribiendo en nuestro iframe, publicando a nuestros servidores, bajo nuestro programa de cumplimiento.

Eso significa que Fluz asume responsabilidad por:

* **Datos de tarjeta.** Los PAN, fechas de expiración y CVV se capturan y almacenan de acuerdo con los requisitos PCI DSS y se cifran en reposo de nuestro lado. Tu página nunca los ve, tus logs nunca los contienen y tu infraestructura se mantiene fuera del alcance PCI para estos flujos.
* **Revelado completo de tarjeta.** Mostrar a un usuario final su propio número de tarjeta virtual es una superficie hospedada de Fluz por la misma razón.
* **Datos CIP e identidad.** SSN, fechas de nacimiento, direcciones y documentos de identidad cargados se recopilan y retienen dentro de nuestro entorno de verificación.
* **PIN.** Configurados y almacenados por nosotros, nunca transmitidos a ti.
* **Credenciales bancarias.** Los flujos de Plaid link se ejecutan dentro del widget; nunca manejas el login bancario del usuario.

Lo que sigue siendo tu responsabilidad: tu `apiSecret` y `client_secret`. La pestaña Installation renderiza fragmentos funcionales que contienen tus credenciales reales, lo cual es conveniente y también un riesgo — **genera el `patToken` en tu servidor, nunca en JavaScript del navegador.** Cualquier cosa en el código fuente de tu página es pública.

<Info>
  Fluz mantiene controles SOC 2 Tipo II y maneja datos de tarjeta de acuerdo con los requisitos PCI DSS. Si tu equipo de cumplimiento necesita documentación para una revisión de proveedor, contacta a tu account manager de Fluz.
</Info>

***

## Obteniendo tu código de embed

No escribes la integración a mano. La pestaña **Installation** de tu app la genera por ti, precargada con el `apiKey` real de tu app, y te da dos selectores:

**Transaction Type** — elige la dirección del movimiento de dinero:

| Etiqueta en la pestaña Installation | `transactionType` en el JWT | Qué sucede                                                                                                                     |
| :---------------------------------- | :-------------------------- | :----------------------------------------------------------------------------------------------------------------------------- |
| **Pay-In**                          | `DEPOSIT`                   | El usuario mueve fondos a Fluz y luego a tu cuenta de gasto de operador. El dinero fluye *hacia* tu plataforma.                |
| **Payout**                          | `WITHDRAW`                  | Los fondos se mueven desde tu cuenta de gasto de operador a la cuenta de Fluz del usuario. El dinero fluye *hacia* tu usuario. |

**Server Language** — el fragmento que genera el token de transacción preaprobada firmado, en el lenguaje que tu backend realmente usa:

<CardGroup cols={4}>
  <Card title="JavaScript" icon="square-code" />

  <Card title="Ruby" icon="gem" />

  <Card title="Python" icon="code" />

  <Card title="Go" icon="code" />

  <Card title="Java" icon="coffee" />

  <Card title="PHP" icon="code" />

  <Card title="C# / .NET" icon="code" />

  <Card title="Más" icon="ellipsis" />
</CardGroup>

Cambia el selector y el bloque de código se reescribe solo — librería JWT correcta, nombres de claims correctos, firma HS256 correcta, caducidad de un día correcta. Cópialo, coloca tu `apiSecret` desde tu almacén de secretos y tendrás un generador de tokens funcional. Cada variante también está documentada en detalle en [Configura tu servidor](/developers/setting-up-your-server).

La parte del lado del cliente es una sola etiqueta de script más una llamada a `FluzEmbedded.init(...)`. Puedes dejarnos renderizar el botón o vincular el modal a un botón que ya tengas. Consulta [Agregar el JS Widget a tu página](/developers/adding-the-js-widget-to-your-page).

La configuración de tu app vive en:

```text theme={null}
https://fluz.app/for-developers/overview/{appId}
```

por ejemplo `https://fluz.app/for-developers/overview/19be9561-a6a1-4e02-8243-10ede908ef33`. Las pestañas en la parte superior — **Overview**, **Permissions**, **OAuth**, **Installation** — mapean exactamente a los pasos anteriores.

***

## Comienza desde una plantilla

No comienzas desde una app en blanco. Desde el panel de desarrollador, elige **Browse templates** y selecciona la más cercana a lo que estás construyendo. Una plantilla preconfigura el tipo de app, los alcances requeridos, la dirección de la transacción y la secuencia de pantallas que verá el usuario — por lo que una app nueva es funcional en el momento en que terminas de nombrarla.

Las plantillas disponibles hoy incluyen:

| Plantilla                            | Lo que configura                                                                                                                                    |
| :----------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Withdraw to a virtual Mastercard** | Un flujo de `Payout` que termina en una tarjeta virtual de Fluz utilizable al instante. Preselecciona los alcances de retiro y creación de tarjeta. |
| **OAuth Integration**                | Una app solo de permisos sin UI embebida — para integraciones headless y basadas en redirect.                                                       |

<Note>
  **Trata la plantilla como un punto de partida, no una especificación.** Después de crearla, ve a la pestaña **Permissions** y moldea la app según lo que realmente intentas hacer — agrega los alcances que tu caso de uso necesita, quita los que no. Un widget de payout que luego emitirá tarjetas en nombre del usuario necesita `CREATE_VIRTUALCARD`; uno que solo mueve efectivo no. Solicitar menos alcances significa una pantalla de consentimiento más corta y una mayor tasa de finalización, así que pide lo que necesitas y nada más.
</Note>

Creación de una app: [Agregar un nuevo App Widget](/developers/add-a-widget) · Configuración: [Configurar App Widget](/developers/configure-app-widget) · Apagarla: [Deshabilitar o eliminar tu app](/developers/disable-or-delete-your-app)

***

## Lo que ve el usuario final

Una vez que un usuario llega a una página que hospeda tu widget y realiza la acción que abre el modal:

<Steps>
  <Step title="Iniciar sesión o registrarse">
    El usuario se autentica en su cuenta de Fluz con un código 2FA enviado a su teléfono. Si no tiene una cuenta, la crea aquí. Pasar `phoneNumber` en el `patToken` salta directamente al paso de ingreso del código.
  </Step>

  <Step title="KYC">
    Si ya posees el SSN del usuario, pásanoslo y lo validamos. Si no, el widget ejecuta el flujo KYC completo. Las respuestas son `APPROVED`, `DECLINED`, `DUPLICATE` o `ERROR` — consulta [Verificación KYC de usuario](/docs/user-kyc-verification) para ver qué significa cada una y cuántos intentos obtiene un usuario.
  </Step>

  <Step title="Otorgar permisos">
    El usuario revisa y aprueba los alcances que solicitó tu app.
  </Step>

  <Step title="Configurar un PIN">
    Una medida de seguridad a nivel de Fluz, solicitada nuevamente más adelante para acciones que requieren confirmación elevada.
  </Step>

  <Step title="Confirmar la transacción">
    El usuario ve el monto y la dirección y aprueba o descarta. En cualquier caso, recibes un evento.
  </Step>
</Steps>

### Pay-In: fondos hacia tu plataforma

<Info>
  Verifica primero el saldo de Fluz del usuario para confirmar que puede cubrir la transacción.
</Info>

1. El usuario ingresa un monto de depósito y hace clic en tu botón.
2. El widget presenta una pantalla de confirmación.
   * **Confirmado** → iniciamos la transferencia desde la cuenta de gasto del usuario a la tuya.
   * **Denegado o descartado** → enviamos un evento.
3. Recibes un evento de finalización o de falla.
4. Verifica tu propio saldo de Fluz para confirmar la liquidación.

### Payout: fondos hacia tu usuario

<Info>
  Verifica primero el saldo de Fluz de tu cuenta. Si no puedes cubrir la transferencia, inicia un depósito desde tu fuente de fondos. Pone en cuarentena o retén los fondos del usuario de tu lado para evitar doble gasto mientras la transferencia está en curso.
</Info>

1. El usuario ingresa un monto de retiro y hace clic en tu botón.
2. El widget presenta una pantalla de confirmación.
   * **Confirmado** → iniciamos la transferencia desde tu cuenta de gasto de operador a la del usuario.
   * **Denegado o descartado** → enviamos un evento.
3. Recibes un evento de finalización o de falla.
4. El widget muestra al usuario que su retiro está completo y le da acceso directo a su tarjeta virtual de Fluz.

<Note>
  Cada llamada que mueve dinero necesita un `jti` único en el token para idempotencia, y un `idempotencyKey` único del lado de la API. Consulta [Idempotencia](/docs/idempotency-requests).
</Note>

***

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Agregar un widget" icon="plus" href="/developers/add-a-widget">
    Crea tu primera app desde una plantilla.
  </Card>

  <Card title="Configurar OAuth y permisos" icon="shield" href="/developers/configure-app-widget">
    Alcances, orígenes, URIs de redirección, webhooks.
  </Card>

  <Card title="Configura tu servidor" icon="server" href="/developers/setting-up-your-server">
    Genera el token de transacción preaprobada en tu lenguaje.
  </Card>

  <Card title="Embeber el widget" icon="code" href="/developers/adding-the-js-widget-to-your-page">
    Etiqueta de script, llamada init, vinculación de botón.
  </Card>

  <Card title="Todo lo que puede hacer la API" icon="sparkles" href="/features">
    Toda la superficie de capacidades, disponible del lado del servidor.
  </Card>

  <Card title="Construir una plataforma" icon="building-2" href="/build-a-platform">
    Ejecuta cada capacidad en cuentas conectadas con tokens con alcance de cliente.
  </Card>
</CardGroup>
