# Flujo de pago — Camino feliz

Esta página describe el **flujo de pago end-to-end estándar** en Fluxis: desde crear una solicitud de pago hasta la detección on-chain, el procesamiento asíncrono y la entrega de webhooks. Para resultados no estándar (pago insuficiente, expiración, transacciones fallidas), consulte [Flujos de pago — Casos límite](/es/docs/payment-flows/edge-cases).

## Descripción general de la arquitectura

El procesamiento de pagos de Fluxis abarca cuatro servicios cooperativos:

```mermaid
graph LR
    API[Core API] --> DB[(PostgreSQL)]
    API --> Redis[(Redis)]
    Cron[Cron] --> Redis
    Cron --> SQS[(SQS transactions queue)]
    Worker[Transaction Worker] --> SQS
    Worker --> DB
    Worker --> API
    Cron --> Chain[Polygon / Base / Avalanche / Arbitrum]
```

| Service | Role |
| ------- | ---- |
| **Core API** | Crea solicitudes de pago, asigna direcciones vault, genera [tokens NASPIP](/es/docs/key-concepts/naspip/introduction), expone endpoints REST |
| **Cron** | Consulta blockchains cada **3 segundos** en busca de eventos ERC-20 `Transfer` hacia direcciones vault activas |
| **Transaction Worker** | Consume la cola SQS `transactions` y ejecuta el ciclo de vida de pago de **3 saltos** |
| **Crypto Service** | Servicio externo para gestión de vaults, consolidación y liquidación (post-pago) |

Los comerciantes interactúan solo con la Core API y [webhooks a nivel de cuenta](/es/docs/developers/webhooks). El monitoreo blockchain y la confirmación de transacciones ocurren de forma asíncrona.

## Requisitos previos

Antes de que un pago pueda tener éxito, la jerarquía del comerciante debe estar configurada:

```mermaid
graph TD
    Org[Organization] --> Acct[Account]
    Acct --> POS[Point of Sale]
    Acct --> WH[Account Webhook]
    POS --> PR[Payment Request]
```

1. **Organization and Account** — Consulte [Merchant Sign Up](/es/docs/merchant-integration/sign-up).
2. **Point of Sale** — Un PoS `online_fixed` (e-commerce) o `cashier_fixed` (caja física). Consulte [Point of Sale](/es/docs/key-concepts/point-of-sale).
3. **Authentication** — Bearer token + `x-fluxis-api-key` en rutas protegidas. Consulte [Authentication & Configuration](/es/docs/merchant-integration/auth-and-conf).
4. **Webhook (recommended)** — Regístrelo a nivel de cuenta: `POST /v1/account/{accountID}/webhook`. Consulte [Webhooks](/es/docs/developers/webhooks).

## Paso 1 — Crear una solicitud de pago

Cree una solicitud de pago a través del endpoint del **Point of Sale** — no una ruta independiente `/v1/payment-requests`:

```
POST /v1/pos/{posID}/payment-request
Authorization: Bearer <token>
x-fluxis-api-key: <api_key_id>
```

```json
{
  "reference_id": "order-12345",
  "amount": "49.99",
  "unique_asset_id": "npolygon_t0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
  "order": {
    "total": "49.99",
    "coin_code": "USD",
    "description": "Premium Subscription"
  }
}
```

::::tip
**Alternativa de checkout alojado**

Cuando el pagador debe elegir su activo entre las `payment_options` del PoS, use `POST /v1/pos/{posID}/payment-request-checkout`. La solicitud de pago comienza en estado `pending` y transiciona a `created` una vez que el pagador selecciona un UAI. Consulte [Creating Payment Requests](/es/docs/merchant-integration/create-payreq).
::::

### Qué hace Fluxis internamente

```mermaid
sequenceDiagram
    participant M as Merchant App
    participant API as Core API
    participant Pool as Vault Pool
    participant Redis as Redis Cache

    M->>API: POST /v1/pos/:posID/payment-request
    API->>Pool: Atomically assign vault (FOR UPDATE SKIP LOCKED)
    Pool-->>API: Vault address
    API->>API: Create payment request (status: created)
    API->>Redis: Cache vault → payment request mapping
    API->>API: Generate NASPIP token (PASETO v4)
    API-->>M: id, status, token, expiration
```

Al crear, Fluxis:

1. Valida el PoS y resuelve el [UAI](/es/docs/key-concepts/uai)
2. Asigna una **dirección vault** única del pool pre-desplegado
3. Establece el estado **`created`** y una marca de **expiración de 8 minutos**
4. Almacena en caché la dirección vault en Redis para búsquedas rápidas del cron
5. Devuelve un [token NASPIP](/es/docs/key-concepts/naspip/introduction) para mostrar QR / enlace de pago

Ejemplo de respuesta:

```json
{
  "status": "success",
  "data": {
    "id": "180ede28-2968-4ac7-8e81-ca446f201949",
    "reference_id": "order-12345",
    "status": "created",
    "token": "naspip;fluxis.us;fluxis.qr.dyn.1;v4.public.IhYyMDI...",
    "expiration": 1759397652
  }
}
```

## Paso 2 — El cliente paga on-chain

El cliente escanea el token NASPIP (código QR o enlace) y envía el importe exacto a la dirección vault en la red configurada. Fluxis no tiene custodia durante este paso — el pago va directamente al smart contract vault.

Su aplicación debe:

- Mostrar el token NASPIP y una cuenta regresiva basada en `expiration`
- Consultar `GET /v1/pos/{posID}/payment-request/{paymentRequestID}` o esperar webhooks
- **No** cumplir el pedido hasta que el pago alcance un estado terminal

## Paso 3 — Cron detecta la transferencia

El servicio cron ejecuta un trabajo de lectura blockchain **cada 3 segundos** en redes admitidas (Polygon, Base, Avalanche, Arbitrum):

```mermaid
flowchart TD
    A[Acquire Redis lock] --> B[Read last processed block]
    B --> C[eth_getLogs Transfer events]
    C --> D[Match tx.to against active vaults in Redis]
    D --> E{Match found?}
    E -->|Yes| F[Enqueue transaction_incoming_payment to SQS]
    E -->|No| G[Update last processed block]
    F --> G
```

Detalles clave:

- Usa `eth_getLogs` con **chunking adaptativo** para consultar eventos ERC-20 `Transfer` eficientemente
- Filtra transacciones donde el destinatario (`to`) coincide con una dirección vault activa en caché en Redis
- Encola transacciones coincidentes en la cola SQS **`transactions`** con tipo de evento `transaction_incoming_payment`

## Paso 4 — Worker SQS de tres saltos

El transaction worker procesa cada pago mediante **tres saltos SQS secuenciales**:

```mermaid
sequenceDiagram
    participant SQS as SQS Queue
    participant W as Transaction Worker
    participant Chain as Blockchain RPC
    participant WH as Merchant Webhook

    Note over SQS,W: Hop 1 — transaction_incoming_payment
    SQS->>W: Incoming payment detected
    W->>W: created → processing
    W->>WH: Webhook (processing)
    W->>SQS: Enqueue check (finality delay)

    Note over SQS,W: Hop 2 — transaction_check_update_payment_request
    SQS->>W: After finality delay (~256s default)
    W->>Chain: GetTransaction (verify status)
    alt Confirmed
        W->>W: Compare amounts → completed / underpaid / overpaid
        W->>WH: Webhook (final status)
        W->>SQS: Enqueue confirm (immediate)
        W->>W: Release vault, clear Redis cache
    else Still pending
        W->>SQS: Re-enqueue with finality delay
    end

    Note over SQS,W: Hop 3 — transaction_confirm_payment_request
    SQS->>W: Confirm payment request
    W->>W: Create internal Transaction record
    W->>W: completed/overpaid → confirmed
```

### Salto 1 — `transaction_incoming_payment`

- Valida que la solicitud de pago esté en `created` o `processing`
- Actualiza el estado a **`processing`**
- Envía un **webhook** con estado `processing`
- Encola el salto 2 con un **retraso de finalidad** (predeterminado **256 segundos** en Polygon, configurable por red)

### Salto 2 — `transaction_check_update_payment_request`

Tras el retraso de finalidad:

- Llama `GetTransaction` para verificar el estado on-chain (pending / confirmed / failed)
- Usa el **importe de la detección `eth_getLogs` del cron** (no de `GetTransaction`, que falla en transacciones proxy/router)
- Compara importe recibido vs importe esperado:
  - Igual → **`completed`**
  - Menor → **`underpaid`**
  - Mayor → **`overpaid`**
- Envía un **webhook** con el estado final
- Encola el salto 3 inmediatamente y libera el vault

### Salto 3 — `transaction_confirm_payment_request`

- Se ejecuta solo para pagos **`completed`** o **`overpaid`**
- Crea un registro interno de **Transaction** (tarifas, direcciones, entrada de ledger)
- Actualiza el estado de la solicitud de pago a **`confirmed`**
- **No** envía webhook (consulte la matriz de webhooks en [Edge Cases](/es/docs/payment-flows/edge-cases))

::::info
**Pagos underpaid**

El salto 3 **no** se ejecuta para pagos `underpaid` — no se crea transacción interna. Consulte [Edge Cases — Underpaid](/es/docs/payment-flows/edge-cases#underpaid).
::::

## Paso 5 — Notificaciones webhook

Fluxis entrega webhooks a nivel de cuenta cuando cambia el estado de la solicitud de pago durante los saltos 1 y 2:

```json
{
  "data": {
    "notification_type": "payment_request_status_update",
    "payment_request_id": "aa5d6c80-0b0b-4a2a-bbc8-14a41e6245bf",
    "payment_request_type": "fixed",
    "external_reference_id": "order-12345",
    "status": "completed",
    "point_of_sale_id": "3cc1f7ca-c017-4e7e-b00d-aca0da6e464e",
    "account_id": "c87464d1-c54a-48c3-80c9-bee4fddf593d"
  }
}
```

| Webhook-delivered status | When |
| ------------------------ | ---- |
| `processing` | Cron detectó una transferencia on-chain al vault |
| `completed` | Confirmado tras finalidad; el importe coincide con lo esperado |
| `underpaid` | Confirmado tras finalidad; se recibió menos de lo esperado |
| `overpaid` | Confirmado tras finalidad; se recibió más de lo esperado |

Verifique cada webhook con HMAC-SHA256 antes de procesar. Consulte [Webhook Signature Verification](/es/docs/developers/webhook-signature-verification) y [Webhooks](/es/docs/developers/webhooks).

## Estados de la solicitud de pago

```mermaid
stateDiagram-v2
    [*] --> pending: Checkout created
    pending --> created: Payer selects UAI / vault assigned
    created --> expired: 8 min timeout
    created --> processing: On-chain payment detected
    processing --> completed: Amount matches
    processing --> underpaid: Amount too low
    processing --> overpaid: Amount too high
    completed --> confirmed: Internal transaction created
    overpaid --> confirmed: Internal transaction created

    expired --> [*]
    underpaid --> [*]
    confirmed --> [*]
    completed --> [*]
    overpaid --> [*]
```

| State | Description | Merchant action |
| ----- | ----------- | --------------- |
| **`pending`** | Creada vía checkout; el pagador aún no ha seleccionado un UAI | Mostrar checkout / selector de activo |
| **`created`** | Vault asignado; en espera de pago on-chain (**ventana de 8 minutos**) | Mostrar token NASPIP; consultar o usar webhooks |
| **`processing`** | Transferencia detectada; en espera de finalidad blockchain | Informar al cliente que el pago se está confirmando |
| **`completed`** | Pago completo confirmado tras finalidad | Cumplir pedido |
| **`confirmed`** | Transacción interna de ledger creada | Pago liquidado en contabilidad Fluxis |
| **`underpaid`** | Confirmado pero el importe es menor al esperado | Consulte [Edge Cases](/es/docs/payment-flows/edge-cases#underpaid) |
| **`overpaid`** | Confirmado pero el importe excede lo esperado | Consulte [Edge Cases](/es/docs/payment-flows/edge-cases#overpaid) |
| **`expired`** | No se recibió pago antes de la expiración | Crear una nueva solicitud de pago |

::::warning
**No cumplir en `processing`**

Espere `completed`, `underpaid` o `overpaid` antes de cumplir pedidos. El estado `processing` significa que se detectó una transferencia pero aún no alcanzó finalidad.
::::

## Tiempos y expiración

Dos timeouts distintos aplican según el flujo:

| Flow | Timeout | Applies to |
| ---- | ------- | ---------- |
| **Payment request** | **8 minutos** | Desde asignación de vault (estado `created`) hasta expiración |
| **Payment intention** | **5 minutos** | Flujo PoS caja (`cashier_fixed` / `cashier_open`) antes de que el comerciante cree la solicitud de pago |

::::info
**Cron de expiración**

Un trabajo en segundo plano se ejecuta cada **30 segundos** para marcar solicitudes de pago con estado `created` y `expiration < now` como **`expired`**. Las transacciones transmitidas cerca del plazo aún pueden detectarse mientras el vault permanezca en caché brevemente tras la expiración.
::::

Para el flujo de caja, el comerciante crea una intención de pago vía `POST /v1/pos/{posID}/payment-intention` con una ventana de **5 minutos**. Una vez confirmada, Fluxis crea la solicitud de pago con la ventana estándar de 8 minutos.

## Secuencia end-to-end

```mermaid
sequenceDiagram
    participant M as Merchant
    participant F as Fluxis API
    participant C as Customer
    participant B as Blockchain
    participant Cron as Cron
    participant W as Worker

    M->>F: POST /v1/pos/:posID/payment-request
    F-->>M: status: created, NASPIP token
    M->>C: Display QR / payment link
    C->>B: Send USDC to vault address
    Cron->>B: eth_getLogs (every 3s)
    Cron->>W: SQS: transaction_incoming_payment
    W->>M: Webhook: processing
    Note over W: Finality delay (~256s)
    W->>B: Verify transaction confirmed
    W->>M: Webhook: completed
    W->>W: Create internal transaction
    Note over W: status → confirmed (no webhook)
    M->>C: Order fulfilled
```

## Opciones de monitoreo

| Method | Endpoint / setup | Best for |
| ------ | ---------------- | -------- |
| **Webhooks (recommended)** | `POST /v1/account/{accountID}/webhook` | Producción — actualizaciones de estado en tiempo real |
| **Polling** | `GET /v1/pos/{posID}/payment-request/{paymentRequestID}` | Desarrollo o respaldo de webhook |
| **Transactions list** | `GET /v1/transactions?page=1&page_size=50` | Conciliación tras `confirmed` |

## Documentación relacionada

- [Creating Payment Requests](/es/docs/merchant-integration/create-payreq) — Guía de integración con ejemplos de API
- [Payment Requests](/es/docs/key-concepts/payment-request) — Estados, campos y flujo de checkout
- [Payment Flows — Edge Cases](/es/docs/payment-flows/edge-cases) — Underpaid, overpaid, expired, transacciones fallidas, reembolsos
- [Webhooks](/es/docs/developers/webhooks) — Registro y formato de payload
- [Webhook Signature Verification](/es/docs/developers/webhook-signature-verification) — Verificación HMAC y flujo de prueba
- [NASPIP](/es/docs/key-concepts/naspip/introduction) — Formato de token y compatibilidad con wallets
- [API Reference — Point of Sale](/api/point-of-sale) — Documentación interactiva de endpoints
