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

# Sandbox

> Construa e valide a integração inteira — pagamentos, webhooks, falhas simuladas — desde o primeiro minuto da conta, sem esperar a ativação.

O sandbox é a produção com dinheiro de mentira: os mesmos endpoints, os mesmos
objetos, os mesmos webhooks. O que separa os dois mundos é só a API key usada
na chamada:

* `ch_live_...` cria e consulta dados de produção (`livemode: true`).
* `ch_test_...` cria e consulta dados de teste (`livemode: false`).

Dados de teste não movimentam dinheiro e ficam isolados dos dados de produção.
Use chaves separadas para desenvolvimento, staging e produção.

## Disponível desde o primeiro minuto

O sandbox funciona de ponta a ponta **antes mesmo da ativação da conta**.
Enquanto o cadastro está em análise, você já cria produtos, payment links,
checkout sessions e payment intents de teste, paga com os cartões e e-mails
determinísticos desta página e recebe os webhooks correspondentes — a
integração inteira pode ficar pronta em paralelo à aprovação.

A ativação só é exigida para **receber pagamento real**. Antes dela, o ambiente
live aceita criar recursos normalmente (clientes, links, sessões), e o
comprador consegue navegar o checkout até o fim — mas a confirmação do
pagamento é recusada com um erro estável, sem cobrar nada:

```json theme={"theme":"css-variables"}
{
  "error": {
    "code": "organization_not_activated",
    "message": "Organization is not ready to accept payments",
    "type": "invalid_request_error"
  }
}
```

Trate esse `code` como "conta ainda em ativação": ele aparece no
[confirm da checkout session](/api-reference/checkout-sessions/confirm) e no
[confirm do payment intent](/api-reference/payment-intents/confirm), sempre com
status `422`, e desaparece quando a ativação é aprovada.

## Criar uma chave de teste

No dashboard, abra **Developers → Chaves de API**, clique em **Nova chave** e
selecione o ambiente `test`. O token gerado começa com `ch_test_` e já
funciona com a conta recém-criada.

```bash theme={"theme":"css-variables"}
curl https://api.chargefy.io/v1/customers \
  -H "Authorization: Bearer {{API_KEY}}"
```

<Tip>
  No dashboard, o menu **Minha conta** alterna entre os ambientes live e sandbox
  a qualquer momento. Contas que ainda não ativaram começam no sandbox por
  padrão — mas a troca é sempre livre.
</Tip>

## Simular cartões

Em checkouts hospedados, no [Chargefy.js](/api/chargefy-js), na página de pagamento de fatura e nos formulários de atualização de cartão, use estes números em test mode. Use qualquer CVC de três dígitos e uma validade futura. Cartão desconhecido em test mode aprova por padrão.

### Sucesso e status

| Cartão             | Resultado/status   | `payment_error.category` | `payment_error.code` | Mensagem esperada |
| ------------------ | ------------------ | ------------------------ | -------------------- | ----------------- |
| `4242424242424242` | `succeeded`        | `null`                   | `null`               | `null`            |
| `4000000000003220` | `requires_capture` | `null`                   | `null`               | `null`            |
| `4000009000000425` | `processing`       | `null`                   | `null`               | `null`            |
| `4000009000000433` | `pending`          | `null`                   | `null`               | `null`            |

Na charge aprovada, `payment_error` é `null`. Nos casos `processing` e
`pending`, ainda não há desfecho — não trate a ausência de erro como
aprovação; aguarde o webhook.

### Cartões salvos e reutilização

Os cartões abaixo aprovam a primeira cobrança e podem ser salvos normalmente.
O resultado especial aparece somente quando o mesmo cartão é cobrado de novo
como cartão salvo — por exemplo, em uma oferta posterior de um funil.

| Cartão             | Primeira cobrança | Cobrança com o cartão salvo                                                                    |
| ------------------ | ----------------- | ---------------------------------------------------------------------------------------------- |
| `4000009000000623` | `succeeded`       | `requires_payment_method`, com `payment_error.code` igual a `single_use_card`.                 |
| `4000009000000631` | `succeeded`       | `processing`; aguarde o webhook e não inicie outra tentativa enquanto o resultado for incerto. |

Use esses números para validar uma compra aprovada seguida de contingência ou
processamento assíncrono no reúso. Em live mode, eles são tratados como números
comuns e não escolhem o resultado do pagamento.

### Falhas simuladas via cartão

Uma recusa encerra a tentativa, não o intent: o Payment Intent volta a
`requires_payment_method` com o motivo em `last_payment_error`, e o mesmo
intent aceita uma nova confirmação — use estes cartões para testar o fluxo de
recusa seguida de retentativa.

O sandbox também oferece cartões para erros que, em produção, podem nascer em
outras etapas — como captura, tokenização ou reembolso. Nesses casos, o cartão
serve para testar o contrato público, a mensagem e a saída segura da interface;
ele não pretende reproduzir a etapa operacional que originou o erro real.

O código Chargefy estável fica em `payment_error.code`, com a orientação em
`payment_error.advice_code`; `payment_error.network_decline_code` só aparece
quando o cenário de teste fornece evidência bruta confiável de rede.

| Cartão             | Resultado/status          | `payment_error.category` | `payment_error.code`                | Mensagem esperada                                              |
| ------------------ | ------------------------- | ------------------------ | ----------------------------------- | -------------------------------------------------------------- |
| `4000000000009995` | `requires_payment_method` | `issuer_declined`        | `insufficient_funds`                | The card has insufficient funds to complete the purchase.      |
| `4000009000000011` | `requires_payment_method` | `issuer_declined`        | `do_not_honor`                      | The issuer declined the transaction without a specific reason. |
| `4000000000000002` | `requires_payment_method` | `issuer_declined`        | `generic_decline`                   | The card was declined.                                         |
| `4000009000000029` | `requires_payment_method` | `issuer_declined`        | `call_issuer`                       | The card was declined. The cardholder must contact the issuer. |
| `4000009000000037` | `requires_payment_method` | `issuer_declined`        | `card_velocity_exceeded`            | The card exceeded its balance, credit, or transaction limit.   |
| `4000009000000045` | `requires_payment_method` | `issuer_declined`        | `invalid_amount`                    | The transaction amount is not allowed for this card.           |
| `4000009000000052` | `requires_payment_method` | `issuer_declined`        | `invalid_account`                   | The account linked to the card is invalid or does not exist.   |
| `4000009000000060` | `requires_payment_method` | `issuer_declined`        | `transaction_not_permitted`         | This type of transaction is not permitted for the cardholder.  |
| `4000009000000078` | `requires_payment_method` | `issuer_declined`        | `service_not_allowed`               | This transaction is not permitted for the card.                |
| `4000009000000086` | `requires_payment_method` | `issuer_declined`        | `card_not_supported`                | The card does not support this type of purchase.               |
| `4000009000000094` | `requires_payment_method` | `issuer_declined`        | `currency_not_supported`            | The card does not support the transaction currency.            |
| `4000009000000102` | `requires_payment_method` | `issuer_declined`        | `card_not_activated`                | The card has not been activated.                               |
| `4000009000000110` | `requires_payment_method` | `issuer_declined`        | `authentication_required`           | The transaction requires cardholder authentication.            |
| `4000009000000441` | `requires_payment_method` | `processing_error`       | `authentication_not_available`      | Cardholder authentication is not available for this payment.   |
| `4000009000000458` | `requires_payment_method` | `invalid`                | `new_account_information_available` | Updated card or account information is required.               |
| `4000009000000128` | `requires_payment_method` | `issuer_declined`        | `reenter_transaction`               | The issuer could not process the transaction. Try again.       |
| `4000009000000136` | `requires_payment_method` | `issuer_declined`        | `approve_with_id`                   | The payment could not be authorized.                           |
| `4000009000000144` | `requires_payment_method` | `issuer_declined`        | `not_permitted`                     | The requested operation is not supported by the card.          |
| `4000000000000069` | `requires_payment_method` | `invalid`                | `expired_card`                      | The card has expired.                                          |
| `4000000000000127` | `requires_payment_method` | `invalid`                | `incorrect_cvc`                     | The card security code (CVC) is incorrect.                     |
| `4000009000000151` | `requires_payment_method` | `invalid`                | `incorrect_number`                  | The card number is incorrect.                                  |
| `4000009000000169` | `requires_payment_method` | `invalid`                | `invalid_number`                    | The card number is invalid or the issuer does not exist.       |
| `4000009000000177` | `requires_payment_method` | `invalid`                | `incorrect_pin`                     | The card PIN is incorrect.                                     |
| `4000009000000185` | `requires_payment_method` | `invalid`                | `invalid_pin`                       | The card PIN is invalid.                                       |
| `4000009000000193` | `requires_payment_method` | `invalid`                | `pin_try_exceeded`                  | The allowable number of PIN tries was exceeded.                |
| `4000009000000201` | `requires_payment_method` | `invalid`                | `invalid_transaction`               | The transaction is invalid.                                    |
| `4000009000000219` | `requires_payment_method` | `invalid`                | `no_payment_method`                 | No payment method available to charge.                         |
| `4000009000000227` | `requires_payment_method` | `invalid`                | `card_unusable`                     | The saved card could not be used.                              |
| `4000009000000235` | `requires_payment_method` | `invalid`                | `payment_method_mismatch`           | The payment method does not belong to this customer.           |
| `4000009000000466` | `requires_payment_method` | `invalid`                | `invalid_cvc`                       | The card security code has an invalid format.                  |
| `4000009000000474` | `requires_payment_method` | `invalid`                | `invalid_expiry_month`              | The card expiration month has an invalid format.               |
| `4000009000000482` | `requires_payment_method` | `invalid`                | `invalid_expiry_year`               | The card expiration year has an invalid format.                |
| `4000009000000490` | `requires_payment_method` | `invalid`                | `invalid_name`                      | The cardholder name is invalid.                                |
| `4000009000000508` | `requires_payment_method` | `invalid`                | `invalid_request`                   | The payment request contains invalid data.                     |
| `4000009000000516` | `requires_payment_method` | `invalid`                | `invalid_token`                     | The card token is invalid or expired.                          |
| `4000009000000243` | `requires_payment_method` | `blocked`                | `lost_card`                         | The card was reported lost.                                    |
| `4000009000000250` | `requires_payment_method` | `blocked`                | `stolen_card`                       | The card was reported stolen.                                  |
| `4000009000000268` | `requires_payment_method` | `blocked`                | `pickup_card`                       | The card cannot be used (retain card).                         |
| `4000009000000276` | `requires_payment_method` | `blocked`                | `restricted_card`                   | The card is restricted.                                        |
| `4000009000000284` | `requires_payment_method` | `blocked`                | `fraudulent`                        | The transaction was flagged as suspected fraud.                |
| `4000009000000292` | `requires_payment_method` | `blocked`                | `security_violation`                | The transaction was declined for a security violation.         |
| `4000009000000300` | `requires_payment_method` | `blocked`                | `stop_payment_order`                | A stop payment order applies to this card.                     |
| `4000009000000318` | `requires_payment_method` | `blocked`                | `revocation_of_authorization`       | Authorization for this card has been revoked.                  |
| `4000009000000326` | `requires_payment_method` | `blocked`                | `revocation_of_all_authorizations`  | All authorizations for this card have been revoked.            |
| `4000009000000334` | `requires_payment_method` | `blocked`                | `transaction_not_allowed`           | The transaction is not allowed.                                |
| `4000009000000524` | `requires_payment_method` | `blocked`                | `single_use_card`                   | This card cannot be reused for this payment.                   |
| `4000009000000342` | `requires_payment_method` | `processing_error`       | `issuer_unavailable`                | The card issuer could not be reached. Try again.               |
| `4000009000000359` | `requires_payment_method` | `processing_error`       | `routing_error`                     | The transaction could not be routed to the issuer.             |
| `4000009000000367` | `requires_payment_method` | `processing_error`       | `duplicate_transaction`             | A duplicate transaction was detected.                          |
| `4000009000000375` | `requires_payment_method` | `processing_error`       | `try_again_later`                   | The payment could not be processed. Try again later.           |
| `4000009000000383` | `requires_payment_method` | `processing_error`       | `connection_error`                  | Could not reach the payment provider. Please try again.        |
| `4000009000000391` | `requires_payment_method` | `processing_error`       | `customer_unavailable`              | Customer could not be identified for the charge.               |
| `4000000000000119` | `requires_payment_method` | `processing_error`       | `processing_error`                  | An error occurred while processing the payment. Try again.     |
| `4000009000000532` | `requires_payment_method` | `processing_error`       | `merchant_not_approved`             | The merchant account is not available for this payment.        |
| `4000009000000540` | `requires_payment_method` | `processing_error`       | `authorization_expired`             | The authorization expired before capture.                      |
| `4000009000000557` | `requires_payment_method` | `processing_error`       | `capture_method_not_supported`      | The selected capture method is not supported.                  |
| `4000009000000565` | `requires_payment_method` | `processing_error`       | `charge_already_captured`           | The payment was already captured.                              |
| `4000009000000573` | `requires_payment_method` | `processing_error`       | `charge_already_refunded`           | The payment was already refunded.                              |
| `4000009000000581` | `requires_payment_method` | `processing_error`       | `partial_refund_not_supported`      | This payment does not support partial refunds.                 |
| `4000009000000599` | `requires_payment_method` | `processing_error`       | `payment_intent_unexpected_state`   | The operation is not allowed in the payment's current state.   |
| `4000009000000607` | `requires_payment_method` | `processing_error`       | `refund_period_expired`             | The refund window for this payment has expired.                |
| `4000009000000615` | `requires_payment_method` | `processing_error`       | `refund_state_mismatch`             | The refund state could not be reconciled.                      |
| `4000009000000409` | `requires_payment_method` | `issuer_declined`        | `testmode_decline`                  | A test card triggered a decline.                               |
| `4000009000000417` | `requires_payment_method` | `issuer_declined`        | `payment_failed`                    | Payment failed.                                                |

## Simular PIX e boleto

Em test mode, o e-mail do cliente determina o resultado de PIX e boleto. Use o
mesmo valor em `customer_email` no Checkout ou no `customer` associado ao
`payment_intent`.

| E-mail                            | Estado inicial            | Transição automática                                         |
| --------------------------------- | ------------------------- | ------------------------------------------------------------ |
| `succeed_immediately@meusite.com` | `succeeded`               | Nenhuma; o pagamento já nasce concluído.                     |
| `succeed_delayed@meusite.com`     | `pending`                 | Muda para `succeeded` após cerca de 3 minutos.               |
| `expire_immediately@meusite.com`  | `requires_payment_method` | Nenhuma; o código já nasce vencido e o intent aceita outro.  |
| `expire_delayed@meusite.com`      | `pending`                 | Muda para `requires_payment_method` após cerca de 3 minutos. |
| `pending@meusite.com`             | `pending`                 | Nenhuma transição automática de teste.                       |

O local-part precisa ser exatamente um dos valores acima; o domínio pode ser
qualquer domínio válido. Em live mode esses endereços são tratados como e-mails
comuns e não alteram o pagamento.

<Note>
  Boleto continua exigindo CPF/CNPJ e endereço válidos. Use esses campos para
  testar validação cadastral; use o e-mail para escolher o resultado financeiro.
</Note>

Nos cenários delayed, a confirmação retorna o código PIX ou o boleto com o
`payment_intent` em `pending`. A transição posterior passa pelo mesmo
processamento financeiro e emite os mesmos webhooks de um pagamento real.

### Controles no checkout hospedado

O checkout hospedado exibe uma barra amarela no topo quando `livemode` é
`false`. Depois que um PIX ou boleto entra em `pending`, a própria barra mostra
dois controles:

* **Simular pagamento** entrega o evento de sucesso e leva o checkout a
  `payment_status: "paid"`.
* **Simular expiração** entrega o evento de expiração do código — o intent
  volta a `requires_payment_method` — e mantém o checkout
  `unpaid`.

Esses controles são uma conveniência visual para testes manuais. Para testes
automatizados e integrações via API, use os e-mails determinísticos da tabela
acima. Os dois caminhos usam o mesmo processamento e produzem os mesmos
webhooks.

## Webhooks em test mode

Eventos criados com `ch_test_...` carregam `livemode: false` e são entregues
apenas para endpoints de webhook criados no ambiente de teste — endpoints e
secrets são separados por ambiente.

Crie pelo menos um endpoint em `test` antes de validar a integração: os
pagamentos simulados desta página emitem exatamente os mesmos eventos dos
pagamentos reais.

## Ativação de organizações no sandbox

<Warning>
  Este recurso só está disponível para **Chargefy for Platforms**.
</Warning>

O cadastro de organizações filhas roda ponta a ponta com `ch_test_...`, com
desfecho determinístico escolhido pelo CPF/CNPJ da organização: aprovado,
reprovado com correção, reprovado sem autoatendimento ou em análise. A tabela
está em [Ativação por API](/platforms/activate-by-api#modo-de-teste) e vale para
os dois caminhos de cadastro, o hospedado e o por API.

## Contas para saques no sandbox

Há dois caminhos, com comportamentos diferentes:

* **Dentro da ativação** (hospedada ou por API): a conta para saques é exigida
  e simulada normalmente com `ch_test_...`. O objeto `payout_account` volta
  preenchido na organização — ele prova o contrato e o fluxo, mas nenhuma
  conta bancária real é validada e nenhum repasse acontece.
* **Recurso independente** (`/v1/payout-accounts`): criar, listar e desconectar
  contas fora da ativação ainda não é simulado. Requisições com `ch_test_...`
  retornam `409` com `code: "sandbox_unsupported"`; use esse recurso apenas em
  produção.

## Ir para produção

Sandbox e produção usam o mesmo código — só a chave muda. Dados de teste não
migram: recrie produto, preço e link com a chave `ch_live_...` quando a conta
estiver ativa. O passo a passo completo, incluindo webhooks e checklist final,
está em [Testar no sandbox](/test-payments-in-sandbox) e no
[Checklist de go-live](/go-live-checklist).
