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 TokensNUSD 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