Testing

AutopayOS provides a complete sandbox environment for testing your integration. Use test API keys, demo endpoints, and simulated payment flows without affecting production data.

Sandbox environment

EnvironmentBase URLAPI Keys
Productionhttps://api.autopayos.comak_live_...
Sandboxhttps://sandbox-api.autopayos.comak_test_...
TypeScript
// Sandbox configuration
const client = new AutopayosClient({
  baseUrl: 'https://sandbox-api.autopayos.com',
  apiKey: 'ak_test_your_test_key',
});

Test API keys

Get test API keys from the Dashboard:

  1. Go to Dashboard → Settings → API Keys
  2. Toggle to Test Mode
  3. Create a new test key

Test keys are prefixed with ak_test_ and only work with the sandbox API.

Test DIDs

Use these pre-configured test DIDs for development:

DIDRoleDescription
did:key:z6MkTestAgent001AgentTest shopping agent
did:key:z6MkTestAgent002AgentSecondary test agent
did:key:z6MkTestUser001PrincipalTest user/owner
did:key:z6MkTestUser002PrincipalSecondary test user
did:key:z6MkTestMerchantMerchantTest merchant
TypeScript
const permission = await client.requestPermission({
  agentDid: 'did:key:z6MkTestAgent001',
  principalDid: 'did:key:z6MkTestUser001',
  amount: 50.00,
  currency: 'USD',
});

Demo endpoints

Demo cart

Generate a test cart VC:

TypeScript
const cart = await client.demoCart({
  payerDid: 'did:key:z6MkTestUser001',
  domain: 'test-merchant.autopayos.com',
  amount: 50.00,
  currency: 'USD',
  items: [
    { name: 'Test Product', price: 50.00, quantity: 1 }
  ],
});

console.log('Demo cart VC:', cart.cartVc);

Or via API:

Bash
curl https://sandbox-api.autopayos.com/ap2/demo/cart \
  -H "Authorization: Bearer ak_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "payerDid": "did:key:z6MkTestUser001",
    "domain": "test-merchant.autopayos.com",
    "amount": 50.00,
    "currency": "USD"
  }'

Demo HP proof

Generate a test Human Presence proof:

TypeScript
const hp = await client.demoHpProof({
  agentDid: 'did:key:z6MkTestAgent001',
  freshnessSeconds: 300,
});

// Use in cart verification
const verification = await client.verifyCart({
  intentVc: permission.intentVc,
  cartVc: cart.cartVc,
  hpProof: hp.hpProof,
});

Demo payment

Simulate a complete payment flow:

Bash
curl https://sandbox-api.autopayos.com/ap2/demo/payment \
  -H "Authorization: Bearer ak_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "agentDid": "did:key:z6MkTestAgent001",
    "principalDid": "did:key:z6MkTestUser001",
    "amount": 50.00,
    "currency": "USD",
    "merchantDomain": "test-merchant.autopayos.com"
  }'

Test scenarios

Successful payment

TypeScript
// This will succeed
const permission = await client.requestPermission({
  agentDid: 'did:key:z6MkTestAgent001',
  principalDid: 'did:key:z6MkTestUser001',
  amount: 50.00,
  currency: 'USD',
  merchantDomain: 'amazon.com',
});

expect(permission.allowed).toBe(true);

Policy denial - Amount

TypeScript
// This will be denied (amount over test cap of $100)
const permission = await client.requestPermission({
  agentDid: 'did:key:z6MkTestAgent001',
  principalDid: 'did:key:z6MkTestUser001',
  amount: 500.00,
  currency: 'USD',
});

expect(permission.allowed).toBe(false);
expect(permission.reasonCodes).toContain('AMOUNT_OVER_CAP');

Policy denial - Merchant

TypeScript
// This will be denied (blocked merchant)
const permission = await client.requestPermission({
  agentDid: 'did:key:z6MkTestAgent001',
  principalDid: 'did:key:z6MkTestUser001',
  amount: 50.00,
  currency: 'USD',
  merchantDomain: 'blocked-merchant.com',
});

expect(permission.allowed).toBe(false);
expect(permission.reasonCodes).toContain('MERCHANT_DENIED');

HP required

TypeScript
// Amounts over $100 in sandbox trigger HP
const permission = await client.requestPermission({
  agentDid: 'did:key:z6MkTestAgent001',
  principalDid: 'did:key:z6MkTestUser001',
  amount: 150.00,
  currency: 'USD',
});

expect(permission.allowed).toBe(true);
expect(permission.hpRequired).toBe(true);

Velocity limit

TypeScript
// Make 11 requests to trigger velocity limit
for (let i = 0; i < 11; i++) {
  await client.requestPermission({
    agentDid: 'did:key:z6MkTestAgent001',
    amount: 10.00,
    // ...
  });
}

// 11th request will be denied
const permission = await client.requestPermission({
  agentDid: 'did:key:z6MkTestAgent001',
  amount: 10.00,
  // ...
});

expect(permission.allowed).toBe(false);
expect(permission.reasonCodes).toContain('VELOCITY_EXCEEDED');

Test Stripe integration

Sandbox mode uses Stripe test mode automatically:

Test CardBehavior
4242424242424242Succeeds
4000000000000002Declined
4000002500003155Requires 3DS
4000000000009995Insufficient funds
TypeScript
// In sandbox, Stripe test mode is used automatically
const payment = await client.executePayment({
  approvalToken: verification.approvalToken,
});

// Payment intent is in test mode
console.log(payment.railResponse.paymentIntentId);
// pi_test_...

Webhook testing

Local webhook forwarding

Use the CLI to forward webhooks to your local server:

Bash
# Install CLI
npm install -g @autopayos/cli

# Login
autopayos login

# Forward webhooks
autopayos webhooks listen --forward-to localhost:3000/webhooks

Trigger test events

Bash
# Trigger specific event
autopayos webhooks trigger payment.authorized

# Trigger with custom data
autopayos webhooks trigger intent.denied \
  --data '{"reasonCodes": ["AMOUNT_OVER_CAP"]}'

Webhook logs

View webhook delivery logs:

Bash
curl https://sandbox-api.autopayos.com/ap2/admin/webhooks/logs \
  -H "Authorization: Bearer ak_test_..."

Test policies

Default test policy

Sandbox comes with a default test policy:

JSON
{
  "spend": {
    "amount_cap": 100.00,
    "currency": "USD",
    "categories": ["groceries", "electronics", "household"]
  },
  "merchant": {
    "deny_list": ["blocked-merchant.com", "casino.com"]
  },
  "context": {
    "presence": "optional",
    "presence_threshold": 100.00
  },
  "risk": {
    "velocity_limit": {
      "max_transactions": 10,
      "time_window": "1h"
    }
  }
}

Custom test policies

Create custom policies for testing:

TypeScript
const testPolicy = await client.createPolicy({
  name: 'Test Policy - High Limits',
  rules: {
    spend: {
      amount_cap: 1000.00,
      currency: 'USD',
    },
    // ... custom rules
  },
});

// Use for testing
await client.setDefaultPolicy(testPolicy.id);

Reset test data

Clear sandbox data for clean testing:

Bash
# Reset all test data for your account
curl -X POST https://sandbox-api.autopayos.com/ap2/admin/reset-test-data \
  -H "Authorization: Bearer ak_test_..."

This clears:

  • Test intents
  • Test carts
  • Test payments
  • Test evidence
  • Velocity counters

Note: This only works in sandbox mode and cannot be undone.

Integration tests

Example Jest test suite:

TypeScript
import { AutopayosClient } from '@autopayos/sdk';

describe('AutopayOS Integration', () => {
  let client: AutopayosClient;

  beforeAll(() => {
    client = new AutopayosClient({
      baseUrl: 'https://sandbox-api.autopayos.com',
      apiKey: process.env.AUTOPAYOS_TEST_KEY!,
    });
  });

  describe('Intent creation', () => {
    it('should approve valid intent', async () => {
      const permission = await client.requestPermission({
        agentDid: 'did:key:z6MkTestAgent001',
        principalDid: 'did:key:z6MkTestUser001',
        amount: 50.00,
        currency: 'USD',
      });

      expect(permission.allowed).toBe(true);
      expect(permission.intentVc).toBeDefined();
    });

    it('should deny over-limit intent', async () => {
      const permission = await client.requestPermission({
        agentDid: 'did:key:z6MkTestAgent001',
        principalDid: 'did:key:z6MkTestUser001',
        amount: 500.00,
        currency: 'USD',
      });

      expect(permission.allowed).toBe(false);
      expect(permission.reasonCodes).toContain('AMOUNT_OVER_CAP');
    });
  });

  describe('Cart verification', () => {
    it('should verify valid cart', async () => {
      const permission = await client.requestPermission({
        agentDid: 'did:key:z6MkTestAgent001',
        principalDid: 'did:key:z6MkTestUser001',
        amount: 50.00,
        currency: 'USD',
      });

      const cart = await client.demoCart({
        payerDid: 'did:key:z6MkTestUser001',
        domain: 'test-merchant.autopayos.com',
        amount: 40.00,
        currency: 'USD',
      });

      const verification = await client.verifyCart({
        intentVc: permission.intentVc,
        cartVc: cart.cartVc,
      });

      expect(verification.allowed).toBe(true);
      expect(verification.approvalToken).toBeDefined();
    });
  });

  describe('Payment execution', () => {
    it('should execute payment successfully', async () => {
      // Setup
      const permission = await client.requestPermission({
        agentDid: 'did:key:z6MkTestAgent001',
        principalDid: 'did:key:z6MkTestUser001',
        amount: 50.00,
        currency: 'USD',
      });

      const cart = await client.demoCart({
        payerDid: 'did:key:z6MkTestUser001',
        domain: 'test-merchant.autopayos.com',
        amount: 40.00,
        currency: 'USD',
      });

      const verification = await client.verifyCart({
        intentVc: permission.intentVc,
        cartVc: cart.cartVc,
      });

      // Execute
      const payment = await client.executePayment({
        approvalToken: verification.approvalToken,
      });

      expect(payment.pmVc).toBeDefined();
      expect(payment.pmVc.credentialSubject.amount).toBe(40.00);
    });
  });
});

CI/CD integration

Add to your GitHub Actions:

YAML
# .github/workflows/test.yml
name: Integration Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20'
          
      - name: Install dependencies
        run: npm ci
        
      - name: Run integration tests
        env:
          AUTOPAYOS_TEST_KEY: ${{ secrets.AUTOPAYOS_TEST_KEY }}
        run: npm run test:integration

Troubleshooting

"Invalid API key"

  • Ensure you're using ak_test_ keys with sandbox URL
  • Check key hasn't been revoked

"Agent not found"

  • Use test DIDs: did:key:z6MkTestAgent001
  • Or register your own agent in sandbox

"Rate limited"

  • Sandbox has lower rate limits
  • Wait and retry, or reset test data

Webhooks not received

  • Check webhook URL is accessible
  • Verify signature validation
  • Check webhook logs in dashboard

Next steps