> ## 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.

# Antes de ir pra produção

> A lista curta do que costuma quebrar no primeiro dia com dinheiro de verdade.

Você testou em sandbox e funcionou. Estes são os pontos que sandbox não pega.

## Segurança

<AccordionGroup>
  <Accordion title="A chave live não está no bundle do front" icon="key" defaultOpen>
    Procure por `ps_live_` no build final, não só no código. Um `console.log` esquecido ou
    uma variável sem prefixo de servidor já entrega a chave.

    Se ela estiver exposta, alguém pode criar cobrança em seu nome e, com [saque
    turbo](/guias/saques#saque-turbo), mandar dinheiro pra fora.
  </Accordion>

  <Accordion title="O webhook valida a assinatura" icon="signature" defaultOpen>
    A sua `callbackUrl` é pública. Sem [validar o
    `X-Webhook-Signature`](/webhooks/assinatura), qualquer pessoa manda um JSON com
    `"status": "paid"` e leva o produto de graça.

    Confira também que você está assinando o **corpo cru**, antes do parse. Um
    `express.json()` no lugar errado quebra a validação de um jeito que passa em teste e
    falha em produção.
  </Accordion>

  <Accordion title="O valor é conferido antes da entrega" icon="scale-balanced">
    Não basta o `status` ser `paid`. Compare o `amountCents` recebido com o valor que você
    esperava para aquele pedido antes de liberar qualquer coisa.
  </Accordion>

  <Accordion title="O webhook secret está fora do repositório" icon="lock">
    Variável de ambiente ou cofre. Se vazou, regenere no painel: o antigo para de funcionar
    na hora.
  </Accordion>
</AccordionGroup>

## Confiabilidade

<AccordionGroup>
  <Accordion title="O handler é idempotente" icon="repeat" defaultOpen>
    Webhook é reentregue quando a entrega falha, e a mesma confirmação pode chegar mais de
    uma vez. Deduplique pelo header `X-Webhook-Id`, que é estável entre as tentativas.

    O teste é simples: mande o mesmo payload duas vezes e veja se o cliente recebe o
    produto duas vezes.
  </Accordion>

  <Accordion title="Você responde 200 rápido e processa depois" icon="bolt">
    O timeout é de 5 segundos. Se o seu handler manda e-mail, gera licença e escreve em
    três tabelas antes de responder, ele vai estourar e você vai receber reentrega de
    coisa que já processou.

    Grave o evento, responda `200`, processe em fila.
  </Accordion>

  <Accordion title="Existe reconciliação além do webhook" icon="arrows-rotate">
    Webhook é notificação, não fonte da verdade. Tenha um job que varre pedidos parados em
    `pending` há mais de uma hora e confirma o estado por `GET`.
  </Accordion>

  <Accordion title="Você não faz retry de 202 e processing" icon="triangle-exclamation">
    Em [saques](/guias/saques), `202` e `status: "processing"` significam que o dinheiro
    pode já ter saído. Reenviar paga duas vezes.
  </Accordion>
</AccordionGroup>

## Configuração da conta

<Steps>
  <Step title="Chave PIX verificada">
    Sem verificação, o primeiro saque devolve `403`. Resolva isso antes de precisar do
    dinheiro, não depois.
  </Step>

  <Step title="URL de webhook cadastrada no painel">
    Os webhooks de [pedido](/webhooks/pedidos) e de [saque](/webhooks/saques) usam a URL
    configurada na conta, não a `callbackUrl` da cobrança.
  </Step>

  <Step title="Valor mínimo conferido">
    O painel permite subir o mínimo da loja acima de R\$ 0,80. Se o seu produto mais barato
    fica abaixo dele, a cobrança falha em produção e passava em sandbox.
  </Step>

  <Step title="Carteira LTC configurada, se for usar cripto">
    Sem carteira, `paymentMethod: "ltc"` devolve `503`.
  </Step>
</Steps>

## Operação

<CardGroup cols={2}>
  <Card title="Log com o tripé certo" icon="file-lines">
    Código HTTP, corpo do erro e `paymentId`. Com esses três, uma dúvida
    [no Discord](https://discord.gg/8eyQQFZZxY) vira uma resposta em vez de cinco.
  </Card>

  <Card title="Alerta de disputa" icon="gavel" href="/guias/disputas">
    Rode `GET /v1/disputes?status=aberta` diariamente. Contestação tem prazo.
  </Card>

  <Card title="Uma chave por serviço" icon="key" href="/guias/autenticacao">
    Dá pra revogar uma sem derrubar o resto, e dá pra saber quem gastou o limite.
  </Card>

  <Card title="Backoff no cliente" icon="gauge-high" href="/guias/limites">
    Com jitter. Sem ele, seus workers batem no `429` todos juntos.
  </Card>
</CardGroup>

## O teste final

Faça uma venda real de valor baixo, do início ao fim: cobrança, pagamento, webhook,
entrega e saque. É o único teste que cobre configuração de conta, e leva dez minutos.

<Card title="Travou em algum ponto?" icon="discord" href="https://discord.gg/8eyQQFZZxY" horizontal>
  Chama no Discord com o código HTTP, o corpo do erro e o `paymentId`. Costuma sair na
  primeira resposta.
</Card>
