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

# Sandbox Environment

> Test your integration safely in sandbox mode

The Zentra sandbox environment allows you to test your integration without using real money or affecting production data.

## Overview

The sandbox environment is a complete replica of the live environment, allowing you to:

* Test all API endpoints
* Simulate transactions
* Test webhook events
* Verify error handling
* Load test your integration

<Info>
  Sandbox and live environments are completely separate. Data does not sync between them.
</Info>

<Note>
  Examples here focus on reviewed transfer, webhook, and optional rail flows. Identity examples are reviewed but tenant-gated; customer and wallet examples should still be treated as compatibility or draft unless your environment explicitly exposes them.
</Note>

## Getting Started

### 1. Get Sandbox API Keys

1. Go to the [Developer Console](https://api.usezentra.com/developer/signin?callbackUrl=%2Fdeveloper%2Fapi-keys)
2. Open **API Keys**
3. Generate sandbox keys (prefixed with `sk_sandbox_`)

### 2. Configure Your Client

<CodeGroup>
  ```javascript JavaScript theme={null}
  const client = new Zentra.Client({
    apiKey: 'sk_sandbox_your_key_here',
    environment: 'sandbox' // Important!
  });
  ```

  ```python Python theme={null}
  client = Client(
      api_key='sk_sandbox_your_key_here',
      environment='sandbox'
  )
  ```

  ```php PHP theme={null}
  $client = new Client([
      'api_key' => 'sk_sandbox_your_key_here',
      'environment' => 'sandbox'
  ]);
  ```
</CodeGroup>

### 3. Make API Calls

All reviewed API endpoints work the same way in sandbox:

```javascript theme={null}
// List banks
const banks = await client.transfers.getBanks();
console.log(banks[0]);
```

## Sandbox vs Live

| Feature                | Sandbox                             | Live                        |
| ---------------------- | ----------------------------------- | --------------------------- |
| **API Keys**           | `sk_sandbox_*`                      | `sk_live_*`                 |
| **Base URL**           | `https://sandbox.api.usezentra.com` | `https://api.usezentra.com` |
| **Real Money**         | No                                  | Yes                         |
| **Real Bank Accounts** | No                                  | Yes                         |
| **Rate Limits**        | 100 req/min                         | Based on plan               |
| **Webhooks**           | Yes                                 | Yes                         |
| **Test Data**          | Required                            | Not allowed                 |

## Test Data

Use these test values in sandbox:

### Test BVNs

| BVN           | Behavior                            |
| ------------- | ----------------------------------- |
| `22222222222` | Valid - Verification succeeds       |
| `11111111111` | Invalid - Verification fails        |
| `33333333333` | Pending - Stays pending for testing |

### Test NIDs

| NIN           | Behavior |
| ------------- | -------- |
| `12345678901` | Valid    |
| `00000000000` | Invalid  |

### Test Cards

| Card Number           | Brand      | Behavior           |
| --------------------- | ---------- | ------------------ |
| `5060990580000217499` | Verve      | Successful         |
| `4084080000000409`    | Visa       | Successful         |
| `5399830000000062`    | Mastercard | Successful         |
| `4000000000000002`    | Visa       | Declined           |
| `4000000000000127`    | Visa       | Insufficient funds |

**Default CVV**: `123`\
**Default Expiry**: Any future date (e.g., `12/26`)\
**Default PIN**: `1234`

### Test Bank Accounts

| Account Number | Bank   | Behavior        |
| -------------- | ------ | --------------- |
| `0123456789`   | GTBank | Valid account   |
| `9876543210`   | Zenith | Valid account   |
| `0000000000`   | Any    | Invalid account |

### Test OTP

For 2FA and verification:

| Scenario | OTP      |
| -------- | -------- |
| Success  | `123456` |
| Failure  | `000000` |

## Simulating Scenarios

### Successful Transfer

```javascript theme={null}
const transfer = await client.transfers.create({
  amountMinor: 50000,
  destinationAccountNumber: '0123456789', // Test account
  destinationBankCode: '058',
  narration: 'Test transfer'
});
// Status will be 'completed' within seconds
```

### Failed Transfer

```javascript theme={null}
const transfer = await client.transfers.create({
  amountMinor: 50000,
  destinationAccountNumber: '0000000000', // Invalid
  destinationBankCode: '058',
  narration: 'Test failed transfer'
});
// Will fail with 'invalid_account' error
```

### Insufficient Balance

```javascript theme={null}
// Create a transfer larger than your balance
const transfer = await client.transfers.create({
  amountMinor: 999999999, // Very large amount
  destinationAccountNumber: '0123456789',
  destinationBankCode: '058',
  narration: 'Test'
});
// Will fail with 'insufficient_balance' error
```

## Testing Webhooks

### Local Development

Use ngrok to expose your local server:

```bash theme={null}
# Install ngrok
npm install -g ngrok

# Start your server
node server.js

# In another terminal, expose it
ngrok http 3000
```

Use the ngrok URL in your webhook settings:

```
https://abc123.ngrok.com/webhooks/zentra
```

### Trigger Test Webhooks

Use your sandbox tenant and the developer tooling available for your environment to trigger or replay webhook events. Prefer replay-safe test tooling over undocumented direct trigger endpoints.

## Sandbox Limitations

<Warning>
  Keep these limitations in mind when testing in sandbox:
</Warning>

* **No Real Money**: Transactions don't involve real money
* **Simplified Processing**: Transfers complete instantly (no banking delays)
* **Limited Banks**: Only major banks are simulated
* **No Physical Cards**: Can't test physical card delivery
* **Rate Limits**: Lower than production (100 req/min)

## Best Practices

<AccordionGroup>
  <Accordion title="Test All Scenarios">
    Test both success and failure cases to ensure your error handling works.
  </Accordion>

  <Accordion title="Use Test Data">
    Always use test data provided above. Don't use real customer information.
  </Accordion>

  <Accordion title="Test Webhooks">
    Ensure your webhook handlers work correctly before going live.
  </Accordion>

  <Accordion title="Simulate Edge Cases">
    Test rate limiting, timeouts, and other edge cases.
  </Accordion>

  <Accordion title="Keep Separate Keys">
    Never mix sandbox and live API keys in your code.
  </Accordion>
</AccordionGroup>

## Switching to Live

When you're ready to go live:

1. **Test Everything**: Ensure all features work in sandbox
2. **Get Live Keys**: Generate production API keys
3. **Update Environment**: Change `environment` to `'live'`
4. **Update Webhooks**: Point webhooks to production server
5. **Monitor**: Watch for errors and issues

```javascript theme={null}
// Before (Sandbox)
const client = new Zentra.Client({
  apiKey: process.env.ZENTRA_SANDBOX_KEY,
  environment: 'sandbox'
});

// After (Live)
const client = new Zentra.Client({
  apiKey: process.env.ZENTRA_LIVE_KEY,
  environment: 'live'
});
```

## Monitoring Sandbox Usage

View your sandbox activity in the Dashboard:

1. Go to **Dashboard → Sandbox**
2. View API calls, transactions, and webhooks
3. Check for errors and warnings

## Resetting Sandbox Data

Need a fresh start?

1. Go to **Dashboard → Sandbox → Reset**
2. Click **Reset All Data**
3. Confirm the action

<Warning>
  This will delete sandbox test records, including any draft customer records, virtual accounts, and transactions. This cannot be undone.
</Warning>

## Getting Help

Questions about sandbox testing?

* 📚 [Test Data Reference](/resources/test-data)
* 📬 [Contact Support](/support/contact)
* 📈 [Status Page](https://status.usezentra.com)

## Next Steps

<CardGroup cols={2}>
  <Card title="Test Data" icon="flask" href="/resources/test-data">
    Complete test data reference
  </Card>

  <Card title="Going Live" icon="rocket" href="/guides/going-live">
    Production checklist
  </Card>

  <Card title="Webhooks Guide" icon="webhook" href="/guides/handling-webhooks">
    Test webhook handling
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/overview">
    API documentation
  </Card>
</CardGroup>
