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
| Feature | Sandbox | Production |
|---|---|---|
| Real Money | ❌ No | ✅ Yes |
| Blockchain | Testnet | Mainnet |
| Data Persistence | Temporary | Permanent |
| Rate Limits | Relaxed | Enforced |
| Support | Community | Priority |
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-urljavascript
// 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-urlTest 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_123Unit 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.jsDebugging
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
- Update Environment
javascript
// Change from sandbox to production
X402_ENVIRONMENT=production
X402_API_KEY=sk_live_your_production_key- Update Endpoints
javascript
const x402 = new X402({
environment: 'production', // Changed from 'sandbox'
apiKey: process.env.X402_API_KEY
});- Update Webhooks
bash
# Point to production webhook endpoint
X402_WEBHOOK_URL=https://api.yourapp.com/webhooks/402x- 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 dashboardResources
Pro Tip
Use the sandbox environment extensively before going to production. Test every edge case, error scenario, and integration point.