Skip to content

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

  1. Log in to Dashboard (sandbox version)
  2. Create a project
  3. Generate an API key with test_ prefix
  4. 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

  1. Go to Sandbox Dashboard
  2. Navigate to Test Tokens → NUSD Faucet
  3. Enter amount (e.g., 1000000 = 1,000 NUSD)
  4. 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 checkoutUrl is returned

Payment Flow

  • Simulate successful payment
  • Receive payment.succeeded webhook
  • Verify order status becomes PAID
  • Simulate failed payment
  • Receive payment.failed webhook
  • 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 environment to 'production'
  • Configured production webhook URL (HTTPS)
  • Tested with small real payment first
  • Set up monitoring & alerting
  • Documented your integration internally

Next Steps