Testing & Sandbox Guide¶
Learn how to test your Nivatio integration thoroughly before going live.
Sandbox Environment¶
Nivatio provides a complete sandbox environment that mimics production behavior without processing real payments.
| Feature | Sandbox | Production |
|---|---|---|
| Base URL | https://sandbox.nivat.io |
https://api.nivat.io |
| API Key Prefix | nv_sk_test_ |
nv_sk_live_ |
| Real Payments | ❌ Simulated only | ✅ Real transactions |
| NUSD Token | Test mintable | Real value |
| Webhooks | ✅ Enabled | ✅ Enabled |
| Required Confirmations | 1 | 2 |
Getting Started with Sandbox¶
1. Get Sandbox API Key¶
- Log in to Dashboard (sandbox version)
- Create a project
- Generate an API key with
test_prefix - Copy the key immediately (shown only once!)
2. Configure Your App¶
const client = new NivatioClient({
apiKey: 'nv_sk_test_abc123...', // Sandbox key
environment: 'sandbox'
});
3. Test Wallet Setup¶
Use the default Anvil test wallet:
Address: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
Test Only
This wallet is public knowledge. Never use these keys in production!
Minting Test NUSD¶
Via Dashboard¶
- Go to Sandbox Dashboard
- Navigate to Test Tokens → NUSD Faucet
- Enter amount (e.g., 1000000 = 1,000 NUSD)
- Click Mint Tokens
Via Contract (Advanced)¶
import { writeContract } from 'wagmi';
import { NUSDAbi } from './abis/nusd.abi';
// Mint 1000 NUSD (6 decimals = 1000000)
await writeContract({
address: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
abi: NUSDAbi,
functionName: 'faucet',
args: ['0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', 1000000n]
});
Simulating Payments¶
Using Internal API (Sandbox Only)¶
curl -X POST https://sandbox.nivat.io/v1/sandbox/simulate-pay \
-H "x-nivatio-internal-key: YOUR_INTERNAL_KEY" \
-H "Content-Type: application/json" \
-d '{
"orderId": "order_abc123",
"outcome": "success"
}'
Parameters:
| Parameter | Type | Description |
|---|---|---|
orderId |
string | The order to simulate payment for |
outcome |
string | success, fail, or timeout |
Test Scenarios¶
// Test successful payment
await simulatePayment(order.id, 'success');
// Wait for webhook...
// Test failed payment
await simulatePayment(order.id, 'fail');
// Handle payment.failed webhook...
// Test timeout (payment never completes)
await simulatePayment(order.id, 'timeout');
// Order will eventually expire...
Automated Testing¶
Jest/JavaScript Example¶
describe('Nivatio Payment Flow', () => {
let client;
let testOrder;
beforeAll(() => {
client = new NivatioClient({
apiKey: process.env.SANDOX_API_KEY,
environment: 'sandbox'
});
});
test('Create order', async () => {
testOrder = await client.orders.create({
amount: 100000,
currency: 'NUSD',
description: 'Test Order'
});
expect(testOrder.status).toBe('PENDING');
expect(testOrder.checkoutUrl).toContain('checkout.nivat.io');
});
test('Simulate successful payment', async () => {
// Simulate payment
await fetch('https://sandbox.nivat.io/v1/sandbox/simulate-pay', {
method: 'POST',
headers: {
'x-nivatio-internal-key': process.env.INTERNAL_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
orderId: testOrder.id,
outcome: 'success'
})
});
// Wait for confirmation
await new Promise(resolve => setTimeout(resolve, 5000));
// Verify status
const order = await client.orders.retrieve(testOrder.id);
expect(order.status).toBe('PAID');
});
});
Python/Pytest Example¶
import pytest
from nivatio import NivatioClient
@pytest.fixture
def client():
return NivatioClient(
api_key=os.getenv('SANDOX_API_KEY'),
environment='sandbox'
)
def test_create_order(client):
order = client.orders.create(
amount=100000,
currency='NUSD',
description='Test Order'
)
assert order.status == 'PENDING'
assert 'checkout.nivat.io' in order.checkout_url
def test_simulate_payment(client):
# Create order
order = client.orders.create(
amount=100000,
currency='NUSD'
)
# Simulate payment
requests.post(
'https://sandbox.nivat.io/v1/sandbox/simulate-pay',
headers={
'x-nivatio-internal-key': os.getenv('INTERNAL_KEY'),
'Content-Type': 'application/json'
},
json={
'orderId': order.id,
'outcome': 'success'
}
)
# Wait and verify
import time
time.sleep(5)
updated = client.orders.retrieve(order.id)
assert updated.status == 'PAID'
Testing Checklist¶
Before going live, test these scenarios:
Order Creation¶
- Create order with valid parameters
- Handle invalid amount (should fail)
- Handle invalid currency (should fail)
- Create order with metadata
- Verify
checkoutUrlis returned
Payment Flow¶
- Simulate successful payment
- Receive
payment.succeededwebhook - Verify order status becomes
PAID - Simulate failed payment
- Receive
payment.failedwebhook - Handle payment timeout (expired)
Webhooks¶
- Webhook endpoint receives events
- Idempotency is working (no duplicates)
- Endpoint responds within 5 seconds
- SSL certificate is valid (production)
Error Handling¶
- Handle 401 (invalid API key)
- Handle 429 (rate limiting with backoff)
- Handle 500 (retry with backoff)
- Network timeouts are handled gracefully
Load Testing (Optional)¶
Test your webhook endpoint under load:
# Use Apache Bench to send 100 concurrent requests
ab -n 100 -c 10 -T "application/json" \
-p webhook-payload.json \
-H "Content-Type: application/json" \
http://yourapp.com/webhook
Going Live Checklist¶
When you're ready for production:
- Created production API key (
nv_sk_live_) - Updated API key in your app
- Changed
environmentto'production' - Configured production webhook URL (HTTPS)
- Tested with small real payment first
- Set up monitoring & alerting
- Documented your integration internally
Next Steps¶
- Payment Processing - Complete payment guide
- Webhook Integration - Set up notifications
- Error Handling - Handle errors gracefully