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

# Testes no sandbox

> O sandbox roda a mesma API da produção. Um endpoint a mais, disponível só no sandbox, leva qualquer registro ao status que você quer testar.

URL base do sandbox: `https://sandbox.javalibridge.com`. As credenciais do sandbox são separadas das de produção e são entregues no onboarding.

## Como funciona

Na produção, validação, compliance, câmbio, Pix e o passar do tempo levam os seus registros de um status para o próximo. No sandbox cada registro espera: **você escolhe o próximo status** com um endpoint, [`POST /v1/sandbox/simulations`](https://developers.javalibridge.com/pt-BR/api-reference/create-sandbox-simulation).

```bash theme={null}
curl -X POST https://sandbox.javalibridge.com/v1/sandbox/simulations \
  -H "Authorization: Bearer {accessToken}" \
  -H "Content-Type: application/json" \
  -d '{
    "resourceType": "REMITTANCE",
    "resourceId": "rem_123",
    "status": "PROCESSING"
  }'
```

```json theme={null}
{
  "resourceType": "REMITTANCE",
  "resourceId": "rem_123",
  "previousStatus": "RECEIVED",
  "status": "PROCESSING",
  "simulatedAt": "2026-11-11T14:02:10Z"
}
```

| Regra | Detalhe |
| - | - |
| A sua integração não muda | Você chama os endpoints de produção exatamente como vai chamar na produção. A simulação é uma chamada à parte, que também pode ser feita pelo portal. |
| Um passo por chamada | Cada chamada avança o registro um status e envia o webhook dessa mudança. |
| Regras reais | Só são aceitas as transições que existem na produção. Uma transição inválida retorna `409` com os status aceitos em `details`. |
| Registros reais | Um remetente levado a `ACTIVE` fica `ACTIVE` e pode ser usado em withdrawals. Saldos, limites e lotes se movem a cada remessa. |
| Mesmos payloads | Requisições, respostas e webhooks têm o mesmo schema da produção. |
| Só no sandbox | O endpoint não existe na produção e lá retorna `404`. |

Erros do endpoint de simulação:

| HTTP | Quando |
| - | - |
| 400 `VALIDATION_ERROR` | `resourceType`, `status` ou `rejectedCode` desconhecido, ou `REJECTED` sem `rejectedCode`. |
| 404 `NOT_FOUND` | O registro não existe na sua conta do sandbox. |
| 409 `INVALID_STATUS_TRANSITION` | O registro não pode ir do status atual para o pedido. |

> [!NOTE]
>
> Toda simulação também está disponível no portal do sandbox: abra o registro e use **Simulate**. Ele chama o mesmo endpoint.

## O que você pode simular

| `resourceType` | `resourceId` | `status` aceito | Webhook enviado |
| - | - | - | - |
| `SENDER` | ID do remetente | `ACTIVE`, `PENDING`, `RESTRICTED`, `BLOCKED`, `INACTIVE` | `sender.status_changed` |
| `BENEFICIARY` | ID do beneficiário | `ACTIVE`, `PENDING`, `BLOCKED`, `INACTIVE` | `beneficiary.status_changed` |
| `PIX_KEY` | ID da instrução de pagamento (`paymentInstructionId`) | `APPROVED`, `REJECTED` | `beneficiary.status_changed` |
| `QUOTE` | ID da cotação | `EXPIRED` | — |
| `REMITTANCE` | ID da remessa | `PROCESSING`, `ON_HOLD`, `COMPLETED`, `REJECTED` (com `rejectedCode`), `FUNDS_HELD_BRL`, `REFUNDED_BY_USER` | `remittance.status_changed` |
| `SETTLEMENT` | ID do lote | `CLOSED`, `DUE`, `OVERDUE`, `COMPLETED` | — |
| `INVENTORY_OBLIGATION` | ID do Inventory Lot | `OVERDUE`, `PAID` | — |

## Remetentes

`POST /v1/senders` cria o remetente em `PENDING`. Ele fica `PENDING` até você simular a decisão de compliance.

| Para testar | Simule `SENDER` → |
| - | - |
| Remetente aprovado | `ACTIVE` |
| Remetente bloqueado, restrito ou desativado | `BLOCKED`, `RESTRICTED`, `INACTIVE` |
| Remetente de volta à análise | `PENDING` |

Qualquer status pode ir para qualquer outro. O nível de compliance é calculado a partir dos dados que você envia, como na produção: um remetente sem os dados do `LEVEL_1` fica `LEVEL_0` e não envia, mesmo `ACTIVE`.

## Beneficiários e chaves Pix

`POST /v1/beneficiaries` cria o beneficiário em `PENDING` e cada chave Pix em `SCREENING`. Eles são aprovados separadamente, como na produção.

| Para testar | Simule |
| - | - |
| Beneficiário aprovado | `BENEFICIARY` → `ACTIVE` |
| Chave Pix aprovada | `PIX_KEY` → `APPROVED` |
| Chave Pix reprovada | `PIX_KEY` → `REJECTED` |
| Beneficiário bloqueado ou desativado | `BENEFICIARY` → `BLOCKED`, `INACTIVE` |

Uma remessa precisa do beneficiário `ACTIVE` e da chave Pix `APPROVED`. Qualquer chave Pix é aceita no cadastro.

## Cotações

`POST /v1/fx/quotes` retorna uma cotação `AVAILABLE` com a validade padrão. Para testar uma cotação expirada sem esperar, simule `QUOTE` → `EXPIRED`.

## Withdrawals

`POST /v1/remittances/withdrawals` cria a remessa em `RECEIVED` e envia o primeiro `remittance.status_changed`. `RECEIVED` significa que a requisição foi aceita e aguarda a validação. No sandbox ela fica `RECEIVED` até você simular o próximo passo.

| De | Você pode simular |
| - | - |
| `RECEIVED` | `PROCESSING` (validação aprovada), `REJECTED` (validação reprovada) |
| `PROCESSING` | `COMPLETED`, `ON_HOLD`, `REJECTED`, `FUNDS_HELD_BRL` |
| `ON_HOLD` | `PROCESSING` (análise aprovada), `REJECTED` (análise reprovada) |
| `COMPLETED` | `REFUNDED_BY_USER` |
| `REJECTED`, `FUNDS_HELD_BRL`, `REFUNDED_BY_USER` | Nada. São finais. |

Os caminhos que você vai querer testar:

| Para testar | Simule, nesta ordem | Webhooks no total |
| - | - | - |
| Remessa concluída | `PROCESSING`, `COMPLETED` | 3 |
| Rejeitada na validação | `REJECTED` com um `rejectedCode` | 2 |
| Análise de compliance aprovada | `PROCESSING`, `ON_HOLD`, `PROCESSING`, `COMPLETED` | 5 |
| Análise de compliance reprovada | `PROCESSING`, `ON_HOLD`, `REJECTED` com `COMPLIANCE_REJECTED` | 4 |
| Valor retido em BRL | `PROCESSING`, `FUNDS_HELD_BRL` | 3 |
| Devolvida pelo beneficiário | `PROCESSING`, `COMPLETED`, `REFUNDED_BY_USER` | 4 |

Os efeitos são os mesmos da produção:

* `PROCESSING` reserva o limite de crédito, o saldo pré-fundado ou o volume do Inventory.
* `REJECTED` libera o que foi reservado. A cotação e o external ID não são liberados: use novos para tentar de novo.
* `COMPLETED` disponibiliza o comprovante em `GET /v1/remittances/{remittanceId}/receipt`. Uma remessa `CREDIT` entra no lote de liquidação aberto.
* `FUNDS_HELD_BRL` e `REFUNDED_BY_USER` não devolvem nada para as suas wallets nem para a sua linha de crédito.

> [!NOTE]
>
> Simular `PROCESSING` roda a validação real. Se o withdrawal tiver um problema real, como um remetente ainda `PENDING`, a remessa vai para `REJECTED` com o código real, e a resposta da simulação mostra isso.

## Rejeições

Uma rejeição é uma remessa que vai para `REJECTED`, com a causa em `rejectedCode` e um texto legível em `rejectedDescription`. Para testar uma, crie um withdrawal e simule `REJECTED` com o código que você quer:

```bash theme={null}
curl -X POST https://sandbox.javalibridge.com/v1/sandbox/simulations \
  -H "Authorization: Bearer {accessToken}" \
  -H "Content-Type: application/json" \
  -d '{
    "resourceType": "REMITTANCE",
    "resourceId": "rem_123",
    "status": "REJECTED",
    "rejectedCode": "CREDIT_LIMIT_EXCEEDED"
  }'
```

O webhook e `GET /v1/remittances/{remittanceId}` passam a retornar:

```json theme={null}
{
  "status": "REJECTED",
  "rejectedCode": "CREDIT_LIMIT_EXCEEDED",
  "rejectedDescription": "The credit limit is not enough."
}
```

`rejectedCode` é obrigatório quando você simula `REJECTED`. `rejectedDescription` é preenchida com o texto padrão do código, sempre em inglês: você não envia.

A partir de `RECEIVED`, estes códigos são aceitos:

| `rejectedCode` | O que representa |
| - | - |
| `QUOTE_EXPIRED` | A cotação expirou antes de o withdrawal ser validado. |
| `QUOTE_ALREADY_USED` | A cotação foi usada por outro withdrawal. |
| `QUOTE_USAGE_MISMATCH` | A cotação foi criada para outro uso. |
| `SENDER_NOT_ELIGIBLE` | O remetente não está `ACTIVE`, está em `LEVEL_0` ou não pode enviar esta remessa. |
| `BENEFICIARY_NOT_ELIGIBLE` | O beneficiário não está `ACTIVE` ou não pode receber esta remessa. |
| `RELATIONSHIP_MISMATCH` | A relação não combina com o tipo do beneficiário. |
| `PAYMENT_INSTRUCTION_INVALID` | A chave Pix não pode ser usada. |
| `PIX_KEY_NOT_FOUND` | A chave Pix não existe. |
| `FUNDING_MODE_NOT_ENABLED` | A modalidade de funding não está habilitada para a conta. |
| `CREDIT_LIMIT_EXCEEDED` | O limite de crédito não é suficiente. |
| `INSUFFICIENT_PREFUNDED_BALANCE` | O saldo em USD não é suficiente. |
| `AMOUNT_BELOW_MINIMUM`, `AMOUNT_ABOVE_LIMIT` | O valor está fora dos limites por remessa. |
| `ACCOUNT_DAILY_LIMIT_EXCEEDED` | A conta atingiu o limite diário. |
| `INVENTORY_NOT_FOUND`, `INVENTORY_SUSPENDED`, `INSUFFICIENT_INVENTORY_BALANCE` | O Inventory Lot não consegue financiar a remessa. |

A partir de `PROCESSING` ou `ON_HOLD`, o único código aceito é `COMPLIANCE_REJECTED`: o compliance recusou a remessa, e o motivo não é detalhado.

## Erros na resposta

Só erros da própria requisição voltam na resposta HTTP do withdrawal. Você os reproduz com uma requisição real, sem o endpoint de simulação.

| Erro | Como reproduzir |
| - | - |
| `VALIDATION_ERROR` (400) | Envie um payload inválido ou incompleto. |
| `DUPLICATE_EXTERNAL_ID` (409) | Repita um `externalId` com uma nova `Idempotency-Key`. |
| `IDEMPOTENCY_CONFLICT` (409) | Repita uma `Idempotency-Key` com outro payload. |
| `UNAUTHORIZED` (401) | Envie um token expirado ou inválido. |

## Liquidações

Um lote abre quando a primeira remessa `CREDIT` do dia fica `COMPLETED`. O tempo e o pagamento em USDC são simulados.

| Para testar | Simule `SETTLEMENT` → |
| - | - |
| Lote fechado | `CLOSED` |
| Pagamento vence hoje | `DUE` |
| Pagamento em atraso | `OVERDUE` |
| Lote pago, linha de crédito liberada | `COMPLETED` (a partir de `CLOSED`, `DUE` ou `OVERDUE`) |

`CLOSED`, `DUE` e `OVERDUE` seguem essa ordem. Lotes não geram webhook: consulte-os em `GET /v1/settlements`.

## Inventory Lots

`POST /v1/inventories` cria o lote com `status = ACTIVE` e `obligation.status = PENDING`.

| Para testar | Faça isto |
| - | - |
| Lote `DEPLETED` | Crie withdrawals até `available` chegar a 0. |
| Obrigação em atraso, lote `SUSPENDED` | Simule `INVENTORY_OBLIGATION` → `OVERDUE`. |
| Obrigação paga, lote de volta a `ACTIVE` ou `DEPLETED` | Simule `INVENTORY_OBLIGATION` → `PAID`. |

## Indisponível no sandbox

`RATE_LIMITED` (429), `INTERNAL_ERROR` (500) e `SERVICE_UNAVAILABLE` (503) não podem ser reproduzidos sob demanda. Siga as regras de nova tentativa em [Convenções da API](https://developers.javalibridge.com/pt-BR/api-reference/conventions.md).

## Saldos e limites

A conta do sandbox começa com saldo USD pré-fundado, uma linha de crédito e as modalidades de funding acordadas para a sua conta. Consulte-os em `GET /v1/wallets`, `GET /v1/credit-line` e `GET /v1/limits`. Nenhum dinheiro real se move.

## Antes de ir para produção

Execute cada cenário abaixo. Um cenário está concluído quando a API retornou o esperado e cada webhook mostra uma entrega `2xx` em `GET /v1/webhooks/{webhookId}/deliveries`.

| # | Cenário | Crie com | Depois simule |
| - | - | - | - |
| 1 | Token e endpoint de webhook | `POST /v1/auth/token`, `POST /v1/webhooks` | — |
| 2 | Remetente aprovado | `POST /v1/senders` | `SENDER` → `ACTIVE` |
| 3 | Remetente bloqueado | — | `SENDER` → `BLOCKED` |
| 4 | Beneficiário e chave Pix aprovados | `POST /v1/beneficiaries` | `BENEFICIARY` → `ACTIVE`, `PIX_KEY` → `APPROVED` |
| 5 | Chave Pix reprovada | `POST /v1/beneficiaries` | `PIX_KEY` → `REJECTED` |
| 6 | Remessa concluída, comprovante lido | Withdrawal | `PROCESSING`, `COMPLETED` |
| 7 | Rejeitada: cotação expirada | Withdrawal | `REJECTED` com `QUOTE_EXPIRED` |
| 8 | Rejeitada: funding (limite ou saldo) | Withdrawal | `REJECTED` com `CREDIT_LIMIT_EXCEEDED` ou `INSUFFICIENT_PREFUNDED_BALANCE` |
| 9 | Rejeitada: chave Pix inexistente | Withdrawal | `REJECTED` com `PIX_KEY_NOT_FOUND` |
| 10 | Análise de compliance aprovada | Withdrawal | `PROCESSING`, `ON_HOLD`, `PROCESSING`, `COMPLETED` |
| 11 | Análise de compliance reprovada | Withdrawal | `PROCESSING`, `ON_HOLD`, `REJECTED` com `COMPLIANCE_REJECTED` |
| 12 | Valor retido em BRL | Withdrawal | `PROCESSING`, `FUNDS_HELD_BRL` |
| 13 | Devolvida pelo beneficiário | Withdrawal | `PROCESSING`, `COMPLETED`, `REFUNDED_BY_USER` |
| 14 | External ID duplicado | Withdrawal repetido | — |
| 15 | `CREDIT`: lote fechado e pago | Withdrawal `CREDIT`, simulado até `COMPLETED` | `SETTLEMENT` → `CLOSED`, `COMPLETED` |
| 16 | `INVENTORY`: lote criado e usado | `POST /v1/inventories`, withdrawal | `PROCESSING`, `COMPLETED` |
| 17 | `INVENTORY`: lote suspenso, depois pago | Lote, depois um withdrawal | `INVENTORY_OBLIGATION` → `OVERDUE`; withdrawal → `PROCESSING`, rejeitado de verdade com `INVENTORY_SUSPENDED`; `INVENTORY_OBLIGATION` → `PAID` |

Os cenários 15 a 17 valem só para as modalidades de funding habilitadas na sua conta.

> [!TIP]
>
> **O que você faz**
>
> * Construa a integração só com os endpoints de produção. Nada nela é específico do sandbox.
> * Use o endpoint de simulação, ou **Simulate** no portal, para levar cada registro ao próximo status.
> * Confira que todos os webhooks foram entregues antes de pedir as credenciais de produção.


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