# Guía de integración API

Esta guía describe los pasos recomendados para integrarte con la API de Fluxis, desde el aprovisionamiento de credenciales hasta la conciliación de transacciones.

## Resumen de la integración

Una integración típica con Fluxis sigue estos pasos:

1. **Aprovisionamiento de credenciales** — Crear una clave API en el dashboard (roles read + write)
2. **Autenticación** — Intercambiar credenciales por un token de acceso Bearer
3. **Descubrimiento de recursos** — Recuperar tus cuentas predeterminadas y puntos de venta predeterminados (los creados al registrarte)
4. **Crear tu POS online** — Configurar tu POS para pagos online, para que pueda generar múltiples solicitudes de pago en paralelo
5. **Configuración de liquidación** — Configurar la dirección cripto donde se entregarán los activos cobrados. Puedes hacerlo en el dashboard o vía API.
6. **Creación de solicitudes de pago** — Crear una solicitud de pago por cada intento de checkout
7. **Monitorear estado de pagos** — [Webhooks](/es/docs/developers/webhook-events) (push) o polling (pull) — elige uno o ambos
8. **Conciliación** — Consultar transacciones periódicamente para detectar eventos perdidos

<div className="my-6">
  <img
    src="/images/fluxis-payment-flow-light.svg"
    alt="Fluxis API payment and collection flow"
    className="block w-full max-w-full dark:hidden"
  />
  <img
    src="/images/fluxis-payment-flow-dark.svg"
    alt="Fluxis API payment and collection flow"
    className="hidden w-full max-w-full dark:block"
  />
</div>

## Antes de empezar

### Entornos

| Entorno | Host                       |
| ----------- | -------------------------- |
| Staging     | `https://api.stgfluxis.us` |
| Production  | `https://api.fluxis.us`    |

::::note
Las credenciales de producción se generarán después de que tu integración en staging esté completa y aprobada por Fluxis.
::::

### Encabezados requeridos

Todos los endpoints protegidos de Fluxis requieren **ambos** encabezados:

- `Authorization: Bearer <access_token>`
- `x-fluxis-api-key: <your_api_key>`

::::warning
Trata tu API Secret como credencial sensible. Nunca lo expongas en código del lado del cliente, navegadores o apps móviles.
::::

---

## Paso 1 — Aprovisionamiento de credenciales

Antes de hacer llamadas API, crea credenciales API en el Dashboard de Fluxis.

::::info
¿Nuevo en Fluxis? Completa el [Registro de comercio](/es/docs/merchant-integration/sign-up) (creación de cuenta + 2FA) antes de este paso.
::::

### Crear una clave API en el dashboard

1. Inicia sesión en el Dashboard de Fluxis ([staging](https://dashboard.stgfluxis.us) o [production](https://dashboard.fluxis.us)).
2. Abre **Developers → API Keys** (o navega a `/app/api-keys`).
3. Haz clic en **Create** (o equivalente) para agregar una nueva clave.
4. Asigna los roles **`read`** y **`write`** para listar recursos y crear solicitudes de pago.
5. Completa el **desafío 2FA** cuando se solicite ([Autenticación de dos factores](/es/docs/developers/two-factor-auth) debe estar registrada primero).
6. Copia el **API Secret** de inmediato — se muestra **una vez** y no puede recuperarse después.

Recibirás:

- **API Key ID** (p. ej. `fxs.stg.<uuid>` para staging, `fxs.prd.<uuid>` para production)
- **API Secret** — guarda en un gestor de secretos o variables de entorno

Consulta [Credenciales API](/es/docs/developers/api-credentials) para roles, lista blanca de IP y ciclo de vida.

::::tip
Si operas varias marcas o regiones, coordina con Fluxis temprano para alinear tu estructura de **Accounts** y **Points of Sale**. Esto simplificará informes y conciliación.
::::

---

## Paso 2 — Autenticación

Intercambia tus credenciales por un token de acceso que debe incluirse en todas las solicitudes API posteriores.

**Endpoint:** `POST /v1/auth/token`

Consulta el formato completo de solicitud/respuesta en nuestra [Referencia API - Authentication](/api/authentication#authenticate-and-get-access-token).

### Uso del token

Incluye el token de acceso en todas las solicitudes protegidas:

```
Authorization: Bearer <access_token>
x-fluxis-api-key: <your_api_key>
```

### Ciclo de vida del token

- **Expiración**: Los tokens de acceso expiran (consulta el campo `expired_at` en la respuesta)
- **Renovación**: Implementa un mecanismo para renovar el token antes de que expire
- **Rotación**: Rota tu API Key/Secret de inmediato si sospechas que han sido comprometidos

---

## Paso 3 — Descubrimiento de recursos

Después de autenticarte, recupera información sobre tus cuentas y puntos de venta predeterminados, o puedes crear nuevos.

### 3.1 Recuperar cuentas

Las cuentas representan las cuentas financieras de tu comercio dentro de Fluxis.

**Endpoint:** `GET /v1/account`

Consulta el formato completo de respuesta en nuestra [Referencia API - Accounts](/api/accounts#list-accounts).

### 3.2 Recuperar puntos de venta

Los Puntos de Venta (POS) representan tus puntos de entrada de pago — ubicaciones físicas o virtuales donde aceptas pagos. Necesitarás el ID del POS al crear solicitudes de pago.

**Endpoint:** `GET /v1/pos?page=1&page_size=20`

Parámetros de consulta requeridos: `page` (≥ 1) y `page_size` (1–100). Las claves de organización pueden filtrar con `account_id`.

Consulta el formato completo de respuesta en nuestra [Referencia API — Point of Sale](/api/point-of-sale#get-all-point-of-sales).

::::tip
Más sobre el concepto POS: [Punto de Venta](/es/docs/key-concepts/point-of-sale).
::::

---

## Paso 4 — Configuración de liquidación

Antes de aceptar pagos, debes configurar adónde se entregarán los activos cripto cobrados.

Todos los activos cobrados de una red específica (p. ej., USDT, USDC u otros tokens en Polygon) se entregarán a la dirección de liquidación configurada para esa red.

::::note
Por razones de seguridad, la configuración de direcciones de liquidación actualmente la gestiona manualmente el equipo de Fluxis. Contacta a tu representante de Fluxis para configurar tus direcciones de liquidación en staging y production.
::::

---

## Paso 5 — Creación de solicitudes de pago

Crea una solicitud de pago por cada intento de checkout del cliente. La respuesta incluye un **token NASPIP** con toda la información de pago.

**Endpoint:** `POST /v1/pos/:posID/payment-request`

Campos clave:

- `amount` — El monto del pago (p. ej., `"49.99"`)
- `unique_asset_id` — El activo/red objetivo ([más sobre UAIs](/es/docs/key-concepts/uai))
- `reference_id` — Tu ID de pedido interno para conciliación
- `order` — Datos estructurados opcionales del pedido para recibos/UX

Consulta el formato completo de solicitud/respuesta en nuestra [Referencia API - Payment Request](/api/point-of-sale#create-point-of-sale-payment-request).

### 5.1 Mostrar el token NASPIP

El `token` devuelto en la respuesta es un token NASPIP que presentas al cliente.

**Checkout en escritorio:**
Muestra el token NASPIP como código QR para que los usuarios lo escaneen con su app de billetera.

**Checkout móvil:**
Muestra un botón "Pagar con [nombre de app de billetera]" que abre la app vía deep link:

```
[wallet app deeplink url]?<custom_query_params>&naspip_token=<NASPIP_TOKEN>
```

::::tip
Más sobre NASPIP: [Token NASPIP](/es/docs/key-concepts/naspip/introduction).

Para una lista mantenida de apps de billetera, plantillas de deep link y logos, consulta [Registro de apps compatibles](/es/docs/developers/compatible-apps).
::::

### 5.2 Hosted checkout (opcional)

Para una página de pago alojada por Fluxis en lugar de incrustar el token NASPIP tú mismo:

**Endpoint:** `POST /v1/pos/:posID/payment-request-checkout`

La respuesta incluye tanto un `token` como una `checkout_url` a la que puedes redirigir clientes directamente. La página hosted consulta `GET /public/checkout/:sessionId` y, al terminar, usa `return_url`: en un punto de venta genérico es `config.return_url` del POS; en una sesión Tiendanube es el callback por intento (`success`, `failure` o `cancel`) guardado en Process Payment, no la URL del POS.

Consulta [API Reference — Create payment request checkout](/api/point-of-sale#create-payment-request-checkout).

---

## Paso 6 — Elegir cómo monitorear pagos

Después de crear una solicitud de pago, necesitas saber cuándo el cliente paga. Elige **una o ambas** estrategias:

| Estrategia                | Entrega                           | Ideal para                                  | Requisitos                                                                                     |
| ----------------------- | ---------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------ |
| **Webhooks (Opción A)** | Push — Fluxis hace POST a tu servidor | Integraciones de producción, UX en tiempo real     | Endpoint HTTPS público, [verificación de firma](/es/docs/developers/webhook-signature-verification) |
| **Polling (Opción B)**  | Pull — tu servidor consulta Fluxis  | Backends simples, desarrollo local, sin URL pública | Token Bearer + API key válidos; polling cada ~3 segundos                                              |

::::tip
Muchos equipos usan **webhooks como principal** y **polling como respaldo** cuando se pierde un webhook o tu endpoint estuvo temporalmente caído.
::::

### Opción A — Notificaciones webhook

Los webhooks son la forma recomendada de recibir actualizaciones de estado de pago en tiempo real.

#### A.1 Configurar tu endpoint webhook

Primero, asegúrate de tener un endpoint HTTPS públicamente accesible listo para recibir solicitudes POST de Fluxis.

Luego registra un webhook en la **cuenta** vinculada a tu POS (usa el `account_id` de tu POS o lista de cuentas):

**Endpoint:** `POST /v1/account/{accountID}/webhook`

```json
{
  "url": "https://your-server.com/webhooks/fluxis",
  "event_type": "payment_request"
}
```

Fluxis devuelve un `secret` **una vez** al crear — guárdalo de forma segura para [verificación de firma](/es/docs/developers/webhook-signature-verification).

Consulta [API Reference — Create webhook](/api/webhooks#create-webhook).

#### A.2 Eventos webhook

Fluxis envía webhooks `payment_request` cuando el estado se vuelve:

| Estado       | Descripción                                         | Webhook entregado   |
| ------------ | --------------------------------------------------- | ------------------- |
| `processing` | Pago detectado, esperando confirmaciones blockchain | Sí                 |
| `completed`  | Pago confirmado — cumple el pedido               | Sí                 |
| `underpaid`  | El cliente envió menos del monto solicitado        | Sí                 |
| `overpaid`   | El cliente envió más del monto solicitado        | Sí                 |
| `expired`    | Sin pago a tiempo                                  | No — usa polling   |
| `failed`     | Error inesperado de procesamiento                         | No — polling / soporte |

::::note
Los estados `underpaid` y `overpaid` son casos límite que pueden implicar una configuración incorrecta del lado de la app de billetera, ya que los tokens NASPIP ya contienen el monto esperado.
Para pasos de verificación de firma, consulta [Verificación de firma de webhook](/es/docs/developers/webhook-signature-verification).
::::

#### A.3 Manejar webhooks

Cuando recibes una notificación webhook:

1. **Verificar autenticidad** — Valida la firma HMAC sobre el cuerpo parseado completo `{ "data": … }` usando el secreto de la creación — consulta [Verificación de firma de webhook](/es/docs/developers/webhook-signature-verification)
2. **Procesar el estado** — Actualiza el estado interno del pedido y notifica al cliente
3. **Confirmar recepción** — Devuelve HTTP `200 OK` para confirmar recepción

::::warning
Tu endpoint debe responder rápido (< 2 segundos). Encola cualquier procesamiento pesado para ejecución en segundo plano. No confirmar puede hacer que Fluxis reenvíe la notificación.
::::

#### A.4 Idempotencia

Puedes recibir eventos webhook duplicados. Asegúrate de que tu manejador sea **idempotente** — procesar el mismo evento varias veces debe producir el mismo resultado.

#### A.5 Probar tu manejador

Después del registro, dispara una entrega de muestra firmada:

**Endpoint:** `POST /v1/account/{accountID}/webhook/{webhookID}/test`

Fluxis hace POST de un payload `payment_request_status_update` usando la misma ruta de firma que producción. Verifica la firma en tu manejador y devuelve HTTP `200`. Consulta [Verificación de firma de webhook](/es/docs/developers/webhook-signature-verification) para las reglas de JSON canónico y el ejemplo trabajado.

También puedes registrar webhooks desde el dashboard en **Developers → Webhooks**. Consulta [Webhooks](/es/docs/developers/webhooks) para opciones API y dashboard.

---

### Opción B — Polling

Si no tienes un endpoint HTTPS público — o prefieres una primera integración más simple — **haz polling** del estado de la solicitud de pago en un intervalo fijo (por ejemplo, cada **3 segundos**) hasta que el estado sea terminal.

**Endpoint:** `GET /v1/pos/:posID/payment-request/:paymentRequestID`

Encabezados requeridos: `Authorization: Bearer <token>` y `x-fluxis-api-key: <your_api_key>`.

#### Patrón de polling recomendado

1. Después de crear una solicitud de pago, registra `paymentRequestID` y `posID`.
2. Haz polling cada **~3 segundos** mientras el estado sea `created`, `pending`, `confirmed` o `processing`.
3. **Detén el polling** cuando el estado sea terminal: `completed`, `expired`, `underpaid`, `overpaid` o `failed`.
4. En `completed`, cumple el pedido; en `expired`, ofrece crear una nueva solicitud.

::::warning
Las solicitudes de pago expiran después de unos **8 minutos**. Evita hacer polling más rápido que una vez por segundo — 3 segundos es un valor razonable para UX de checkout.
::::

**Ejemplo (curl):**

```bash
curl "https://api.stgfluxis.us/v1/pos/${POS_ID}/payment-request/${PAYMENT_REQUEST_ID}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "x-fluxis-api-key: ${API_KEY}"
```

**Ejemplo (bucle Node.js):**

```javascript
const TERMINAL = new Set([
  "completed",
  "expired",
  "underpaid",
  "overpaid",
  "failed",
]);
const POLL_MS = 3000;

async function waitForPayment(posId, paymentRequestId) {
  while (true) {
    const res = await fetch(
      `${API_BASE}/v1/pos/${posId}/payment-request/${paymentRequestId}`,
      {
        headers: {
          Authorization: `Bearer ${accessToken}`,
          "x-fluxis-api-key": apiKey,
        },
      },
    );
    const { data } = await res.json();
    if (TERMINAL.has(data.status)) return data;
    await new Promise((r) => setTimeout(r, POLL_MS));
  }
}
```

Consulta el formato completo de respuesta en nuestra [Referencia API — Get payment request](/api/point-of-sale#get-payment-request).

::::note
Los estados `expired` y `failed` **no** disparan webhooks — se requiere polling (o comprobaciones manuales) para esos resultados.
::::

---

## Paso 7 — Conciliación

Incluso con webhooks o polling en el momento del checkout, ejecuta **conciliación periódica** para asegurar que no se perdieron pagos (tiempo de inactividad, problemas de red o bugs del manejador).

### Consultar una solicitud de pago específica

Si no recibiste un webhook (o tu sistema estuvo caído), obtén el estado de la solicitud de pago directamente:

**Endpoint:** `GET /v1/pos/:posID/payment-request/:paymentRequestID`

### Listar transacciones para conciliación

Para conciliación por lotes, consulta el endpoint de transacciones:

**Endpoint:** `GET /v1/transactions?page=1&page_size=50`

Parámetros de consulta requeridos: `page` (≥ 1) y `page_size` (5–100).

Filtros opcionales:

- `accountID` — Filtrar por cuenta (solo claves API a nivel de organización)

La respuesta está paginada: `{ data, total, page, page_size, total_pages }`.

::::tip
Un patrón de conciliación común: listar periódicamente transacciones `completed` y emparejarlas con tus pedidos internos por ID de referencia, monto y marca de tiempo.
::::

---

## Ciclo de vida de solicitud de pago

Las solicitudes de pago pasan por los siguientes estados:

| Estado                               | Descripción                              | Acción del comercio                              |
| ----------------------------------- | ---------------------------------------- | -------------------------------------------- |
| `pending`                           | Checkout creado, moneda no seleccionada  | Esperar o mostrar hosted checkout              |
| `created`                           | Dirección asignada, esperando pago       | Mostrar QR/enlace al cliente                  |
| `confirmed`                         | Paso de confirmación interna               | Normalmente sin acción del comercio                   |
| `processing`                        | Pago detectado, esperando confirmaciones | Seguir esperando — no cumplir aún             |
| `completed`                         | Pago confirmado                        | Cumplir el pedido                            |
| `expired`                           | Sin pago recibido a tiempo              | Ofrecer al cliente reintentar (crear nueva solicitud) |
| `underpaid` / `overpaid` / `failed` | Casos límite                               | Contactar soporte de Fluxis                       |

Más información: [Flujos de pago - Camino feliz](/es/docs/payment-flows/std-flow) y [Flujos de pago - Casos límite](/es/docs/payment-flows/edge-cases).

---

## Lista de verificación para producción

Antes de ir a producción, verifica:

- [ ] Puedes obtener y renovar tokens Bearer vía `POST /v1/auth/token`
- [ ] Puedes listar tu POS y seleccionar el `posID` correcto
- [ ] Tu checkout crea una solicitud de pago por intento
- [ ] Muestras el token NASPIP correctamente (código QR o deep link)
- [ ] Tienes una estrategia de monitoreo: webhooks **y/o** polling (~3 s de intervalo hasta estado terminal)
- [ ] Si usas webhooks: registrado vía `POST /v1/account/{accountID}/webhook` con `event_type: payment_request`
- [ ] Secreto de webhook almacenado de la respuesta de creación y usado para [verificación de firma](/es/docs/developers/webhook-signature-verification)
- [ ] Entrega de prueba vía `POST /v1/account/{accountID}/webhook/{webhookID}/test` verifica y devuelve HTTP 200
- [ ] Tu endpoint webhook es públicamente accesible y responde con HTTP 200
- [ ] Tu manejador de webhook es idempotente
- [ ] Si usas polling: `GET /v1/pos/:posID/payment-request/:paymentRequestID` se detiene en estado terminal
- [ ] Tienes un proceso de conciliación periódica (`GET /v1/transactions`)

---

## ¿Necesitas ayuda?

Si tienes preguntas sobre incorporación, credenciales o preparación para producción, contáctanos en [support@fluxis.us](mailto:support@fluxis.us).
