# Valores, datas e identificadores

URL: https://staging.pagpolar.com/docs/guias/fundamentos/valores-datas-e-identificadores

> Envie valores em centavos, leia valores em reais, e use datas e os tipos de identificador da API sem errar.

## Valores nas respostas: reais, como número

Nas respostas da API, todo valor em dinheiro vem **em reais**, como número:

```json
{
  "total_amount": 197.9,
  "items": [
    { "amount": 197.9, "original_amount": 219.9, "discount_value": 22 }
  ]
}
```

`197.9` significa R$ 197,90.

> **No webhook é diferente**
>
> No webhook, a maioria dos valores chega como **texto**, por exemplo `"197.9000"`. Veja [Formato do evento](/docs/webhooks/formato-do-evento#valores).

## Valores que você envia: centavos, como número inteiro

Todo valor em dinheiro que você envia à API vai **em centavos**, como número inteiro. A unidade é a mesma em todos os campos:

| Onde                                                  | Campo         | Unidade                  | Exemplo para R$ 49,90 |
| ----------------------------------------------------- | ------------- | ------------------------ | --------------------- |
| `POST /offers` e `PATCH /offers/{id}`                 | `price`       | Centavos, número inteiro | `4990`                |
| `POST /plans/{id}/offers` e `PATCH /plan-offers/{id}` | `price`       | Centavos, número inteiro | `4990`                |
| Oferta informada na venda (`offer`)                   | `offer.value` | Centavos, número inteiro | `4990`                |

Nas quatro rotas, um `price` com casas decimais, como `49.9`, é recusado com `400`. Envie `4990`.

`offer.value` tem um valor mínimo. Por padrão, é `500` (R$ 5,00). Abaixo disso, a resposta é `400`. `price` não tem esse mínimo: a validação aceita qualquer inteiro a partir de `0`. Quem limita na prática, na oferta avulsa, é a [parcela mínima](/docs/guias/jornadas/criar-produto-e-oferta#parcela-minima).

A API converte para reais ao gravar. Por isso a oferta volta com `price` em reais na resposta.

## Parcela mínima

Numa oferta avulsa, cada parcela no cartão precisa valer pelo menos R$ 5,00 (valor padrão), senão a criação responde `400` com o valor da parcela e o mínimo em vigor na `message`. A conta, os exemplos e o que fazer estão em [A regra da parcela mínima](/docs/guias/jornadas/criar-produto-e-oferta#parcela-minima).

## Datas

* Datas nas respostas vêm em ISO 8601, em UTC: `2026-09-15T14:30:00.000Z`.
* Datas que ficam vazias vêm `null`. Exemplo: `paid_at` enquanto a venda não foi paga.
* Nos filtros, envie data e hora em ISO 8601 com fuso: `2026-09-15T23:59:59-03:00`.

## Identificadores

A API usa quatro tipos de identificador:

| Nome                   | Exemplo                                | O que é                                                                                    |
| ---------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------ |
| `id`                   | `a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d` | Id interno (uuid). Todo recurso tem.                                                       |
| `identifier`           | `PPO9876543210`                        | Código da venda ou da oferta. Veja [Códigos com prefixo](#codigos-com-prefixo).            |
| `external_reference`   | `PEDIDO-1234`                          | Código do **seu** pedido. Você envia na cobrança ou na assinatura, com até 255 caracteres. |
| `affiliate_identifier` | `PAO0123456789`                        | Código do afiliado, o mesmo do link de divulgação.                                         |

### Códigos com prefixo

Todo código é um prefixo seguido de 10 dígitos, que podem começar com zero. Nas respostas da API e no webhook, o código sai **sempre com o prefixo**. É o mesmo código que aparece no painel.

| Código   | Prefixo           | Exemplo         | Onde aparece                                                                                                                                                               |
| -------- | ----------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Venda    | `PPO`             | `PPO9876543210` | `identifier` da venda em `GET /sales`, `GET /sales/{identifier}` e `GET /payments/{identifier}`; `sale.identifier` do reembolso; `data.transaction.identifier` do webhook. |
| Oferta   | `PPP`             | `PPP1234567890` | `identifier` da oferta; `data.offer_identifier` da resposta `201` das cobranças; `items[].offer.identifier` da venda; `items[].price.identifier` do webhook.               |
| Afiliado | `PAO`, por padrão | `PAO0123456789` | `affiliate_identifier`, que você envia na cobrança e na assinatura.                                                                                                        |

Guarde e compare o código como ele chega, com o prefixo. Para ligar registros entre a API e o webhook, prefira o `id`.

Na entrada, o código funciona **com ou sem o prefixo**, em toda rota da tabela abaixo que aceita código. `PPP1234567890` e `1234567890` encontram a mesma oferta, e `PPO9876543210` e `9876543210` encontram a mesma venda.

### Qual identificador cada rota aceita

| Rota                                                     | Aceita                                                 |
| -------------------------------------------------------- | ------------------------------------------------------ |
| `GET /sales/{identifier}` e `GET /payments/{identifier}` | `id` da venda, código da venda ou `external_reference` |
| `GET /offers/{identifier}`                               | `id` ou código da oferta                               |
| `POST /plans/offer/{id}/subscribe`                       | `id` ou código da oferta de plano                      |
| `offer_identifier` no corpo das cobranças                | Código da oferta                                       |
| `sale_identifier` em `POST /refunds` e `GET /refunds`    | Código da venda                                        |
| Demais rotas com `{id}` no caminho                       | Só o `id` (uuid)                                       |

Onde a rota aceita código, você também pode enviar o link com o código no final: a API lê o último pedaço do link. Para a oferta, ela usa só os números desse pedaço. Para a venda, o pedaço precisa ter o formato do código da venda, descrito abaixo.

### Como a venda é encontrada

`GET /sales/{identifier}` testa o valor nesta ordem e para no primeiro que encontrar:

1. Se o valor é um uuid, procura pelo `id` da venda.
2. Se o valor tem o formato do código da venda, procura pelo código. O formato é: o prefixo seguido de 10 dígitos, sem diferenciar maiúsculas de minúsculas (`PPO0087103960` ou `ppo0087103960`); exatamente 10 dígitos, sem o prefixo (`0087103960`); ou um link cujo último pedaço é um desses dois.
3. Procura pela `external_reference`, com o texto exato. Se a mesma referência foi usada em mais de uma venda, devolve a mais recente.

Se nada for encontrado, a resposta é `404` com `Venda não encontrada`.

> **Não use o formato do código da venda na external_reference**
>
> Um valor fora desses formatos, como `PED-2026-09-15-01`, vai direto para o passo 3. Já uma `external_reference` com o formato do código da venda, como `0087103960` ou `PPO0087103960`, é procurada antes como código. Se ela bater com o código de **outra** venda, a API devolve essa outra venda.
>
>   Para achar todas as vendas de uma referência, use [`GET /sales?external_reference=<SUA_REFERENCIA>`](/docs/referencia/vendas/list-sales), que procura só pela referência.

## Documento e telefone

A API confere o formato do documento e do telefone antes de criar qualquer coisa. A regra vale para estes campos:

* `customer.document` e `customer.phone`, nas cobranças (`POST /payments/pix`, `POST /payments/boleto` e `POST /payments/credit-card`) e na criação de assinatura (`POST /plans/offer/{id}/subscribe`);
* `holder_document`, o documento do titular do cartão, na cobrança no cartão, na criação de assinatura, na troca de cartão (`PATCH /subscriptions/{id}/card`) e em `card` na troca de plano (`POST /subscriptions/{id}/plan-change`).

| Campo                                   | Formato                                                                                  | Exemplos fictícios                                      |
| --------------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| `customer.document` e `holder_document` | CPF com 11 dígitos ou CNPJ com 14 dígitos.                                               | `12345678909` ou `123.456.789-09`                       |
| `customer.phone`                        | DDD e número, com 10 ou 11 dígitos. Com o código do país 55 na frente, 12 ou 13 dígitos. | `11999998888`, `(11) 99999-8888` ou `+55 11 99999-8888` |

Pontuação é aceita e removida: no telefone, isso inclui espaços, parênteses e `+`. A API grava só os dígitos. `123.456.789-09` é gravado como `12345678909`, e `+55 11 99999-8888` como `5511999998888`.

Fora do formato, a resposta é `400 invalid_request` e nada é criado:

| Campo               | `message`                                                                                                                   |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `customer.document` | `Documento inválido: envie o CPF com 11 dígitos ou o CNPJ com 14 dígitos, com ou sem pontuação.`                            |
| `holder_document`   | `Documento do titular do cartão inválido: envie o CPF com 11 dígitos ou o CNPJ com 14 dígitos, com ou sem pontuação.`       |
| `customer.phone`    | `Telefone inválido: envie o DDD e o número, com 10 ou 11 dígitos (12 ou 13 com o código do país 55), com ou sem pontuação.` |

## Dados pessoais mascarados

Nas respostas da API, o documento e o telefone do cliente vêm mascarados:

| Campo                            | Valor guardado   | Valor na resposta    |
| -------------------------------- | ---------------- | -------------------- |
| `document` com 11 dígitos (CPF)  | `12345678909`    | `***.456.***-**`     |
| `document` com 14 dígitos (CNPJ) | `12345678000195` | `**.345.***/****-**` |
| `document` com outro tamanho     | qualquer         | `***`                |
| `phone`                          | `11987654321`    | `****4321`           |

O nome e o e-mail vêm completos.

Nos eventos de webhook esses dados chegam sem máscara. Veja [Dados pessoais no webhook](/docs/webhooks/formato-do-evento#dados-pessoais).
