# Webhook URL

## Visão geral

Este recurso entrega os dados de uma cobrança paga ao servidor do lojista. Ele existe para que a loja do lojista processe o pagamento automaticamente e entregue o produto ou serviço ao seu cliente.

A Webhook URL é definida individualmente para cada projeto e aponta para os scripts de tratamento de pagamentos dentro da loja do lojista. O endereço deve usar HTTPS e um nome de domínio: endereços IP não são aceitos, e o certificado é verificado a cada entrega.

Toda vez que o status de uma cobrança muda para Paga, o serviço envia uma requisição POST para essa URL no seguinte formato:

```json
{
   "wallet":{
      "id":"47aa71e2-07a0-482e-9172-7114d7376ba0",
      "name":"usdt-tron",
      "blockchain":"tron",
      "cryptocurrency":"usdt",
      "address":"TKbstUwMzLrfTAGL4erYb7gc7ghmHQ9zG7"
   },
   "project":{
      "id":"9deea1e2-0c08-41a3-bdc2-a34eada3892d",
      "name":"My project",
      "commissionPayer":"seller",
      "commissionRate":1
   },
   "invoice":{
      "id":"a4c9e2ee-9a03-43e5-a1a1-00caf679d16a",
      "uid":"AFhygKX21ecd",
      "createDatetime":"2024-02-26 13:29:24",
      "timeToPayDatetime":"2024-02-27 01:29:24",
      "commissionFiatUSD":0.05,
      "amountFiatUSD":5.02,
      "amountFiat":5,
      "calcAmountFiat":5.02,
      "currencyFiat":"USD",
      "description":null,
      "serviceData":null,
      "status":"paid"
   },
   "payment":{
      "id":"f986ad8d-2298-473d-982a-efbc817b975d",
      "amount":5.02,
      "hash":"74763b65e43bcc9492a6ce9a7f26fbfdbd7635aecd3454420b5e9534cba50ee6",
      "transactionDatetime":"2024-02-26 13:32:57"
   }
}
```

A notificação é enviada a cada transição para Paga — tanto quando o serviço encontrou o pagamento automaticamente quanto quando o lojista vinculou o pagamento à cobrança manualmente.

## Parâmetros da requisição

| Parâmetro                     | Descrição                                                                                                                                                                                                                                                                                        |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `wallet.id`                   | ID da carteira no formato UUID                                                                                                                                                                                                                                                                   |
| `wallet.name`                 | Nome da carteira                                                                                                                                                                                                                                                                                 |
| `wallet.blockchain`           | O blockchain da carteira cripto                                                                                                                                                                                                                                                                  |
| `wallet.cryptocurrency`       | A criptomoeda da carteira                                                                                                                                                                                                                                                                        |
| `wallet.address`              | O endereço da carteira cripto                                                                                                                                                                                                                                                                    |
| `project.id`                  | ID do projeto no formato UUID                                                                                                                                                                                                                                                                    |
| `project.name`                | Nome do projeto                                                                                                                                                                                                                                                                                  |
| `project.commissionPayer`     | Quem paga a taxa do serviço                                                                                                                                                                                                                                                                      |
| `project.commissionRate`      | Taxa em %                                                                                                                                                                                                                                                                                        |
| `invoice.id`                  | ID da cobrança no formato UUID                                                                                                                                                                                                                                                                   |
| `invoice.uid`                 | ID da cobrança (para o cliente)                                                                                                                                                                                                                                                                  |
| `invoice.createDatetime`      | Data e hora de criação da cobrança (UTC)                                                                                                                                                                                                                                                         |
| `invoice.timeToPayDatetime`   | Data e hora até as quais a cobrança é válida para o cliente (UTC). A busca de pagamentos continua por mais 1 hora depois dessa marca — para levar em conta redes lentas. Por isso uma notificação pode chegar para uma cobrança que já era exibida como expirada                                  |
| `invoice.commissionFiatUSD`   | Valor da taxa do serviço. Calculado a partir do valor `invoice.amountFiatUSD`                                                                                                                                                                                                                    |
| `invoice.amountFiatUSD`       | Valor em USD. Na criação da cobrança, é calculado a partir de `invoice.amountFiat` pela cotação atual. **No momento do pagamento, é sobrescrito com o valor efetivamente recebido**, convertido para USD pela cotação daquele momento. A taxa em `invoice.commissionFiatUSD` também é recalculada a partir dele |
| `invoice.amountFiat`          | O valor original da cobrança em moeda fiat. Não muda                                                                                                                                                                                                                                             |
| `invoice.calcAmountFiat`      | O valor calculado na moeda `invoice.currencyFiat` pela cotação da cripto no momento do pagamento. Pode diferir de `invoice.amountFiat` porque o cliente pode ter pagado a cobrança algum tempo depois da criação, e não imediatamente. Nesse intervalo, a cotação da cripto em relação a `invoice.currencyFiat` pode se mover para qualquer lado |
| `invoice.currencyFiat`        | Moeda fiat                                                                                                                                                                                                                                                                                       |
| `invoice.description`         | A descrição definida na criação da cobrança                                                                                                                                                                                                                                                      |
| `invoice.serviceData`         | Os dados de serviço definidos na criação da cobrança                                                                                                                                                                                                                                             |
| `invoice.status`              | Status da cobrança                                                                                                                                                                                                                                                                               |
| `payment.id`                  | ID do pagamento no formato UUID                                                                                                                                                                                                                                                                  |
| `payment.amount`              | Valor do pagamento em criptomoeda                                                                                                                                                                                                                                                                |
| `payment.hash`                | O hash da transação on-chain                                                                                                                                                                                                                                                                     |
| `payment.transactionDatetime` | Data e hora da transação on-chain (UTC)                                                                                                                                                                                                                                                          |

## Assinatura da notificação

Cada requisição é assinada com o segredo do webhook. A assinatura viaja nos cabeçalhos `X-Timestamp` e `X-Signature` e permite ter certeza de que a notificação veio do serviço, e não de um estranho que descobriu o endereço do seu manipulador.

Verifique a assinatura antes de processar o pedido. A mecânica e exemplos prontos estão em [Verificação da assinatura do webhook](./signature-verification.md).

## Recomendações de tratamento

**Não rejeite uma notificação porque o prazo de pagamento passou.** Uma verificação como “a cobrança expirou, logo o pagamento é inválido” parece lógica, mas corta uma parte dos pagamentos reais: em redes lentas uma transação pode ser confirmada depois do prazo, e o lojista pode vincular manualmente um pagamento a uma cobrança expirada. A própria notificação confirma o pagamento.

**Confira o valor com o campo original** `invoice.amountFiat`. Esse é o valor da cobrança como emitida, e ele não muda. O campo `amountFiatUSD` reflete o valor efetivamente recebido e pode diferir do emitido — tanto pelo movimento da cotação quanto pela vinculação manual de pagamentos.

**Faça o parse dos valores como números.** Zeros à direita são descartados: um valor de 10.00 chega como 10; formate-o do seu lado para exibição. Valores abaixo de 0.0001 chegam em notação exponencial, por exemplo 1.0e-6 — o parse padrão de JSON retorna o número correto; só o parse manual de strings quebra.

**Trate as notificações de forma idempotente.** A mesma notificação pode chegar de novo — por exemplo, se o seu script processou o pagamento com sucesso mas retornou um código diferente de 2xx. Antes de entregar o pedido, verifique se este `invoice.id` já foi processado.

**Escape os valores na saída.** Os campos `invoice.description` e `invoice.serviceData` voltam exatamente como o lojista os enviou. Se você os renderiza em HTML, faça o escape do seu lado.

## Cronograma de entrega

O servidor na Webhook URL deve responder com um código HTTP 2xx. Qualquer outro código, um timeout ou uma conexão interrompida conta como falha de entrega.

Redirecionamentos não são seguidos: uma resposta 301 ou 302 é uma falha de entrega, não um salto para o novo endereço. Configure o endereço final do manipulador.

A conexão tem 5 segundos; a requisição inteira, 10 segundos. Se o manipulador não couber nisso, a entrega conta como falha.

Depois de uma falha de entrega, o serviço tenta de novo no seguinte cronograma:

* 5 minutos depois da última entrega com falha
* Depois de 15 minutos
* Depois de 30 minutos
* Depois de 1 hora
* Depois de 3 horas
* Depois de 6 horas
* Depois de 12 horas
* Depois de 24 horas

Depois disso, as tentativas de entrega param.

## Desativação da Webhook URL

Às vezes o script de webhook de uma loja processa o pagamento corretamente, mas retorna um código HTTP diferente de 2xx. Isso leva a novas tentativas frequentes do nosso servidor pelo cronograma acima, gerando carga extra tanto no nosso servidor quanto no seu.

Para prevenir esses casos, temos um mecanismo que desativa a Webhook URL em um projeto. Para evitá-lo, siga estes passos:

1. Altere o código do seu manipulador de webhook para que ele retorne um código 2xx, geralmente 200, no processamento bem-sucedido do pagamento. Teste-o com qualquer emulador, por exemplo o Postman.
2. Entre em contato com o suporte técnico para corrigir as configurações.
3. Reative a Webhook URL nas configurações do projeto e salve o projeto.
