# Fluxo de pagamento — Caminho feliz

Esta página descreve o **fluxo de pagamento end-to-end padrão** na Fluxis: desde a criação de uma solicitação de pagamento até a detecção on-chain, processamento assíncrono e entrega de webhooks. Para resultados não padrão (pagamento insuficiente, expiração, transações falhas), consulte [Fluxos de pagamento — Casos extremos](/pt/docs/payment-flows/edge-cases).

## Visão geral da arquitetura

O processamento de pagamentos Fluxis abrange quatro serviços 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** | Cria solicitações de pagamento, atribui endereços vault, gera [tokens NASPIP](/pt/docs/key-concepts/naspip/introduction), expõe endpoints REST |
| **Cron** | Consulta blockchains a cada **3 segundos** por eventos ERC-20 `Transfer` para endereços vault ativos |
| **Transaction Worker** | Consome a fila SQS `transactions` e executa o ciclo de vida de pagamento de **3 saltos** |
| **Crypto Service** | Serviço externo para gerenciamento de vaults, consolidação e liquidação (pós-pagamento) |

Comerciantes interagem apenas com a Core API e [webhooks em nível de conta](/pt/docs/developers/webhooks). Monitoramento blockchain e confirmação de transações ocorrem de forma assíncrona.

## Pré-requisitos

Antes que um pagamento possa ser bem-sucedido, a hierarquia do comerciante deve 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](/pt/docs/merchant-integration/sign-up).
2. **Point of Sale** — Um PoS `online_fixed` (e-commerce) ou `cashier_fixed` (caixa física). Consulte [Point of Sale](/pt/docs/key-concepts/point-of-sale).
3. **Authentication** — Bearer token + `x-fluxis-api-key` em rotas protegidas. Consulte [Authentication & Configuration](/pt/docs/merchant-integration/auth-and-conf).
4. **Webhook (recommended)** — Registre em nível de conta: `POST /v1/account/{accountID}/webhook`. Consulte [Webhooks](/pt/docs/developers/webhooks).

## Passo 1 — Criar uma solicitação de pagamento

Crie uma solicitação de pagamento pelo endpoint do **Point of Sale** — não uma rota independente `/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 hospedado**

Quando o pagador deve escolher o ativo entre as `payment_options` do PoS, use `POST /v1/pos/{posID}/payment-request-checkout`. A solicitação de pagamento inicia em status `pending` e transiciona para `created` quando o pagador seleciona um UAI. Consulte [Creating Payment Requests](/pt/docs/merchant-integration/create-payreq).
::::

### O que a Fluxis faz 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
```

Na criação, a Fluxis:

1. Valida o PoS e resolve o [UAI](/pt/docs/key-concepts/uai)
2. Atribui um **endereço vault** único do pool pré-implantado
3. Define status **`created`** e timestamp de **expiração de 8 minutos**
4. Armazena em cache o endereço vault no Redis para buscas rápidas do cron
5. Retorna um [token NASPIP](/pt/docs/key-concepts/naspip/introduction) para exibir QR / link de pagamento

Exemplo de resposta:

```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
  }
}
```

## Passo 2 — Cliente paga on-chain

O cliente escaneia o token NASPIP (QR code ou link) e envia o valor exato para o endereço vault na rede configurada. A Fluxis não detém custódia neste passo — o pagamento vai diretamente para o smart contract vault.

Sua aplicação deve:

- Exibir o token NASPIP e uma contagem regressiva baseada em `expiration`
- Consultar `GET /v1/pos/{posID}/payment-request/{paymentRequestID}` ou aguardar webhooks
- **Não** cumprir o pedido até o pagamento atingir um status terminal

## Passo 3 — Cron detecta a transferência

O serviço cron executa um job de leitura blockchain **a cada 3 segundos** em redes suportadas (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
```

Detalhes importantes:

- Usa `eth_getLogs` com **chunking adaptativo** para consultar eventos ERC-20 `Transfer` eficientemente
- Filtra transações onde o destinatário (`to`) corresponde a um endereço vault ativo em cache no Redis
- Enfileira transações correspondentes na fila SQS **`transactions`** com tipo de evento `transaction_incoming_payment`

## Passo 4 — Worker SQS de três saltos

O transaction worker processa cada pagamento por **três saltos SQS sequenciais**:

```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 a solicitação de pagamento está em `created` ou `processing`
- Atualiza status para **`processing`**
- Envia **webhook** com status `processing`
- Enfileira salto 2 com **atraso de finalidade** (padrão **256 segundos** na Polygon, configurável por rede)

### Salto 2 — `transaction_check_update_payment_request`

Após o atraso de finalidade:

- Chama `GetTransaction` para verificar status on-chain (pending / confirmed / failed)
- Usa o **valor da detecção `eth_getLogs` do cron** (não de `GetTransaction`, que falha em transações proxy/router)
- Compara valor recebido vs valor esperado:
  - Igual → **`completed`**
  - Menor → **`underpaid`**
  - Maior → **`overpaid`**
- Envia **webhook** com status final
- Enfileira salto 3 imediatamente e libera o vault

### Salto 3 — `transaction_confirm_payment_request`

- Executa apenas para pagamentos **`completed`** ou **`overpaid`**
- Cria registro interno de **Transaction** (taxas, endereços, entrada de ledger)
- Atualiza status da solicitação de pagamento para **`confirmed`**
- **Não** envia webhook (consulte a matriz de webhooks em [Edge Cases](/pt/docs/payment-flows/edge-cases))

::::info
**Pagamentos underpaid**

O salto 3 **não** executa para pagamentos `underpaid` — nenhuma transação interna é criada. Consulte [Edge Cases — Underpaid](/pt/docs/payment-flows/edge-cases#underpaid).
::::

## Passo 5 — Notificações webhook

A Fluxis entrega webhooks em nível de conta quando o status da solicitação de pagamento muda durante os saltos 1 e 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 detectou transferência on-chain para o vault |
| `completed` | Confirmado após finalidade; valor corresponde ao esperado |
| `underpaid` | Confirmado após finalidade; recebido menos que o esperado |
| `overpaid` | Confirmado após finalidade; recebido mais que o esperado |

Verifique cada webhook com HMAC-SHA256 antes de processar. Consulte [Webhook Signature Verification](/pt/docs/developers/webhook-signature-verification) e [Webhooks](/pt/docs/developers/webhooks).

## Estados da solicitação de pagamento

```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`** | Criada via checkout; pagador ainda não selecionou um UAI | Exibir checkout / seletor de ativo |
| **`created`** | Vault atribuído; aguardando pagamento on-chain (**janela de 8 minutos**) | Exibir token NASPIP; consultar ou usar webhooks |
| **`processing`** | Transferência detectada; aguardando finalidade blockchain | Informar cliente que pagamento está sendo confirmado |
| **`completed`** | Pagamento integral confirmado após finalidade | Cumprir pedido |
| **`confirmed`** | Transação interna de ledger criada | Pagamento liquidado na contabilidade Fluxis |
| **`underpaid`** | Confirmado, mas valor menor que o esperado | Consulte [Edge Cases](/pt/docs/payment-flows/edge-cases#underpaid) |
| **`overpaid`** | Confirmado, mas valor excede o esperado | Consulte [Edge Cases](/pt/docs/payment-flows/edge-cases#overpaid) |
| **`expired`** | Nenhum pagamento recebido antes da expiração | Criar nova solicitação de pagamento |

::::warning
**Não cumprir em `processing`**

Aguarde `completed`, `underpaid` ou `overpaid` antes de cumprir pedidos. O status `processing` significa que uma transferência foi detectada, mas ainda não atingiu finalidade.
::::

## Temporização e expiração

Dois timeouts distintos se aplicam conforme o fluxo:

| Flow | Timeout | Applies to |
| ---- | ------- | ---------- |
| **Payment request** | **8 minutos** | Desde atribuição de vault (status `created`) até expiração |
| **Payment intention** | **5 minutos** | Fluxo PoS caixa (`cashier_fixed` / `cashier_open`) antes do comerciante criar a solicitação de pagamento |

::::info
**Cron de expiração**

Um job em segundo plano executa a cada **30 segundos** para marcar solicitações de pagamento com status `created` e `expiration < now` como **`expired`**. Transações transmitidas perto do prazo ainda podem ser detectadas enquanto o vault permanece em cache brevemente após a expiração.
::::

Para o fluxo de caixa, o comerciante cria uma intenção de pagamento via `POST /v1/pos/{posID}/payment-intention` com janela de **5 minutos**. Uma vez confirmada, a Fluxis cria a solicitação de pagamento com a janela padrão de 8 minutos.

## Sequência 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
```

## Opções de monitoramento

| Method | Endpoint / setup | Best for |
| ------ | ---------------- | -------- |
| **Webhooks (recommended)** | `POST /v1/account/{accountID}/webhook` | Produção — atualizações de status em tempo real |
| **Polling** | `GET /v1/pos/{posID}/payment-request/{paymentRequestID}` | Desenvolvimento ou fallback de webhook |
| **Transactions list** | `GET /v1/transactions?page=1&page_size=50` | Reconciliação após `confirmed` |

## Documentação relacionada

- [Creating Payment Requests](/pt/docs/merchant-integration/create-payreq) — Guia de integração com exemplos de API
- [Payment Requests](/pt/docs/key-concepts/payment-request) — Status, campos e fluxo de checkout
- [Payment Flows — Edge Cases](/pt/docs/payment-flows/edge-cases) — Underpaid, overpaid, expired, transações falhas, reembolsos
- [Webhooks](/pt/docs/developers/webhooks) — Registro e formato de payload
- [Webhook Signature Verification](/pt/docs/developers/webhook-signature-verification) — Verificação HMAC e fluxo de teste
- [NASPIP](/pt/docs/key-concepts/naspip/introduction) — Formato de token e compatibilidade com wallets
- [API Reference — Point of Sale](/api/point-of-sale) — Documentação interativa de endpoints
