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

# Ambientes e sandbox

> Como testar o fluxo inteiro, inclusive webhook, sem mover um centavo.

A API tem dois ambientes e uma URL só. Quem decide onde a requisição cai é o prefixo da
chave.

> [card] Produção
>
> Chave `ps_live_`.
>
> Cobrança de verdade, saldo de verdade, saque de verdade.

> [card] Sandbox
>
> Chave `ps_test_`.
>
> Nada é enviado a banco nenhum. O PIX gerado não é pagável.

> [!WARNING]
>
> O `brCode` do sandbox não é um código PIX de verdade. Ele volta como
> `SANDBOX_PIX_<paymentId>`, uma string sem valor nenhum: não escaneia, não cola em app
> de banco, ninguém paga por acidente.
>
> Se você renderizar isso num QR Code na sua tela de teste, o QR vai existir e não vai
> funcionar. É esperado.

Os dados são isolados de ponta a ponta. Uma cobrança criada com `ps_test_` não aparece
para `ps_live_`, e o saldo de sandbox é calculado só a partir das transações de teste.
Se o prefixo da chave não bater com o ambiente em que ela foi criada, a API responde
`401` em vez de escolher um ambiente por conta própria.

## Simulando pagamento

Como ninguém consegue pagar um PIX de sandbox, você marca como pago pela API:

```bash Cobrança (psc_) theme={null}
curl -X POST https://api.purin.cash/v1/sandbox/charges/psc_a1b2c3d4/simulate-paid \
  -H "Authorization: Bearer ps_test_sua_chave"
```

```bash Pagamento (psa_) theme={null}
curl -X POST https://api.purin.cash/v1/sandbox/payments/psa_a1b2c3d4/simulate-paid \
  -H "Authorization: Bearer ps_test_sua_chave"
```

O status vira `paid` e o webhook sai para a `callbackUrl` que você informou na criação,
exatamente como aconteceria em produção.

Não existe aprovação de ninguém no meio. A chamada só funciona com chave `ps_test_` e só
alcança cobrança da sua própria conta: com chave `ps_live_` a resposta é `403`.

> [!TIP]
>
> Chame `simulate-paid` **duas vezes** na mesma cobrança. O status não muda de novo, mas o
> webhook sai outra vez com o mesmo `X-Webhook-Id`. É o jeito mais barato de verificar se o
> seu handler é idempotente antes de precisar disso em produção.

> [!NOTE]
>
> O `event` do webhook de simulação acompanha o recurso, IGUAL à produção:
> `payment.paid` para `psa_` e `charge.paid` para `psc_`. O payload é enxuto: `event`,
> `paymentId`, `amountCents`, `status`, `paidAt`, `customer`, `metadata` e
> `sandbox: true`. (Antes o simulate de cobrança mandava `payment.paid` e o handler
> construído no sandbox nunca via o evento real; foi alinhado.)

## Conferindo o resultado

> [card] [GET /v1/sandbox/wallet](https://docs.purin.cash/api-reference/introducao.md)
>
> Saldo simulado, somado a partir das transações de teste.

> [card] [GET /v1/sandbox/transactions](https://docs.purin.cash/api-reference/introducao.md)
>
> Extrato do que você criou em sandbox, com paginação.

`GET /v1/wallet` também funciona com chave de teste. Nesse caso a resposta vem com
`"sandbox": true`, e `disputeBlocked` e `cryptoBalanceLtc` ficam sempre em zero.

## O que não roda em sandbox

> [accordion] Cartão de crédito
>
> `POST /v1/card-payments` depende do provedor de checkout e não é simulado. Teste o
> cartão direto em produção com um valor baixo.

> [accordion] Litecoin
>
> `paymentMethod: "ltc"` responde `400` com chave de teste. A cotação e o endereço vêm
> da rede real, então não há como simular.

> [accordion] Disputas
>
> Os endpoints de `/v1/disputes` respondem `404` em sandbox. Contestação nasce de uma
> transação real.

> [accordion] Saques
>
> O saque em sandbox é registrado e dispara os eventos `withdrawal.test.requested` e
> `withdrawal.test.completed`, mas nenhum valor sai.

## Indo para produção

Troque a variável de ambiente com a chave. Nada mais muda: mesma URL, mesmos campos,
mesmos nomes de evento.

> [!TIP]
>
> Vale a pena rodar o mesmo teste automatizado nos dois ambientes, com a chave vindo de
> variável. Se o teste passa com `ps_test_` e quebra com `ps_live_`, o problema está em
> configuração de conta e não no seu código.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.