Skip to content

Testing & Sandbox

Overview

The 402x Sandbox environment lets you test payment integrations without real money or blockchain transactions - perfect for development, testing, and demos.


Sandbox vs Production

Environment Comparison

FeatureSandboxProduction
Real Money❌ No✅ Yes
BlockchainTestnetMainnet
Data PersistenceTemporaryPermanent
Rate LimitsRelaxedEnforced
SupportCommunityPriority

Getting Started

1. Create Sandbox Account

Visit sandbox.402x.io and sign up for free.

You'll receive:

  • Sandbox API key
  • Test wallet with 1000 USDC
  • Full dashboard access
  • API documentation

2. Configure Environment

javascript
// .env.development
X402_ENVIRONMENT=sandbox
X402_API_KEY=sk_test_abc123xyz
X402_WEBHOOK_URL=https://webhook.site/your-unique-url
javascript
// Initialize SDK
import { X402 } from '402x-sdk';

const x402 = new X402({
  apiKey: process.env.X402_API_KEY,
  environment: 'sandbox' // Use sandbox
});

Test Data

Test Wallets

Pre-configured test wallets with funds:

javascript
// Test wallet addresses
const testWallets = {
  user1: {
    address: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
    privateKey: 'test_key_user1_abc123',
    balance: 1000 // USDC
  },
  user2: {
    address: '0x891a4F2e5D9b3cDf6E7a8B9c0D1e2F3a4B5c6D7e',
    privateKey: 'test_key_user2_xyz789',
    balance: 500
  },
  merchant: {
    address: '0x123a4B5c6D7e8F9a0B1c2D3e4F5a6B7c8D9e0F1a',
    privateKey: 'test_key_merchant_def456',
    balance: 10000
  }
};

Test Payment Scenarios

Success Scenarios:

javascript
// Always succeeds
const alwaysSuccess = {
  amount: 1.00,
  wallet: testWallets.user1
};

// Delayed confirmation (useful for testing loading states)
const delayedConfirm = {
  amount: 5.00,
  delay: 3000 // 3 second delay
};

Failure Scenarios:

javascript
// Insufficient funds
const insufficientFunds = {
  amount: 9999.00,
  wallet: testWallets.user2 // Only has 500
};

// Network error simulation
const networkError = {
  amount: 0.01,
  simulateError: 'network_timeout'
};

// Fraud detection trigger
const fraudTrigger = {
  amount: 100.00,
  velocity: 'high', // Triggers fraud detection
  wallet: testWallets.user1
};

Test Cards & Accounts

For fiat on-ramp testing:

javascript
// Test credit cards (sandbox only)
const testCards = {
  success: {
    number: '4242 4242 4242 4242',
    exp: '12/30',
    cvc: '123'
  },
  decline: {
    number: '4000 0000 0000 0002',
    exp: '12/30',
    cvc: '123'
  },
  insufficient: {
    number: '4000 0000 0000 9995',
    exp: '12/30',
    cvc: '123'
  }
};

Testing Tools

Payment Simulator

Web-based tool to simulate payments:

Access: sandbox.402x.io/simulator

javascript
// Simulate payment
await simulator.createPayment({
  amount: 2.50,
  from: testWallets.user1.address,
  to: testWallets.merchant.address,
  status: 'confirmed', // or 'pending', 'failed'
  delay: 1000 // milliseconds
});

Webhook Testing

Webhook.site Integration:

bash
# Get temporary webhook URL
curl https://webhook.site/token

# Configure in dashboard
X402_WEBHOOK_URL=https://webhook.site/your-unique-url

Test Webhook Events:

javascript
// Trigger test webhook
await x402.webhooks.test({
  event: 'payment.confirmed',
  payload: {
    id: 'pay_test_123',
    amount: 5.00,
    status: 'confirmed'
  }
});

CLI Testing Tool

bash
# Install CLI
npm install -g 402x-cli

# Login to sandbox
402x login --sandbox

# Create test payment
402x payments create \
  --amount 2.50 \
  --from user1 \
  --to merchant

# List payments
402x payments list

# Simulate webhook
402x webhooks trigger payment.confirmed \
  --payment pay_test_123

Unit Testing

Jest Examples

javascript
// __tests__/payments.test.js
import { X402 } from '402x-sdk';

describe('Payment Processing', () => {
  let x402;
  
  beforeAll(() => {
    x402 = new X402({
      apiKey: process.env.X402_TEST_API_KEY,
      environment: 'sandbox'
    });
  });
  
  test('successful payment', async () => {
    const payment = await x402.payments.create({
      amount: 1.00,
      description: 'Test payment'
    });
    
    expect(payment.status).toBe('confirmed');
    expect(payment.amount).toBe(1.00);
  });
  
  test('insufficient funds', async () => {
    await expect(
      x402.payments.create({
        amount: 9999.00
      })
    ).rejects.toThrow('Insufficient funds');
  });
  
  test('webhook delivery', async () => {
    const payment = await x402.payments.create({
      amount: 2.50
    });
    
    // Wait for webhook
    const webhook = await waitForWebhook({
      event: 'payment.confirmed',
      paymentId: payment.id,
      timeout: 5000
    });
    
    expect(webhook.data.id).toBe(payment.id);
  });
});

Mocha Examples

javascript
// test/integration.test.js
const { expect } = require('chai');
const { X402 } = require('402x-sdk');

describe('Integration Tests', () => {
  it('should process paywall payment', async () => {
    const x402 = new X402({ 
      environment: 'sandbox' 
    });
    
    const paywall = await x402.paywalls.create({
      price: 0.50,
      content: 'Premium article'
    });
    
    expect(paywall).to.have.property('id');
    expect(paywall.price).to.equal(0.50);
  });
});

Integration Testing

End-to-End Testing

javascript
// e2e/payment-flow.test.js
import { test, expect } from '@playwright/test';

test('complete payment flow', async ({ page }) => {
  // Navigate to product page
  await page.goto('http://localhost:3000/premium-article');
  
  // Click pay button
  await page.click('[data-testid="pay-button"]');
  
  // 402x payment modal appears
  await expect(page.locator('.x402-modal')).toBeVisible();
  
  // Confirm payment (sandbox auto-confirms)
  await page.click('[data-testid="confirm-payment"]');
  
  // Wait for content unlock
  await expect(page.locator('.premium-content')).toBeVisible();
  
  // Verify payment in dashboard
  const payments = await fetch('https://sandbox.402x.io/api/payments', {
    headers: { 'Authorization': `Bearer ${process.env.X402_API_KEY}` }
  });
  
  const paymentsList = await payments.json();
  expect(paymentsList.data.length).toBeGreaterThan(0);
});

API Testing with Postman

Import Collection:

json
{
  "info": {
    "name": "402x Sandbox API",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/"
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://sandbox.402x.io/api"
    },
    {
      "key": "api_key",
      "value": "sk_test_your_key_here"
    }
  ],
  "item": [
    {
      "name": "Create Payment",
      "request": {
        "method": "POST",
        "url": "{{base_url}}/payments",
        "header": [
          {
            "key": "Authorization",
            "value": "Bearer {{api_key}}"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\"amount\": 1.00, \"description\": \"Test\"}"
        }
      }
    }
  ]
}

Mock Data Generation

Generate Test Payments

javascript
// scripts/generate-test-data.js
const { X402 } = require('402x-sdk');

async function generateTestData() {
  const x402 = new X402({ environment: 'sandbox' });
  
  // Generate 100 test payments
  for (let i = 0; i < 100; i++) {
    await x402.payments.create({
      amount: Math.random() * 10,
      description: `Test payment ${i}`,
      metadata: {
        test: true,
        timestamp: Date.now()
      }
    });
  }
  
  console.log('Generated 100 test payments');
}

generateTestData();

Bulk Test Operations

javascript
// Bulk create products
const products = await Promise.all(
  Array.from({ length: 50 }, (_, i) => 
    x402.products.create({
      name: `Test Product ${i}`,
      price: (i + 1) * 0.50,
      type: 'digital'
    })
  )
);

Performance Testing

Load Testing with k6

javascript
// load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  vus: 100, // 100 virtual users
  duration: '5m',
  thresholds: {
    http_req_duration: ['p(95)<500'], // 95% under 500ms
  },
};

export default function() {
  const payload = JSON.stringify({
    amount: 1.00,
    description: 'Load test payment'
  });
  
  const params = {
    headers: {
      'Authorization': `Bearer ${__ENV.X402_API_KEY}`,
      'Content-Type': 'application/json',
    },
  };
  
  const res = http.post(
    'https://sandbox.402x.io/api/payments',
    payload,
    params
  );
  
  check(res, {
    'status is 200': (r) => r.status === 200,
    'payment confirmed': (r) => JSON.parse(r.body).status === 'confirmed',
  });
  
  sleep(1);
}

Run Load Test:

bash
k6 run load-test.js

Debugging

Debug Mode

javascript
// Enable debug logging
const x402 = new X402({
  apiKey: process.env.X402_API_KEY,
  environment: 'sandbox',
  debug: true // Verbose logging
});

// Logs will show:
// [402x] Request: POST /api/payments
// [402x] Body: {"amount": 1.00}
// [402x] Response: 200 {"id": "pay_123", "status": "confirmed"}

Request Inspection

javascript
// Capture all requests
x402.on('request', (req) => {
  console.log('Request:', req.method, req.url);
  console.log('Headers:', req.headers);
  console.log('Body:', req.body);
});

x402.on('response', (res) => {
  console.log('Response:', res.status);
  console.log('Body:', res.body);
});

Error Simulation

javascript
// Simulate specific errors
await x402.test.simulateError({
  type: 'network_timeout',
  endpoint: '/api/payments',
  probability: 0.5 // 50% chance of error
});

// Simulate rate limiting
await x402.test.simulateRateLimit({
  endpoint: '/api/payments',
  duration: 60000 // 1 minute
});

Best Practices

✅ Do:

  • Use sandbox for all development and testing
  • Reset sandbox data regularly
  • Test all error scenarios
  • Validate webhook signatures
  • Test with realistic data volumes
  • Document test scenarios
  • Automate tests in CI/CD

❌ Don't:

  • Use production keys in tests
  • Commit API keys to version control
  • Skip edge case testing
  • Ignore webhook failures
  • Test only happy paths
  • Use sandbox in production

Transition to Production

Checklist

  • [ ] All tests passing
  • [ ] Error handling implemented
  • [ ] Webhooks verified
  • [ ] Security review completed
  • [ ] Documentation updated
  • [ ] Monitoring configured
  • [ ] Production keys secured
  • [ ] Rate limiting tested
  • [ ] Load testing completed
  • [ ] Rollback plan ready

Migration Steps

  1. Update Environment
javascript
// Change from sandbox to production
X402_ENVIRONMENT=production
X402_API_KEY=sk_live_your_production_key
  1. Update Endpoints
javascript
const x402 = new X402({
  environment: 'production', // Changed from 'sandbox'
  apiKey: process.env.X402_API_KEY
});
  1. Update Webhooks
bash
# Point to production webhook endpoint
X402_WEBHOOK_URL=https://api.yourapp.com/webhooks/402x
  1. Monitor Closely
  • Watch error rates
  • Monitor payment success
  • Check webhook delivery
  • Review user feedback

Troubleshooting

Common Issues

"Invalid API Key"

javascript
// Check environment
console.log('Environment:', process.env.X402_ENVIRONMENT);
console.log('API Key:', process.env.X402_API_KEY?.slice(0, 10) + '...');

// Verify key format
if (!apiKey.startsWith('sk_test_')) {
  throw new Error('Must use sandbox API key (sk_test_...)');
}

"Payment Not Confirming"

javascript
// Check payment status
const payment = await x402.payments.get(paymentId);
console.log('Status:', payment.status);
console.log('Error:', payment.error);

// Retry if needed
if (payment.status === 'failed') {
  await x402.payments.retry(paymentId);
}

"Webhook Not Received"

bash
# Test webhook endpoint
curl -X POST https://your-app.com/webhooks/402x \
  -H "Content-Type: application/json" \
  -d '{"event": "test", "data": {}}'

# Check webhook logs in dashboard

Resources

Pro Tip

Use the sandbox environment extensively before going to production. Test every edge case, error scenario, and integration point.