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

# Intercambiar token

> Intercambia un ID token OIDC de tu proveedor de identidad por un access token de Fire spark para el cliente autenticado.

La API Storefront soporta [OAuth 2.0 Token Exchange](https://datatracker.ietf.org/doc/html/rfc8693) (RFC 8693) para **clientes públicos**. Tu app, web o kiosco envía el **ID token OIDC** del cliente y recibe a cambio un access token de Fire spark de corta duración.

No se requiere `client_id` ni `client_secret`. Fire spark lee los claims `iss` y `aud` del ID token, encuentra el proveedor de identidad configurado para el comercio, valida el token contra el JWKS de ese proveedor y emite un access token ligado al cliente identificado por el claim `sub`.

## Cuándo usar token exchange

Usa este endpoint cuando:

* Los clientes inician sesión con un proveedor de identidad OIDC compatible en el cliente
* Tu canal necesita llamar a la API Storefront en nombre de ese cliente
* Quieres que Fire spark valide la identidad y limite el acceso a un solo customer

> [!TIP]
>
> Envía el **ID token**, no access tokens opacos ni API keys. Los ID tokens son
> JWTs que identifican al usuario autenticado mediante claims estándar: `sub`,
> `iss` y `aud`. Todo proveedor OIDC compatible los expone tras el sign-in.

## Requisitos previos

1. Configura tu proveedor de identidad en el [panel de Fire spark](https://firespark.cloud) para tu comercio.
2. Autentica al cliente en el dispositivo y obtén un ID token OIDC vigente de tu proveedor.

## Cómo funciona

**1. El cliente inicia sesión en el dispositivo**

Tu app completa el sign-in con tu proveedor OIDC usando el SDK del proveedor.
Obtén el ID token que emite para la sesión autenticada.

**2. El cliente envía el ID token**

Tu cliente llama a `POST /oauth/exchange` con el ID token como
`subject_token`. No hace falta enviar merchant ID ni secret de API.

**3. Fire spark resuelve el comercio y valida el token**

Fire spark relaciona el `iss` y `aud` del token con el proveedor configurado
para un comercio, verifica la firma y expiración usando el JWKS de ese
proveedor, y usa `sub` como identificador externo del cliente.

**4. El cliente usa el access token de Fire spark**

Fire spark devuelve un access token para ese cliente. Úsalo en el
header `Authorization` en las solicitudes a la API Storefront.

## Obtener el ID token

Cada proveedor expone el ID token a través de su SDK de cliente. Usa el método que devuelve el **JWT ID token** de la sesión actual.

> [tab] Auth0
>
> ```javascript theme={null}
> import { useAuth0 } from "@auth0/auth0-react";
>
> const { getIdTokenClaims } = useAuth0();
> const claims = await getIdTokenClaims();
> const idToken = claims?.__raw;
> ```

> [tab] Clerk
>
> ```javascript theme={null}
> import { useAuth } from "@clerk/clerk-react";
>
> const { getToken } = useAuth();
> const idToken = await getToken();
> ```

> [tab] Supabase
>
> ```javascript theme={null}
> import { createClient } from "@supabase/supabase-js";
>
> const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
> const { data } = await supabase.auth.getSession();
> const idToken = data.session?.access_token;
> ```
>
> Supabase devuelve un JWT firmado con los claims `sub`, `iss` y `aud`. Usa el
> JWT de sesión inmediatamente después del sign-in mientras siga vigente.

> [tab] Firebase
>
> ```javascript theme={null}
> import { getAuth } from "firebase/auth";
>
> const auth = getAuth();
> const idToken = await auth.currentUser?.getIdToken();
> ```

> [tab] Amazon Cognito
>
> ```javascript theme={null}
> import { fetchAuthSession } from "aws-amplify/auth";
>
> const session = await fetchAuthSession();
> const idToken = session.tokens?.idToken?.toString();
> ```

> [tab] Okta
>
> ```javascript theme={null}
> import OktaAuth from "@okta/okta-auth-js";
>
> const authClient = new OktaAuth({ issuer, clientId });
> const { idToken } = await authClient.tokenManager.get("idToken");
> const idTokenJwt = idToken.idToken;
> ```

## Solicitud de token exchange

Envía una solicitud `POST` a `/oauth/exchange` con `Content-Type: application/json`. El cuerpo de la solicitud es el mismo sin importar el proveedor.

```javascript Cualquier proveedor OIDC theme={null}
const response = await fetch(
  "https://firespark.cloud/api/storefront/v1/oauth/exchange",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
      subject_token: idToken,
      subject_token_type: "urn:ietf:params:oauth:token-type:id_token"
    })
  }
);

const { access_token } = await response.json();
```

```bash cURL theme={null}
curl -X POST "https://firespark.cloud/api/storefront/v1/oauth/exchange" \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
    "subject_token": "YOUR_ID_TOKEN",
    "subject_token_type": "urn:ietf:params:oauth:token-type:id_token"
  }'
```

```json Éxito theme={null}
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
  "token_type": "Bearer",
  "expires_in": 3600
}
```

### Cuerpo de la solicitud

| Campo | Requerido | Descripción |
| - | - | - |
| `grant_type` | Sí | Debe ser `urn:ietf:params:oauth:grant-type:token-exchange`. |
| `subject_token` | Sí | El ID token OIDC de tu proveedor de identidad para el cliente autenticado. |
| `subject_token_type` | Sí | Debe ser `urn:ietf:params:oauth:token-type:id_token`. No se aceptan access tokens opacos. |

### Cómo Fire spark identifica al comercio

Fire spark no requiere un merchant ID en la solicitud. Inspecciona los claims del ID token:

| Claim | Propósito |
| - | - |
| `iss` | Identifica la URL del issuer del proveedor de identidad. |
| `aud` | Identifica el proyecto, realm o app client del proveedor. |
| `sub` | Identificador estable del cliente usado para resolver o crear el registro del customer. |

Fire spark relaciona `iss` y `aud` con la configuración del proveedor registrada para un comercio y valida la firma del token antes de emitir un access token.

### Proveedores soportados

Cualquier proveedor OIDC compatible que emita JWT ID tokens con un endpoint JWKS descubrible es compatible. Registra el proveedor en el panel antes de ir a producción.

| Proveedor | Formato típico de `iss` | Cómo obtener el ID token |
| - | - | - |
| Auth0 | `https://{tenant}.auth0.com/` | `getIdTokenClaims().__raw` |
| Clerk | `https://{your-clerk-domain}` | `getToken()` |
| Supabase | `https://{project-ref}.supabase.co/auth/v1` | `getSession().access_token` |
| Firebase | `https://securetoken.google.com/{projectId}` | `getIdToken()` |
| Amazon Cognito | `https://cognito-idp.{region}.amazonaws.com/{userPoolId}` | `fetchAuthSession().tokens.idToken` |
| Okta | `https://{okta-domain}/oauth2/{authorizationServerId}` | `tokenManager.get("idToken")` |
| Keycloak | `https://{host}/realms/{realm}` | `keycloak.idToken` |

> [!NOTE]
>
> Los valores de `iss` y `aud` deben coincidir exactamente con lo que Fire spark
> tiene registrado para tu comercio. Cópialos de un ID token decodificado al
> configurar el proveedor en el panel.

## Usar el token intercambiado

Incluye el access token de Fire spark en el header `Authorization`. El token solo permite acceder a recursos del cliente vinculado al claim `sub` original.

```bash theme={null}
curl "https://firespark.cloud/api/storefront/v1/customers/me" \
  -H "Authorization: Bearer FIRESPARK_ACCESS_TOKEN"
```

> [!NOTE]
>
> Vuelve a intercambiar cuando tu proveedor refresque el ID token. Los access
> tokens de Fire spark son de corta duración y no reemplazan mantener vigente la
> sesión del IdP. Un proxy de un socio que proteja sus propios endpoints con
> este token debe [inspeccionarlo](https://firespark.cloud/docs/es/storefront-api/oauth/introspect/post.md) en
> lugar de verificar el JWT en local.

## Propiedades de seguridad

* **Perfil de cliente público:** Pensado para clientes mobile y web. No se envían ni almacenan credenciales confidenciales en la app.
* **Solo ID token:** Solo se aceptan JWT ID tokens OIDC como `subject_token`. Se rechazan tokens opacos o API tokens del proveedor.
* **Validación criptográfica:** Se verifican firma, `iss`, `aud` y `exp` contra el proveedor registrado del comercio antes de devolver datos del cliente.
* **Aislamiento por cliente:** El access token emitido está ligado al `sub` del ID token. Las solicitudes para otros clientes se rechazan.
* **Tokens de corta duración:** Los tokens intercambiados expiran tras `expires_in` segundos.

> [!WARNING]
>
> Llama siempre a este endpoint por HTTPS. No registres ID tokens ni access tokens
> de Fire spark en logs. Renueva el exchange cuando tu proveedor rote el ID token.

## Respuestas de error

Los errores siguen RFC 6749 y RFC 8693. El endpoint devuelve `application/json` con un campo `error`.

| Error | Descripción |
| - | - |
| `invalid_request` | Falta un campo requerido o está mal formado. |
| `invalid_grant` | El ID token es inválido, expiró o no coincide con ningún proveedor registrado para un comercio. |
| `unsupported_grant_type` | El valor de `grant_type` no es compatible. |

```json Error theme={null}
{
  "error": "invalid_grant",
  "details": "No merchant is configured for this token issuer and audience."
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.