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

# Aprovisionamiento por inserción en billeteras digitales

Usa la consulta `getCardProvisioningUrl` para emitir una URL corta de un solo uso que —al abrirse en el teléfono del usuario final— inicia Fluz en el dispositivo y agrega la tarjeta virtual de una oferta dada a Apple Pay (iOS) o Google Pay (Android).

Puedes entregar la URL como prefieras: un código QR, un SMS, un email o un botón dentro de tu app. Fluz se encarga del flujo de aprovisionamiento en la billetera a partir de ahí.

## Cuándo usarlo

En cualquier lugar donde normalmente le entregarías una tarjeta virtual al usuario y quieras que pueda agregarla a la billetera de su teléfono sin teclear el número de tarjeta. Flujos típicos:

* Después de crear una oferta de tarjeta para el usuario, presenta un código QR en pantalla.
* Envía por texto o email la URL al tarjetahabiente.
* Inserta un botón “Agregar a Apple Pay / Google Pay” en tu propia app móvil.

<Info>
  **Requisitos previos:** un token de acceso OAuth para el usuario final que incluya el alcance `CREATE_VIRTUALCARD`, y una oferta de tarjeta virtual para el usuario (creada mediante el API de ofertas existente).
</Info>

<Warning>
  La autenticación básica (`client_id` / `client_secret`) **no** es aceptada en esta consulta: debe ser un token bearer en contexto de usuario.
</Warning>

## La consulta

```graphql theme={null}
query ProvisionCard($offerId: String!) {
  getCardProvisioningUrl(input: { offerId: $offerId, platform: IOS }) {
    url
    expiresAt
  }
}
```

### Entrada

| Campo      | Tipo                   | Requerido | Descripción                                                                                                                        |
| ---------- | ---------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `offerId`  | `String!` (UUIDv4)     | sí        | La oferta de tarjeta virtual a aprovisionar. Debe estar activa, ser apta para tokenización y accesible para la cuenta del usuario. |
| `platform` | `ProvisioningPlatform` | no        | Pista sobre dónde abrirá el usuario la URL. Predetermina a `IOS`. Ver abajo: esto **no** bloquea la URL a una sola plataforma.     |

#### `ProvisioningPlatform`

La URL devuelta es consciente de la plataforma: los usuarios de iOS obtienen automáticamente la experiencia de App Clip, los usuarios de Android obtienen automáticamente el deep link a la app de Fluz. El valor `platform` solo afecta lo que sucede cuando la URL se abre en un lugar **distinto** a un dispositivo iOS o Android (p. ej., un navegador de escritorio).

| Valor                  | Recurso alternativo en escritorio / dispositivo desconocido |
| ---------------------- | ----------------------------------------------------------- |
| `IOS` (predeterminado) | Lanzador de Apple App Clip                                  |
| `ANDROID`              | Deep link de Fluz para Android                              |
| `OTHER`                | App web de Fluz                                             |

Elige el valor que mejor coincida con donde esperas que se abra la URL. En caso de duda, déjalo como `IOS`.

### Salida

| Campo       | Tipo      | Descripción                                                                                       |
| ----------- | --------- | ------------------------------------------------------------------------------------------------- |
| `url`       | `String!` | La URL corta para entregar al usuario. De un solo uso.                                            |
| `expiresAt` | `String!` | Marca de tiempo ISO-8601. La URL deja de funcionar en ese momento (≈ 5 minutos tras su creación). |

## Ejemplo

### Solicitud

```bash theme={null}
curl -X POST https://api.fluz.app/api/v1/graphql \
  -H "Authorization: Bearer <user_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query($id:String!){ getCardProvisioningUrl(input:{ offerId:$id, platform:IOS }){ url expiresAt } }",
    "variables": { "id": "11111111-2222-3333-4444-555555555555" }
  }'
```

### Respuesta

```json theme={null}
{
  "data": {
    "getCardProvisioningUrl": {
      "url": "https://fluz.app.link/abc123XYZ",
      "expiresAt": "2026-05-26T17:42:11.000Z"
    }
  }
}
```

## Cómo entregar la URL

La URL es opaca y no contiene datos sensibles; es seguro mostrarla en códigos QR, SMS, email o en la interfaz de tu app. Patrones comunes:

* **Código QR en pantalla**: genera un QR a partir de `url` y muéstralo; el usuario lo escanea con la cámara de su teléfono.
* **SMS / email**: envía el enlace directamente al teléfono o bandeja de entrada del usuario.
* **Deep link dentro de la app**: conecta un botón en tu app móvil que abra `url`.

Sea cual sea el canal de entrega, el usuario debe abrir la URL en un dispositivo móvil: ahí es donde ocurre el aprovisionamiento en la billetera.

## Vigencia y reemisión

* Cada llamada devuelve una URL **nueva y de un solo uso**.
* La URL es válida hasta `expiresAt` (≈ 5 minutos).
* Si un usuario no actúa a tiempo, simplemente vuelve a llamar a `getCardProvisioningUrl` para emitir una nueva. No existe un endpoint de “refresh” separado.

## Manejo de errores

Todos los errores regresan en la forma estándar de errores de GraphQL de Fluz, con el nombre del error en `extensions.code`.

| Código                                        | Qué significa                                                                | Qué hacer                                                           |
| --------------------------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `Arguments.INVALID`                           | `offerId` no es un UUID válido.                                              | Valida la entrada de tu lado.                                       |
| `VirtualCard.OFFER_NOT_FOUND`                 | La oferta no existe o está inactiva.                                         | Confirma el id de la oferta; crea una nueva si es necesario.        |
| `VirtualCard.OFFER_NOT_ACCESSIBLE`            | La cuenta del usuario no es elegible para esta oferta (acceso a la campaña). | Muestra un mensaje genérico de “no disponible”.                     |
| `VirtualCard.OFFER_NOT_AVAILABLE`             | La oferta ya fue canjeada en una tarjeta que ya no está activa.              | No reintentes con la misma oferta; crea una nueva.                  |
| `VirtualCard.OFFER_NOT_TOKENIZATION_ELIGIBLE` | El programa de tarjeta de la oferta no admite aprovisionamiento a billetera. | No ofrezcas “Agregar a la billetera” para este programa de tarjeta. |
| `Auth.USER_REVOKED_DEVELOPER_ACCESS`          | El usuario revocó el acceso OAuth a tu app.                                  | Vuelve a enviar al usuario por el consentimiento de OAuth.          |
| `Auth.INVALID_SCOPE`                          | El token no tiene `CREATE_VIRTUALCARD`.                                      | Solicita el alcance durante OAuth.                                  |
| `Generic.EXTERNAL_SERVICE_ERROR`              | Problema transitorio aguas abajo.                                            | Reintenta: es seguro repetir la llamada.                            |

## Preguntas frecuentes

<AccordionGroup>
  <Accordion title="¿La URL contiene el número de la tarjeta?">
    No. La URL solo transporta un identificador opaco de corta duración. Las credenciales se intercambian de forma segura en el dispositivo una vez que el usuario abre el enlace.
  </Accordion>

  <Accordion title="¿Se puede reutilizar la misma URL?">
    No. Es de un solo uso. Genera una nueva cada vez que necesites presentar el flujo.
  </Accordion>

  <Accordion title="¿Qué pasa si el usuario está en escritorio?">
    Llegará al recurso alternativo que seleccionaste con `platform` (lanzador de App Clip, deep link de Android o app web de Fluz). Para que el aprovisionamiento en la billetera funcione, deben terminar abriendo la URL en un dispositivo móvil.
  </Accordion>

  <Accordion title="¿Necesito hacer algo distinto para iOS vs. Android?">
    No. La misma URL funciona para ambos: Fluz enruta automáticamente según el dispositivo.
  </Accordion>
</AccordionGroup>

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Enviar tarjetas" icon="send" href="/features/send-cards">
    Distribuye tarjetas virtuales a destinatarios por email, SMS o enlace compartido.
  </Card>

  <Card title="Configurar el PIN de una tarjeta virtual" icon="key-round" href="/set-virtual-card-pin">
    Configura un PIN en tarjetas elegibles antes de transacciones presenciales que solicitan PIN.
  </Card>
</CardGroup>
