> ## Documentation Index
> Fetch the complete documentation index at: https://docs.purincash.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Receber por PIX

> Os dois endpoints de PIX, quando usar cada um e como reconciliar sem passar vergonha.

Existem dois jeitos de gerar um PIX, e a diferença não é estilo: eles aceitam recursos
diferentes.

**Os dois aceitam valor solto.** Não é que um seja "com produto" e o outro "sem". Em
`/v1/payments` o `productId` é opcional: sem ele, você manda `valueCents` e funciona
igual. O que separa de verdade é o que cada um faz **além** disso.

| Você quer                                   | Use                                            | ID         |
| ------------------------------------------- | ---------------------------------------------- | ---------- |
| Só gerar um PIX de um valor                 | `POST /v1/charges`                             | `psc_`     |
| Dividir o valor com outras contas           | `POST /v1/charges` com `splits`                | `psplit_`  |
| O preço vir de um produto cadastrado        | `POST /v1/payments` com `productId`            | `psa_`     |
| Cobrar em [Litecoin](/guias/cripto)         | `POST /v1/payments` com `paymentMethod: "ltc"` | `psa_`     |
| [Assinatura](/guias/assinaturas) recorrente | `POST /v1/subscriptions`                       | `psa_sub_` |

<Tip>
  Regra prática: **quer só um valor, usa `charges`.** É o caminho mais curto, e é o único
  que faz split. Vá pra `payments` quando precisar de catálogo, cripto ou assinatura.
</Tip>

Uma coisa que **os dois** aceitam: o campo `supplier`, que amarra a cobrança a um produto
da sua loja pra [entrega automática](/guias/entrega#amarrando-o-produto). Isso é
independente de qual endpoint você escolheu.

## Criando

<CodeGroup>
  ```bash Valor livre theme={null}
  curl -X POST https://api.purincash.com/v1/charges \
    -H "Authorization: Bearer $PURINCASH_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "valueCents": 1990,
      "description": "Plano Pro",
      "callbackUrl": "https://minhaloja.com/webhooks/purincash",
      "customer": { "name": "João Silva", "email": "joao@exemplo.com" },
      "metadata": "{\"pedido\":\"1042\"}"
    }'
  ```

  ```bash A partir de um produto theme={null}
  curl -X POST https://api.purincash.com/v1/payments \
    -H "Authorization: Bearer $PURINCASH_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "productId": "665f1a2b3c4d5e6f7a8b9c0d",
      "callbackUrl": "https://minhaloja.com/webhooks/purincash",
      "customer": { "name": "João Silva", "externalId": "user_42" }
    }'
  ```
</CodeGroup>

```json Resposta theme={null}
{
  "paymentId": "psc_a1b2c3d4e5f6",
  "status": "pending",
  "amountCents": 1990,
  "currency": "BRL",
  "environment": "live",
  "pix": {
    "brCode": "00020126580014br.gov.bcb.pix0136...",
    "qrCodeImage": "https://qr.exemplo.com/psc_a1b2c3d4e5f6.png"
  },
  "expiresAt": "2026-03-18T12:30:00.000Z"
}
```

<Note>
  Em `/v1/payments`, se você mandar `productId` e `valueCents` ao mesmo tempo, o preço do
  produto vence. Produto em moeda diferente de BRL é convertido para real na hora da
  cobrança.

  Sem `productId`, o `valueCents` manda e a `description` vira o nome do pagamento
  (padrão `"Pagamento"` quando você não mandar nenhuma).
</Note>

<Warning>
  Cuidado pra não confundir dois campos com nome parecido:

  `productId` é produto **de cobrança**, criado por `POST /v1/products`. Ele define o
  preço.

  `supplier.productId` é produto **da loja**, no formato `prod_xxx`. Ele não define preço
  nenhum: serve pra entrega automática. Passar um no lugar do outro devolve `404`.
</Warning>

## Valor mínimo

O piso da plataforma é **R\$ 0,80** (`valueCents: 80`), mas cada loja pode configurar um
mínimo maior no painel. Quando o valor não passa, o erro `400` já diz qual é o mínimo
daquela conta:

```json theme={null}
{ "error": "valueCents must be >= 500 (R$ 5.00), or provide productId" }
```

Vale ler esse número em vez de fixar `80` no seu código.

## Ciclo de vida

<Steps>
  <Step title="pending">
    A cobrança existe e o `brCode` funciona. Dura 30 minutos.
  </Step>

  <Step title="paid">
    O PIX caiu. O webhook sai nesse momento e o valor entra no seu saldo.
  </Step>

  <Step title="expired">
    Passou dos 30 minutos sem pagamento. O código não funciona mais. Para tentar de novo,
    crie outra cobrança.
  </Step>

  <Step title="refunded / cancelled">
    Estorno ou cancelamento posterior. Vale conferir esses status antes de entregar algo
    de valor alto.
  </Step>
</Steps>

## Reconciliando

Faça as duas coisas. Elas cobrem falhas diferentes.

<AccordionGroup>
  <Accordion title="Webhook: rápido, mas não confiável sozinho" icon="bell" defaultOpen>
    A entrega é feita assim que o pagamento confirma, com reentrega automática em caso de
    falha. Ainda assim, a sua URL é pública e qualquer um pode chamá-la.

    Sempre [valide a assinatura](/webhooks/assinatura) e deduplique pelo header
    `X-Webhook-Id`.
  </Accordion>

  <Accordion title="Consulta: lenta, mas definitiva" icon="magnifying-glass">
    `GET /v1/charges/{paymentId}` e `GET /v1/payments/{paymentId}` devolvem o estado
    atual. Use antes de entregar algo caro, e como rede de segurança quando o webhook não
    chegou.

    ```bash theme={null}
    curl https://api.purincash.com/v1/charges/psc_a1b2c3d4e5f6 \
      -H "Authorization: Bearer $PURINCASH_KEY"
    ```
  </Accordion>

  <Accordion title="Polling: último recurso" icon="clock-rotate-left">
    Se precisar mesmo, use intervalo de 5 segundos ou mais e pare no primeiro status
    final. O [limite de 120 requisições por minuto](/guias/limites) vale para tudo
    somado.
  </Accordion>
</AccordionGroup>

<Warning>
  Antes de liberar o produto, confira `amountCents` além do `status`. Um pagamento pago
  com valor menor que o esperado não deveria virar entrega.
</Warning>

## Dados do pagador

No webhook `charge.paid` chegam campos que não existem na criação, porque vêm do banco:

| Campo        | Conteúdo                                       |
| ------------ | ---------------------------------------------- |
| `payer`      | Nome de quem pagou                             |
| `bank`       | Banco de origem, no formato `código - nome`    |
| `endToEndId` | Identificador end-to-end da transação no Bacen |
| `txId`       | txid da transação                              |

Servem para conciliação bancária e para responder [disputa](/guias/disputas). CPF,
telefone e endereço não são enviados em webhook.

<CardGroup cols={2}>
  <Card title="Dividir o valor" icon="chart-pie" href="/guias/splits">
    Marketplace, comissão ou sociedade, resolvido no momento do pagamento.
  </Card>

  <Card title="Entregar sozinho" icon="truck-fast" href="/guias/entrega">
    Chave ou conta liberada assim que o PIX confirma.
  </Card>
</CardGroup>
