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

> Lee el catálogo de comercios, entiende ofertas fijas versus variables, compra una tarjeta y revelala: todo el ciclo de tarjeta de regalo y qué página leer en cada paso.

Comprar una tarjeta de regalo a través de Fluz son cuatro pasos, y cada uno tiene su propia página. Este es el mapa.

<Steps>
  <Step title="Encuentra la oferta">
    Extrae el catálogo o pide la mejor tasa en un comercio. → [Leer el catálogo](#reading-the-catalog)
  </Step>

  <Step title="Confirma que el monto es comprable">
    Fija o variable, con inventario o generada bajo demanda. → [Fijas vs. variables](#fixed-vs-variable-offers)
  </Step>

  <Step title="Compra">
    Una mutación, una tarjeta, una clave de idempotencia. → [Comprar](#buying-a-card)
  </Step>

  <Step title="Revela">
    Obtén el código, PIN o URL, y muéstralo correctamente. → [Revelar](#revealing-the-card)
  </Step>
</Steps>

<Warning>
  **Las tasas cambian constantemente.** Fluz re-precia continuamente para ofrecer a los clientes la mejor oferta disponible, y tus tasas están personalizadas para tu cuenta. Nunca caches una tasa para comprar más tarde: vuelve a confirmarla inmediatamente antes de comprar.
</Warning>

***

## Vocabulario

Cinco términos hacen la mayor parte del trabajo en esta sección, y tres suenan parecidos.

| Término             | Qué es                                                                                                                   |
| :------------------ | :----------------------------------------------------------------------------------------------------------------------- |
| **Merchant**        | La marca — Starbucks, Best Buy. Tiene un `merchantId` y un `slug` legible por humanos.                                   |
| **Offer**           | Un acuerdo específico que se puede comprar de ese comercio, con su propio `offerId`. Un comercio puede tener varios.     |
| **Offer rate**      | La recompensa asociada a una oferta — cashback, boosts, denominaciones elegibles, métodos de pago permitidos.            |
| **Denomination**    | El valor facial de la tarjeta. Elegido de una lista preestablecida o cualquier monto en un rango.                        |
| **Delivery format** | Cómo llega la tarjeta: `URL`, `CODES`, `PIN_AS_CODE`, `PIN_WITH_URL` o `CODE_WITH_PREFIX`. Determina cómo la renderizas. |

Dos identificadores se confunden fácilmente: `merchantId` identifica la marca, `offeringMerchantId` identifica a la parte que ofrece ese acuerdo en particular. Compras contra un `offerId` o un `slug`, nunca contra un `merchantId`.

***

## Leyendo el catálogo

Tres caminos de entrada, para tres trabajos distintos.

| Enfoque                         | Consulta                                     | Úsalo cuando                                                                                          |
| :------------------------------ | :------------------------------------------- | :---------------------------------------------------------------------------------------------------- |
| **Catálogo completo**           | `getMerchants`                               | Estás construyendo un escaparate navegable, sincronizando un catálogo local o comparando entre marcas |
| **Mejor tasa para un comercio** | `getOfferQuote`                              | Ya conoces la marca y el monto y solo quieres la mejor tasa de hoy                                    |
| **Exportación CSV**             | Dashboard → **Stores** → generar exportación | Análisis, finanzas o una persona quiere una hoja de cálculo                                           |

Filtra `getMerchants` a tarjetas de regalo con `offerTypes: { giftCardOffer: true, cardLinkedOffer: false }`. Las ofertas vinculadas a tarjeta existen en el catálogo, pero hoy solo las ofertas de tarjeta de regalo y exclusivas se pueden comprar a través del API.

<Note>
  **El catálogo completo es un archivo en caché, actualizado dos veces al día.** `getOfferQuote` es en vivo. Si la tasa exacta importa al momento de la compra — y normalmente importa — cotiza antes de comprar en lugar de confiar en una extracción de catálogo de esta mañana. Las tasas promocionales se reflejan en ambos, incluyendo en exportaciones CSV generadas durante una promoción.
</Note>

Ambas consultas tienen límite de tasa, así que pagina el catálogo completo en lugar de solicitarlo en una sola llamada. → [Obtener Catálogo](/get-catalog) · [Obtener Ofertas de Tarjetas de Regalo](/get-gift-card-offers) · [Obtener la Mejor Oferta](/get-best-offer)

### Ofertas exclusivas

Las tasas están personalizadas por cuenta. Si la tuya tiene tasas negociadas, aparecen como ofertas con `type: "EXCLUSIVE_RATE_OFFER"` que llevan un `exclusiveRateId`. Pasa ese ID a `purchaseGiftCard` para forzar la compra en esa tasa; si lo omites, Fluz elige la mejor disponible.

***

## Ofertas fijas vs. variables

Esta es la distinción que más da forma a cómo construyes, y un comercio puede tener ambas.

<CardGroup cols={2}>
  <Card title="FIJA" icon="lock">
    La tarjeta viene en **denominaciones preestablecidas** — $25, $50, \$100 — y compras una de ellas exactamente.

    Con frecuencia respaldada por **inventario real** que Fluz posee, por lo que las ofertas fijas suelen tener **mejores tasas y límites de compra más altos**.

    El inventario es finito. Se agota.
  </Card>

  <Card title="VARIABLE" icon="sliders-horizontal">
    Eliges **cualquier monto dentro de un rango mínimo/máximo**, y la tarjeta se genera en tiempo real.

    No hay inventario que agotar — suministro efectivamente ilimitado.

    Usualmente una **tasa de recompensa menor** que la oferta fija de la misma marca.
  </Card>
</CardGroup>

La compensación práctica: las ofertas fijas pagan mejor pero pueden agotarse a mitad de la ejecución; las ofertas variables siempre funcionan pero pagan menos. Los pedidos de alto volumen usualmente toman primero el inventario fijo y caen a variable.

### Dónde leer los montos comprables

Dos campos lo deciden, y la combinación determina en cuál campo está la respuesta. Si te equivocas, enviarás montos que la oferta no puede cumplir.

| `denominationsType` | `hasStockInfo` | Los montos comprables viven en        | Significado                                                             |
| :------------------ | :------------- | :------------------------------------ | :---------------------------------------------------------------------- |
| `FIXED`             | `true`         | `stockInfo` → `StockInfoFixedType`    | Denominaciones específicas con un `availableStock` contable             |
| `FIXED`             | `false`        | `offerRates.denominations`            | Denominaciones preestablecidas, sin restricción de inventario publicada |
| `VARIABLE`          | `true`         | `stockInfo` → `StockInfoVariableType` | Un rango `minDenomination`–`maxDenomination`                            |
| `VARIABLE`          | `false`        | `offerRates.denominations`            | Cualquier monto en el rango publicado                                   |

<Warning>
  `stockInfo` es un **tipo unión**. Debes consultarlo con fragmentos en línea para *ambas* formas, o no obtendrás nada para una de ellas:

  ```graphql theme={null}
  stockInfo {
    ... on StockInfoFixedType    { __typename denomination availableStock }
    ... on StockInfoVariableType { __typename description minDenomination maxDenomination }
  }
  ```

  Incluye siempre ambos fragmentos, incluso cuando creas saber cuál obtendrás. Ver [Cómo funciona el API GraphQL](/concepts/graphql).
</Warning>

Observa que "tiene información de inventario" no significa "tiene inventario contable". En una oferta variable, `stockInfo` devuelve un *rango*, no una cantidad. Solo `StockInfoFixedType` lleva un número `availableStock` contra el que puedes decrementar.

Rellenar `stockInfo` requiere que Fluz confirme inventario con el proveedor, y los tiempos de respuesta del proveedor varían, por lo que solicitarlo hace la consulta más lenta. Pídelo solo cuando estés a punto de actuar sobre ello. → [Obtener Inventario en Ofertas con Stock](/get-inventory)

***

## Comprar una tarjeta

Una mutación: `purchaseGiftCard`. Tres decisiones.

### 1. Cómo elegir la oferta

| Tú pasas                         | Comportamiento                                                                                                      |
| :------------------------------- | :------------------------------------------------------------------------------------------------------------------ |
| `offerId`                        | **Anclada.** Compra esa oferta exacta. Si está agotada, la llamada falla — sin fallback.                            |
| `merchantSlug`                   | **Selección automática.** Compra la mejor tasa disponible para esa marca, retrocediendo según cambie el inventario. |
| `merchantSlug` + `minRewardRate` | Selección automática **con piso.** Falla en lugar de comprar por debajo de tu tasa mínima.                          |
| `exclusiveRateId`                | Fuerza una tasa negociada específica.                                                                               |

Anclar te da certeza sobre la tasa; la selección automática te da certeza sobre el cumplimiento. `merchantSlug` + `minRewardRate` es el punto medio y usualmente el valor predeterminado correcto para pedidos automatizados.

### 2. Cómo pagar

Se requiere al menos una fuente de fondos, y puedes combinar tu saldo de Fluz con otra.

| Campo                                            | Qué hace                                                     |
| :----------------------------------------------- | :----------------------------------------------------------- |
| `balanceAmount`                                  | **Cuánto** pagar desde tu saldo de Fluz                      |
| `userCashBalanceId`                              | **Qué cuenta de gasto** aporta ese saldo                     |
| `bankCardId` / `bankAccountId` / `paypalVaultId` | Fuentes de fondos externas                                   |
| `defaultToBalance`                               | Recurre al saldo si otro método falla. Por defecto es `true` |

<Warning>
  **Si tu cuenta tiene más de una cuenta de gasto, pasa siempre `userCashBalanceId` explícitamente.** Si lo omites, Fluz toma de la cuenta marcada `isDefault`, lo que puede cambiar sin que tu código cambie, redirigiendo silenciosamente de dónde proviene tu dinero. Esta es la causa más común de fallas inesperadas por fondos insuficientes.

  En canalizaciones automatizadas, también establece `defaultToBalance: false` para que una compra use la cuenta que nombraste o falle limpiamente.
</Warning>

### 3. Idempotencia

`idempotencyKey` es obligatorio, y es la diferencia entre un reintento y una compra doble. Una clave por tarjeta prevista, reutilizada en cada reintento de esa misma tarjeta. → [Idempotencia](/docs/idempotency-requests)

→ [Comprar Tarjeta de Regalo](/purchase-gift-card)

### Comprar más de una

**Una llamada compra exactamente una tarjeta**, en una oferta, a una tasa. No hay campo de cantidad ni mezcla entre ofertas. Para diez tarjetas, envía diez llamadas con diez claves de idempotencia distintas.

Lo que sucede cuando sobrepasas el inventario depende de cómo elegiste la oferta:

* **Anclada (`offerId`)** — una vez que la oferta con stock se agota, las llamadas restantes fallan. Sin fallback automático.
* **Selección automática (`merchantSlug`)** — las llamadas restantes pasan a la siguiente mejor oferta, a menudo una variable con una tasa menor, a menos que `minRewardRate` lo bloquee.

→ [Comprar en Lote](/purchase-in-bulk)

### Pedidos a volumen

Las compras contra la misma cuenta de Fluz se procesan **secuencialmente**. Si envías un lote grande de una vez, las llamadas se encolan unas detrás de otras, tardando ocasionalmente minutos en responder.

<Note>
  **Un timeout del cliente no es una cancelación.** Fluz sigue procesando una solicitud por la que dejaste de esperar. Trata un timeout como un resultado *desconocido*, nunca como una falla.

  Resuélvelo reintentando con la **misma** `idempotencyKey` — el reintento devuelve la compra original si ya tuvo éxito, y no cobrará doble. Emitir una clave nueva para una compra que ya intentaste es exactamente cómo ocurren los pedidos duplicados.

  Configura los timeouts del cliente en alrededor de un minuto, marca el paso de las solicitudes en tandas en lugar de todas a la vez y distribuye el volumen pesado entre múltiples cuentas.
</Note>

***

## Revelar la tarjeta

Una compra te da un `giftCardId`. Los detalles de canje llegan en una segunda llamada.

<Steps>
  <Step title="Obtén la tarjeta de regalo">
    Omite esto si acabas de comprar y ya tienes el `giftCardId`. De lo contrario, `getGiftCards` las lista con `purchaseId`, `purchaseDisplayId`, `purchaseValue`, `currentValue` y `status` — suficiente para conciliar pedidos sin revelar cada tarjeta.
  </Step>

  <Step title="Revelarla">
    `revealGiftCardByGiftCardId` devuelve `code`, `pin`, `url` y `termsAndConditions`.
  </Step>
</Steps>

Tres cosas que suelen atrapar a la gente:

* **No todas las tarjetas tienen los tres campos.** Algunos comercios emiten un código sin PIN; otros emiten solo una URL. Fluz transmite lo que el comercio proporciona — maneja nulos.
* **Renderiza según `deliveryFormat` y `barcodeType`,** y toma `deliveryFormat` de `getGiftCards`, no de la oferta actual del comercio. Las ofertas cambian; la tarjeta se emitió bajo el formato vigente al momento de la compra. `barcodeType` es `NONE`, `C128`, `PDF417` o `QRCODE`; cuando es `NONE`, considera mostrar el `faceplateUrl` en su lugar.
* **Es posible que los detalles no estén listos al instante.** Haz polling con backoff exponencial — 300 ms, duplicando, con tope de tres minutos — y detente tan pronto como regresen los detalles.

→ [Ver Tarjetas de Regalo](/view-gift-card)

***

## Alcances (scopes)

| Scope               | Necesario para                           |
| :------------------ | :--------------------------------------- |
| `LIST_OFFERS`       | `getMerchants`, `getOfferQuote`          |
| `PURCHASE_GIFTCARD` | `purchaseGiftCard`                       |
| `REVEAL_GIFTCARD`   | `revealGiftCardByGiftCardId`             |
| `LIST_PURCHASES`    | `getUserPurchases`, historial de compras |
| `LIST_PAYMENT`      | `getUserCashBalances`, `getWallet`       |

Habilítalos en la pestaña **Permissions** de tu app antes de construir. Un scope que solicitas pero no has habilitado se descarta silenciosamente. → [Configurar App OAuth](/configure-o-auth-app)

***

## Cuando las cosas fallan

| Código    | Significado                                              |
| :-------- | :------------------------------------------------------- |
| `GC-0002` | El monto de compra o el monto de Fluz Pay no es positivo |
| `GC-0003` | No se pudo recuperar el registro de la tarjeta de regalo |
| `GC-0004` | La compra falló — intenta otro método de pago            |
| `GC-0006` | No se pudo revelar la tarjeta                            |

Lista completa: [Códigos de Error de Tarjetas de Regalo](/gift-card-error-codes).

Antes de reembolsar a un usuario final en una compra fallida o con timeout, **reintenta con la misma `idempotencyKey` o busca la compra por ID.** Las solicitudes con timeout frecuentemente tuvieron éxito, y el código permanece revelable hasta que se reembolsa la compra.

***

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Obtener catálogo" icon="list" href="/get-catalog">
    Extrae comercios y sus ofertas.
  </Card>

  <Card title="Obtener la mejor oferta" icon="badge-percent" href="/get-best-offer">
    Cotización en vivo para un comercio y monto.
  </Card>

  <Card title="Obtener inventario" icon="package" href="/get-inventory">
    Stock en ofertas fijas con inventario.
  </Card>

  <Card title="Comprar una tarjeta de regalo" icon="shopping-cart" href="/purchase-gift-card">
    La mutación, completa.
  </Card>

  <Card title="Comprar en lote" icon="layers" href="/purchase-in-bulk">
    Pedir muchas tarjetas y el comportamiento al agotarse.
  </Card>

  <Card title="Ver tarjetas de regalo" icon="eye" href="/view-gift-card">
    Revelar códigos, PINs y URLs.
  </Card>
</CardGroup>
