# Polling

Os [webhooks de notificação](/pt-br/products/payments-direct-2/api-docs/payment-monitoring/notification-webhooks) são a forma recomendada de acompanhar as mudanças de estado do pagamento no Payments Direct. No entanto, se a sua integração não puder receber webhooks de entrada (por exemplo, por restrições de rede ou regras de firewall que impeçam uma URL de callback HTTPS pública), você pode fazer polling na API para detectar atualizações de pagamento.

Este tópico descreve quando e como fazer polling de forma eficaz e aborda dois padrões complementares:

- **Polling de pagamento único:** acompanha o estado de um pagamento específico pelo `paymentId`
- **Polling de busca em lote:** detecta todos os pagamentos atualizados desde um determinado timestamp


Combine polling com webhooks sempre que possível
Polling e webhooks não são mutuamente exclusivos. Mesmo quando os webhooks são o seu mecanismo principal de notificação, um polling periódico de busca em lote é uma rede de segurança útil para capturar transições de estado que o seu handler de webhook possa ter perdido por falhas de entrega ou entrega fora de ordem.

## Quando usar cada padrão

| Padrão | Indicado para |
|  --- | --- |
| Polling de pagamento único | Acompanhar o resultado de um pagamento específico que você acabou de criar |
| Polling de busca em lote | Conciliar todos os pagamentos atualizados desde a sua última verificação; capturar notificações de webhook perdidas |


## Polling de pagamento único

Use `GET /v3/payments/{paymentId}` para verificar o estado atual de um pagamento específico.

**Exemplo: fazer polling de um pagamento por ID**

```bash
curl -X GET "https://{base-url}/v3/payments/5ce2c433-a96d-48d0-8857-02637a60abf4" \
  -H "Authorization: Bearer <access_token>"
```

**Resposta (200 OK)**

```json
{
  "paymentId": "5ce2c433-a96d-48d0-8857-02637a60abf4",
  "paymentState": "TRANSFERRING",
  "initiatedAt": "2025-10-01T14:00:00.000Z",
  "updatedAt": "2025-10-01T14:00:45.321Z",
  "expiresAt": "2025-11-30T14:00:00.000Z"
}
```

Repita a requisição em intervalos fixos até que o pagamento chegue a um estado terminal: `COMPLETED`, `FAILED`, `DECLINED` ou `RETURNED`.

Use updatedAt, não a ordem de chegada
Se estiver comparando várias respostas, use `updatedAt` para determinar o estado mais recente. Não confie na ordem em que as respostas chegam, porque as condições de rede podem fazer com que elas cheguem fora de sequência.

### Orientações sobre o intervalo de polling

- Não faça polling com frequência maior que **30 segundos** para pagamentos ativos.
- Para pagamentos nos estados iniciais `INITIATED` ou `VALIDATING`, um intervalo de 30 a 60 segundos é adequado.
- Quando um pagamento chega a `TRANSFERRING`, o tempo até a conclusão depende do corredor e do payment rail. Ajuste o seu intervalo para atender aos seus requisitos de SLA.
- Pare o polling quando o pagamento chegar a um estado terminal (`COMPLETED`, `FAILED`, `DECLINED`, `RETURNED`).


### Tratamento de erros no polling de pagamento único

| Status HTTP | Ação |
|  --- | --- |
| `200 OK` | Leia `paymentState` e continue o polling se não for terminal |
| `404 Not Found` | O ID do pagamento é inválido ou não pertence à sua conta |
| `429 Too Many Requests` | Aplique espera exponencial antes de tentar novamente (consulte [Espera exponencial](#espera-exponencial)) |
| `500` / `503` | Repita com espera exponencial; acione um alerta se a condição persistir |


## Polling de busca em lote

Use `POST /v3/payments` (Search payments) para recuperar todos os pagamentos cujo estado foi atualizado pela última vez dentro de um intervalo de tempo. Esta é a abordagem recomendada para conciliação e para integrações que processam grandes volumes de pagamentos.

A combinação de filtros principal:

- `filterRangeType: PAYMENT_STATUS_LAST_UPDATED`: filtra pelo momento em que um pagamento mudou de estado pela última vez
- `afterTimestamp`: o timestamp do seu último polling bem-sucedido (o seu "cursor")
- `beforeTimestamp`: o horário atual (opcional, mas recomendado para evitar processar atualizações em andamento)


### Etapa 1: Requisição inicial

```bash
curl -X POST "https://{base-url}/v3/payments" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {
      "filterRangeType": "PAYMENT_STATUS_LAST_UPDATED",
      "afterTimestamp": "2025-10-01T14:00:00Z",
      "beforeTimestamp": "2025-10-01T14:05:00Z"
    },
    "page": {
      "size": 100
    }
  }'
```

**Resposta (200 OK)**

```json
{
  "data": [
    {
      "paymentId": "5ce2c433-a96d-48d0-8857-02637a60abf4",
      "paymentState": "COMPLETED",
      "updatedAt": "2025-10-01T14:03:12.000Z"
    },
    {
      "paymentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "paymentState": "FAILED",
      "updatedAt": "2025-10-01T14:04:55.000Z"
    }
  ],
  "filter": { "filterRangeType": "PAYMENT_STATUS_LAST_UPDATED", "afterTimestamp": "2025-10-01T14:00:00Z", "beforeTimestamp": "2025-10-01T14:05:00Z" },
  "page": {
    "size": 100,
    "lastPageToken": "eyJrZXkiOiJhMWIyYzNkNCJ9"
  }
}
```

### Etapa 2: Paginar os resultados

Se a resposta incluir um `page.lastPageToken`, há mais resultados. Inclua-o na próxima requisição para recuperar a página seguinte.

```bash
curl -X POST "https://{base-url}/v3/payments" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {
      "filterRangeType": "PAYMENT_STATUS_LAST_UPDATED",
      "afterTimestamp": "2025-10-01T14:00:00Z",
      "beforeTimestamp": "2025-10-01T14:05:00Z"
    },
    "page": {
      "size": 100,
      "lastPageToken": "eyJrZXkiOiJhMWIyYzNkNCJ9"
    }
  }'
```

Continue paginando até que uma resposta não retorne `lastPageToken`. Nesse ponto, todos os resultados desta janela de tempo foram recuperados.

### Etapa 3: Avançar o cursor

Depois de esgotar todas as páginas de uma janela de tempo, registre o `beforeTimestamp` daquela requisição como o novo `afterTimestamp` do próximo ciclo de polling.

```
afterTimestamp (next poll) = beforeTimestamp (this poll)
```

Isso cria um cursor estável e sem sobreposição, que evita que você perca transições de estado entre os pollings.

Use um beforeTimestamp fixo por ciclo de polling
Defina `beforeTimestamp` como o horário atual **antes** de começar a paginar e mantenha-o constante em todas as páginas do mesmo ciclo de polling. Se você usar um timestamp móvel entre as páginas, corre o risco de perder atualizações ocorridas enquanto paginava.

### Intervalo do polling de busca em lote

- Execute o seu polling de busca em lote a cada **1 a 5 minutos**, conforme o seu volume e o SLA de conciliação.
- Em integrações de alto volume, um intervalo de 1 minuto com `page.size: 100` oferece um bom equilíbrio entre agilidade e eficiência da API.
- Se um ciclo de polling retornar zero resultados, aumente um pouco o intervalo (por exemplo, dobre-o, até um máximo de 10 minutos) para reduzir carga desnecessária.


## Tratamento de estados terminais

Quando um pagamento chega a um estado terminal (`COMPLETED`, `FAILED`, `DECLINED` ou `RETURNED`), pare o polling daquele pagamento e processe o resultado.

Nos estados `FAILED`, `DECLINED` e `RETURNED`, o payload do webhook (e os resultados da busca) não incluem detalhes do erro. Para obter o motivo da falha, chame `GET /v3/payments/{paymentId}` depois de detectar o estado terminal.

Para mais informações sobre os estados terminais e o significado deles, consulte [Ciclo de vida do pagamento](/pt-br/products/payments-direct-2/introduction/concepts/payment-lifecycle).

## Espera exponencial

Aplique espera exponencial com jitter quando receber `429 Too Many Requests` ou erros de servidor `5xx`:

1. Na primeira falha, aguarde um intervalo base curto (por exemplo, 2 segundos).
2. A cada falha seguinte, dobre o tempo de espera.
3. Adicione um jitter aleatório (por exemplo, ±10 a 20% do intervalo) para evitar tempestades de novas tentativas sincronizadas.
4. Limite a espera máxima a um teto razoável (por exemplo, 5 minutos).
5. Após um número configurável de novas tentativas sem sucesso, acione a sua equipe de plantão.


**Exemplo de escalonamento de espera:**

| Nova tentativa | Espera antes de tentar novamente |
|  --- | --- |
| 1 | 2s |
| 2 | 4s |
| 3 | 8s |
| 4 | 16s |
| 5 | 32s |
| 6+ | 60s (limite) |


## Fluxograma do polling

O fluxograma a seguir ilustra o laço de polling de busca em lote, incluindo a paginação e o avanço do cursor.

![Fluxograma de polling de pagamentos](../../images/rri-polling-payments-flowchart.svg)

## Próximos passos

- Para receber notificações push em vez de fazer polling, consulte [Webhooks de notificação](/pt-br/products/payments-direct-2/api-docs/payment-monitoring/notification-webhooks).
- Para orientações sobre os estados de pagamento que as suas respostas de polling retornarão, consulte [Ciclo de vida do pagamento](/pt-br/products/payments-direct-2/introduction/concepts/payment-lifecycle).
- Para ver a referência completa da API de busca de pagamentos, consulte [Search payments (v3)](/pt-br/products/payments-direct-2/api-docs/payments-direct-api/payments-direct-2-api#operation/searchPaymentsV2).