> ## 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 aplicaciones OAuth

> Cómo tu aplicación obtiene permiso para actuar en la cuenta de un usuario de Fluz: las credenciales involucradas, el modelo de permisos, el ciclo de vida del token y qué página leer a continuación.

## Por qué existe OAuth aquí

Tu aplicación ya puede hacer todo lo que ofrece la API de Fluz **en tu propia cuenta**. Generas un token con tu clave de API y listo — ver [Autenticación](/concepts/authentication) y [Credenciales de API](/get-started/api-credentials).

Una aplicación OAuth es lo que necesitas cuando la cuenta no es tuya.

En el momento en que quieras emitir una tarjeta en la billetera de un cliente, extraer de su cuenta bancaria vinculada, leer sus transacciones o pagarle, necesitas el permiso explícito de esa persona — y lo necesitas en una forma que Fluz pueda verificar, acotar (scope), expirar y revocar. Eso es una aplicación OAuth: **una identidad registrada para tu software, más un mecanismo de consentimiento que convierte la aprobación de un usuario en un token que tu servidor puede usar.**

<Info>
  Una vez que tengas un token con alcance al cliente, la API es idéntica. `createVirtualCard` con tu propio token crea una tarjeta en tu billetera; la misma mutación con un token del cliente la crea en la suya. OAuth cambia *de quién es la cuenta que tocas*, no lo que puedes hacer.
</Info>

***

## ¿Necesitas una?

<Tabs>
  <Tab title="No — solo tu propia cuenta">
    Estás emitiendo tarjetas, comprando tarjetas de regalo o moviendo dinero **dentro de tu propia cuenta de Fluz**: un motor de desembolsos, una corrida de tarjetas en lote, una herramienta interna de gasto, una sincronización de ERP.

    Usa la clave de API de tu aplicación para llamar `generateUserAccessToken` directamente. Sin app OAuth, sin pantalla de consentimiento, sin redirección. Comienza en [Credenciales de API](/get-started/api-credentials).
  </Tab>

  <Tab title="Sí — cuentas de clientes">
    Estás construyendo una plataforma donde **tus usuarios tienen sus propias cuentas de Fluz** y actúas en su nombre.

    Necesitas una aplicación OAuth, y cada usuario debe otorgar scopes a tu app una vez. Luego retienes un token actualizable con alcance al cliente. Comienza con [Crear una app OAuth](/create-an-o-auth-app), luego consulta [Crear una plataforma](/build-a-platform).
  </Tab>

  <Tab title="Ya tienes una">
    Estás incrustando un [Widget de Fluz](/developers/widgets).

    Un widget **es** una aplicación OAuth — una que viene con un front end hospedado para el paso de consentimiento en lugar de hacerte construir un flujo de redirección. Las credenciales, los scopes y la mecánica de tokens en esta página aplican por igual. Ver [Configurar App Widget](/developers/configure-app-widget).
  </Tab>
</Tabs>

***

## Tres conjuntos de credenciales, tres trabajos distintos

La fuente de confusión más común en esta sección es que una aplicación de Fluz lleva más de un par de credenciales, y no son intercambiables.

| Credencial                           | Dónde vive                              | Para qué sirve                                                                                                                                                                        | ¿Alguna vez sale de tu servidor?              |
| :----------------------------------- | :-------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :-------------------------------------------- |
| **API Key** / **API Secret**         | Pestaña Overview de tu app              | Identifica tu *aplicación*. Genera tokens en tu propia cuenta (`Authorization: Basic <API_KEY>`) y firma tokens de transacción preaprobados del widget.                               | Nunca                                         |
| **Client ID** / **Client Secret**    | Pestaña Overview de tu app              | Identifica tu app ante el *servidor de autorización*. Se usa en la URL de authorize y para intercambiar o refrescar códigos (`Authorization: Basic base64(client_id:client_secret)`). | El Client ID es público; el secret nunca      |
| **Access Token** / **Refresh Token** | Devueltos por usuario, por otorgamiento | Actúa en la cuenta de un usuario específico con un conjunto específico de scopes.                                                                                                     | Se envía como `Authorization: Bearer <token>` |

<Warning>
  Cada secreto aquí otorga autoridad. Una filtración de `apiSecret` permite a alguien firmar transacciones como tu plataforma; una filtración de `client_secret` permite a alguien intercambiar códigos como tu app. Mantén ambos del lado del servidor, fuera de bundles del navegador, fuera de binarios móviles, fuera del control de versiones.
</Warning>

***

## El modelo de permisos

Fluz aplica permisos en dos niveles, y el acceso efectivo de una aplicación es la **intersección** de ambos.

<Steps>
  <Step title="Otorgamiento a nivel de app — el techo">
    Configurado en la pestaña **Permissions** de tu app. Este es el máximo que tu aplicación podrá solicitar jamás, independientemente de cualquier usuario. Un scope que no hayas habilitado aquí se ignora silenciosamente si lo pones en una URL de authorize — la solicitud no fallará, simplemente no se otorgará ese scope.

    Algunos scopes son administrados por Fluz en lugar de ser autoseleccionados. `PCI_COMPLIANCE` se otorga solo a nivel de aplicación, a desarrolladores que hayan demostrado cumplimiento con PCI DSS, y no puede solicitarse al generar un token.
  </Step>

  <Step title="Otorgamiento a nivel de usuario — el piso">
    Configurado por el usuario final en la pantalla de consentimiento. Ven los scopes que solicitaste — agrupados bajo encabezados legibles de alto nivel en lugar de valores enum en crudo — y los aprueban. Cualquier cosa que rechacen no se otorga.
  </Step>

  <Step title="Ambos deben estar vigentes">
    Validado en `generateUserAccessToken`, no en tiempo de llamada. Ambos otorgamientos deben existir y no haber expirado. Un otorgamiento revocado o vencido, por lo tanto, aparece como un **fallo de generación de token**, no como un error de permiso a mitad de un flujo — que suele ser el primer lugar a revisar cuando una integración que funcionaba deja de hacerlo.
  </Step>
</Steps>

Scopes por capacidad:

| Área                | Scopes                                                                              |
| :------------------ | :---------------------------------------------------------------------------------- |
| Fuentes de fondos   | `LIST_PAYMENT`, `MANAGE_PAYMENT`                                                    |
| Depósitos y retiros | `MAKE_DEPOSIT`, `MAKE_WITHDRAW`                                                     |
| Tarjetas de regalo  | `LIST_OFFERS`, `PURCHASE_GIFTCARD`, `REVEAL_GIFTCARD`, `LIST_PURCHASES`             |
| Tarjetas virtuales  | `CREATE_VIRTUALCARD`, `EDIT_VIRTUALCARD`, `REVEAL_VIRTUALCARD`, `CREATE_SHARE_LINK` |
| Datos de tarjeta    | `PCI_COMPLIANCE` (a nivel de aplicación, administrado por Fluz)                     |

Usa `getApplicationScopes` para leer lo que está otorgado actualmente. Referencia completa: [Application Scopes](/application-scopes).

<Note>
  **Pide menos.** Una pantalla de consentimiento más corta convierte mejor, y un token más acotado limita el daño si se filtra. Solicita lo que el flujo frente a ti necesita y genera un token nuevo cuando necesites más.
</Note>

***

## El ciclo de vida, de extremo a extremo

Cada paso a continuación es una página de inmersión profunda en esta sección. Este es el mapa; las páginas son el territorio.

<Steps>
  <Step title="Crea la app">
    Desde el panel de desarrollador, elige **Browse templates** y agrega la plantilla **OAuth Integration**. Ponle nombre, subtítulo y descripción — esos tres campos son lo que tus usuarios verán en la pantalla de consentimiento, así que escríbelos para un humano, no para tu issue tracker.

    → [Crear una app OAuth](/create-an-o-auth-app)
  </Step>

  <Step title="Configúrala">
    En la pestaña **Permissions**, selecciona tu techo de scopes. En la pestaña **OAuth**, configura tus **Redirect URIs** (públicas, sin parámetros de query, cualquier cantidad de ellas) y tus **Webhook URLs** (cada una opcionalmente suscrita a eventos específicos; una URL sin ninguno seleccionado se convierte en catch-all). Agrega un avatar y un logomark en **Overview** — la pantalla de consentimiento se ve incompleta sin ellos.

    → [Configurar app OAuth](/configure-o-auth-app)
  </Step>

  <Step title="Envía al usuario a autorizar">
    Redirige a `/authorize` con `response_type=code`, tu `client_id`, un `redirect_uri` registrado, una lista de `scopes` delimitada por espacios y un valor opcional `state` que quieres que te devuelvan intacto.

    → [Flujo de otorgamiento OAuth orientado al cliente](/client-facing-o-auth-grant-flow)
  </Step>

  <Step title="Recibe el código">
    Tras la aprobación, Fluz redirige a tu `redirect_uri` con `code` y tu `state` original. En caso de una mala configuración, la redirección lleva un mensaje de error que describe lo que no coincidió.
  </Step>

  <Step title="Intercambia el código por tokens">
    Llama a `/token/exchange` con el `code` y **el mismo `redirect_uri` exacto**, autenticado con `Authorization: Basic base64(client_id:client_secret)`. Recibirás un `accessToken`, un `refreshToken`, marcas de tiempo de expiración y el arreglo de scopes confirmados.

    → [Intercambiar un código de autorización OAuth](/exchanging-an-o-auth-authorization-code)
  </Step>

  <Step title="Refresca, no vuelvas a pedir permiso">
    Llama a `/token/refresh` con el `refresh_token` y el mismo encabezado Basic auth. Los access tokens son deliberadamente de corta duración — del orden de diez minutos — mientras que los refresh tokens duran aproximadamente un mes. Refresca silenciosamente en segundo plano; solo vuelve a enviar a un usuario por consentimiento cuando el refresh token haya expirado o el otorgamiento haya sido revocado.

    → [Refrescar un OAuth accessToken](/refresh-o-auth-access-token)
  </Step>

  <Step title="Pasa a producción">
    Staging y producción son entornos separados con aplicaciones y credenciales separadas. Nada se traslada — registras la app, los Redirect URIs y los endpoints de webhook nuevamente contra los hosts de producción.

    → [Despliegue a producción](/deploying-to-production)
  </Step>
</Steps>

***

## Reglas que muerden

Vale la pena interiorizarlas antes de comenzar, porque cada una de estas falla de forma silenciosa o confusa.

<AccordionGroup>
  <Accordion title="Los Redirect URIs deben coincidir exactamente — dos veces">
    El `redirect_uri` que envías a `/authorize` debe estar registrado en tu app, y el que envías a `/token/exchange` debe ser idéntico byte a byte al que usaste en `/authorize`. Las barras finales, `http` vs `https`, y el uso de mayúsculas en el host cuentan. No registres parámetros de query en el propio URI — usa `state` para llevar contexto.
  </Accordion>

  <Accordion title="Los scopes no habilitados se ignoran, no se rechazan">
    Si solicitas un scope que no marcaste en la pestaña Permissions, la solicitud de authorize igual tendrá éxito — el scope se descartará. Lee siempre el arreglo `scope` en la respuesta del intercambio y trátalo, no a tu solicitud, como la verdad sobre lo que puedes hacer.
  </Accordion>

  <Accordion title="Un código de autorización es de un solo uso y corta vida">
    Intercámbialo inmediatamente, del lado del servidor, una sola vez. Si tu manejador de redirección puede reproducirse — un usuario refrescando la página de callback, un prefetcher de enlaces — asegúrate de que un segundo intento no corrompa el estado.
  </Accordion>

  <Accordion title="La autenticación Basic es base64 del par, no de cada parte">
    `Authorization: Basic <base64(client_id + ":" + client_secret)>`. Codifica la cadena unida. La mayoría de los fallos de integración en el paso de intercambio se deben a esto.
  </Accordion>

  <Accordion title="`state` es tu único canal de retorno">
    La redirección es una navegación de navegador nueva. Si necesitas saber qué usuario, qué flujo o a qué página regresar, pon una referencia firmada o buscada por el servidor en `state`. No pongas nada sensible allí — viaja a través del navegador del usuario.
  </Accordion>

  <Accordion title="Las fallas de token suelen ser fallas de otorgamiento">
    Si `generateUserAccessToken` empieza a fallar para un usuario que funcionaba ayer, verifica si el otorgamiento a nivel de app o a nivel de usuario expiró o fue revocado, antes de revisar tu código.
  </Accordion>
</AccordionGroup>

***

## Apps OAuth vs. widgets

Ambas son aplicaciones. Ambas usan el modelo de permisos anterior. La diferencia es quién construye la superficie de consentimiento.

|                                             | Aplicación OAuth                              | Widget                                     |
| :------------------------------------------ | :-------------------------------------------- | :----------------------------------------- |
| UI de consentimiento                        | Tú construyes el flujo de redirección         | Fluz lo renderiza en un modal en tu página |
| El usuario sale de tu sitio                 | Sí, a `/authorize`                            | No                                         |
| Datos sensibles (PAN, SSN, documentos, PIN) | Tú los manejas, y estás en alcance para ellos | Fluz los recopila y encripta               |
| Registro y KYC                              | Tuyos para construir, o vía API               | Incluido en el flujo                       |
| Control sobre la presentación               | Completo                                      | Limitado al branding                       |
| Tiempo hasta el primer flujo funcional      | Días                                          | Horas                                      |

Puedes combinarlos: registra y realiza KYC de usuarios vía API, luego abre un widget solo para consentimiento y captura sensible. Ver [Widgets incrustados](/developers/widgets) para los patrones híbridos.

***

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Crear una app OAuth" icon="plus" href="/create-an-o-auth-app">
    Registra tu aplicación desde la plantilla OAuth Integration.
  </Card>

  <Card title="Configurar app OAuth" icon="sliders" href="/configure-o-auth-app">
    Scopes, redirect URIs, webhooks, branding.
  </Card>

  <Card title="Flujo de otorgamiento orientado al cliente" icon="user-check" href="/client-facing-o-auth-grant-flow">
    Construye la URL de authorize y maneja el callback.
  </Card>

  <Card title="Intercambiar un código de autorización" icon="arrow-left-right" href="/exchanging-an-o-auth-authorization-code">
    Convierte un código en un access token y un refresh token.
  </Card>

  <Card title="Refrescar un access token" icon="refresh-cw" href="/refresh-o-auth-access-token">
    Mantente autorizado sin volver a pedir permiso al usuario.
  </Card>

  <Card title="Despliegue a producción" icon="rocket" href="/deploying-to-production">
    Vuelve a registrar contra hosts en vivo y sal a producción.
  </Card>
</CardGroup>

<Info>
  ¿Estás construyendo una plataforma donde cada uno de tus clientes tiene una cuenta de Fluz? [Crear una plataforma](/build-a-platform) recorre todo el patrón de extremo a extremo, y cada capacidad en [Características de la API](/features) funciona de manera idéntica en una cuenta conectada.
</Info>
