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

# Sandbox testing

> Test funding accounts, deposits, webhooks, and flagged edge cases in sandbox

## Overview

Sandbox is designed to help you test **real production behaviors** in a safe environment.

In particular, you can trigger a mock deposit for an NGN or crypto funding account:

* [Create a sandbox deposit](/api-reference/sandbox/create-sandbox-deposit)

## What it validates

* Your **deposit lifecycle UI/state machine**
* Your **webhook endpoint** (signature verification + idempotency + retries)
* Your handling of **edge cases** like deposits that require review

## Testing specific deposit outcomes

Use `scenario` with `POST /v1/sandbox/deposits` when you need to trigger a specific lifecycle state.

```json theme={null}
{
  "funding_account_id": "6b0e8400-e29b-41d4-a716-446655440000",
  "scenario": "COMPLETED"
}
```

Supported scenarios:

| Scenario          | Webhooks to expect                            | What to verify                                                        |
| ----------------- | --------------------------------------------- | --------------------------------------------------------------------- |
| `PROCESSING`      | `deposit.received`, `deposit.processing`      | Your app shows an in-progress state and keeps polling/listening       |
| `COMPLETED`       | `deposit.received`, `deposit.completed`       | Your app only credits the user when the final completed state arrives |
| `REQUIRES_REVIEW` | `deposit.received`, `deposit.requires_review` | Your app holds the transaction and shows a review state               |
| `FAILED`          | `deposit.received`, `deposit.failed`          | Your app shows failure messaging and does not credit the user         |

<Note>
  If you omit `scenario`, sandbox runs the default processing flow. Use the default flow when you want to test production-like behavior and natural intermediate states, and use `scenario` when you want deterministic state testing.
</Note>

<Note>
  `PROCESSING` and `COMPLETED` scenarios still use the funding account's active settlement destination. Make sure the funding account is active, has an active settlement destination, and includes any required `rate_id`, destination wallet, or destination bank details before triggering those outcomes.
</Note>

## Flagging behavior (important)

Sandbox follows the same rules engine as production. As a result, simulated deposits may require review automatically:

* **Rate expired**: If the quote/rate tied to the funding account is expired, the deposit will be flagged.
* **Re-used temporary NGN account**: If a deposit has already been created for the same temporary receive instruction, subsequent simulated deposits may be flagged.

<Note>
  If you want a clean happy path test, create a fresh funding account, then trigger the sandbox deposit immediately. For crypto funding accounts, you can either use this helper with `funding_account_id` or send testnet USDC/USDT to the returned address.
</Note>

## Sandbox Bank Accounts

When testing crypto funding accounts with `NGN_PAYOUT` settlement, use the following test bank accounts:

| Field               | Value                                         |
| ------------------- | --------------------------------------------- |
| **Bank code**       | `044`                                         |
| **Account numbers** | `0690000031`, `0690000032`, `0690000033`, ... |

Increment the last digit of the account number to generate additional test accounts. Resolve them with `POST /v1/banks/resolve` before use — just like production.

## Recommended end-to-end flow

### NGN receive instruction

1. Call `GET /v1/rates?side=BUY` to get a fresh `rate_id`
2. Create a sandbox NGN funding account with `rail: NGN_VIRTUAL_ACCOUNT`
3. Call `POST /v1/sandbox/deposits` with the returned funding account `id` as `funding_account_id`
4. Observe status progression and confirm you receive the expected webhooks (`deposit.received`, then `deposit.completed` / `deposit.failed` / `deposit.requires_review`)

### Crypto funding account

1. Call `POST /v1/banks/resolve` to verify the test bank account
2. Call `GET /v1/rates?side=SELL` to get a fresh `rate_id`
3. Call `POST /v1/funding-accounts` with `rail: CRYPTO_ADDRESS`, `asset`, `chain`, and `NGN_PAYOUT` settlement
4. Call `POST /v1/sandbox/deposits` with the returned funding account `id` as `funding_account_id`, or send test crypto to the returned `address`
5. Observe deposit webhook events (`deposit.received`, then `deposit.completed` / `deposit.failed` / `deposit.requires_review`)

## Getting Testnet USDC

To test crypto deposits in sandbox, you need testnet USDC. Use the Circle faucet to get free testnet USDC:

<Card title="Circle USDC Faucet" icon="coins" href="https://faucet.circle.com/">
  Get free testnet USDC to send to your sandbox crypto funding account addresses
</Card>

## Next Steps

<CardGroup cols={2}>
  <Card title="Webhooks Overview" icon="bell" href="/api-reference/webhooks/overview">
    Ensure your webhook endpoint is receiving deposit events
  </Card>

  <Card title="Webhook Verification" icon="shield-check" href="/api-reference/webhooks/verification">
    Verify signatures correctly and handle retries safely
  </Card>
</CardGroup>
