Docs/Error Handling

Error Handling

Learn how to handle errors from the Web3 Pay API. All errors follow a consistent format with actionable error codes.

Error Response Format

All API errors return a JSON response with this structure:

json
{
  "success": false,
  "error": {
    "code": "INVALID_WALLET_ADDRESS",
    "message": "The provided wallet address is not valid for ethereum network",
    "details": {
      "wallet_address": "0xinvalid",
      "network": "ethereum"
    }
  }
}

HTTP Status Codes

StatusDescription
200Success - Request completed successfully
400Bad Request - Invalid parameters or request body
401Unauthorized - Invalid or missing API key
403Forbidden - Insufficient permissions
404Not Found - Resource doesn't exist
429Too Many Requests - Rate limit exceeded
500Server Error - Something went wrong on our end

Error Codes Reference

Authentication Errors (401)

MISSING_API_KEY

API key not provided in request headers

Solution: Include X-API-Key header with your API key

INVALID_API_KEY

The provided API key is invalid or revoked

Solution: Check your API key is correct and not revoked

EXPIRED_API_KEY

The API key has expired

Solution: Generate a new API key in the dashboard

Authorization Errors (403)

INSUFFICIENT_PERMISSIONS

API key lacks required permission for this endpoint

Solution: Use a key with appropriate permissions or update key permissions

CONNECT_NOT_READY

Stripe Connect account is not set up or pending verification

Solution: Complete Stripe Connect onboarding in the dashboard

ACCOUNT_SUSPENDED

Your account has been suspended

Solution: Contact support@web3pay.io for assistance

Validation Errors (400)

VALIDATION_ERROR

Request body contains invalid or missing fields

Solution: Check the error details for specific field issues

INVALID_WALLET_ADDRESS

Wallet address is invalid for the specified network

Solution: Verify the address format matches the target network

UNSUPPORTED_CURRENCY

The requested cryptocurrency is not supported

Solution: Use a supported currency (ETH, USDC, USDT, MATIC)

UNSUPPORTED_NETWORK

The specified network is not supported

Solution: Use a supported network (ethereum, polygon, base)

AMOUNT_TOO_LOW

Transaction amount is below the minimum ($10)

Solution: Increase the amount to at least $10

AMOUNT_TOO_HIGH

Transaction amount exceeds your plan limit

Solution: Reduce amount or upgrade your plan for higher limits

INVALID_METADATA

Metadata object contains invalid data types

Solution: Ensure metadata values are strings, numbers, or booleans

Resource Errors (404)

SESSION_NOT_FOUND

The specified session ID does not exist

Solution: Verify the session_id is correct

TRANSACTION_NOT_FOUND

The specified transaction ID does not exist

Solution: Verify the transaction ID is correct

API_KEY_NOT_FOUND

The specified API key ID does not exist

Solution: Verify the key ID is correct

Session Errors (400)

SESSION_EXPIRED

The onramp session has expired

Solution: Create a new session (sessions expire after 30 minutes)

SESSION_ALREADY_USED

The session has already been completed or failed

Solution: Create a new session for another transaction

QUOTE_EXPIRED

The price quote has expired

Solution: Create a new session to get an updated quote

Rate Limit Errors (429)

RATE_LIMITED

Too many requests - rate limit exceeded

Solution: Wait and retry after the Retry-After header duration

Server Errors (500)

INTERNAL_ERROR

An unexpected error occurred

Solution: Retry the request. If persistent, contact support.

SERVICE_UNAVAILABLE

Service is temporarily unavailable

Solution: Retry after a few minutes

Handling Errors in Code

javascript
1400">import { Web3Pay } 400">from 400">'@web3pay/sdk';
2 
3400">const client = 400">new Web3Pay({ apiKey: 400">'wp3_live_sk_...' });
4 
5400">async 400">function createPurchase(walletAddress, amount) {
6 400">try {
7 400">const session = 400">await client.createSession({
8 walletAddress,
9 cryptoCurrency: 400">'ETH',
10 fiatAmount: amount,
11 fiatCurrency: 400">'USD'
12 });
13 400">return session;
14 } 400">catch (error) {
15 500">// Handle specific error codes
16 400">switch (error.code) {
17 400">case 400">'INVALID_WALLET_ADDRESS':
18 showError(400">'Please enter a valid Ethereum wallet address');
19 400">break;
20 
21 400">case 400">'AMOUNT_TOO_LOW':
22 showError(400">'Minimum purchase amount is $10');
23 400">break;
24 
25 400">case 400">'AMOUNT_TOO_HIGH':
26 showError(400">'Amount exceeds your daily limit');
27 400">break;
28 
29 400">case 400">'CONNECT_NOT_READY':
30 500">// Redirect to complete setup
31 window.location.href = 400">'/dashboard/connect';
32 400">break;
33 
34 400">case 400">'RATE_LIMITED':
35 500">// Retry after delay
36 400">const retryAfter = error.retryAfter || 60;
37 showError(400">`Too many requests. Please 400">try again in ${retryAfter}s`);
38 400">break;
39 
40 400">default:
41 500">// Generic error handling
42 showError(400">'Something went wrong. Please 400">try again.');
43 console.error(400">'API Error:', error);
44 }
45 }
46}

Retry Logic

Some errors are transient and can be retried. Here's a recommended approach:

javascript
400">async 400">function withRetry(fn, maxRetries = 3) {
  400">let lastError;

  for (400">let attempt = 1; attempt <= maxRetries; attempt++) {
    400">try {
      400">return 400">await fn();
    } 400">catch (error) {
      lastError = error;

      500">// Don&#039;t retry client errors (except rate limits)
      400">if (error.status >= 400 && error.status < 500 && error.code !== 400">&#039;RATE_LIMITED&#039;) {
        400">throw error;
      }

      500">// Don400">&#039;t retry on last attempt
      400">if (attempt === maxRetries) {
        400">throw error;
      }

      500">// Calculate delay (exponential backoff)
      400">const delay = error.code === &#039;RATE_LIMITED&#039;
        ? (error.retryAfter || 60) * 1000
        : Math.min(1000 * Math.pow(2, attempt), 30000);

      400">await 400">new Promise(resolve => setTimeout(resolve, delay));
    }
  }

  400">throw lastError;
}

500">// Usage
400">const session = 400">await withRetry(() => client.createSession({...}));

Retryable Errors

  • RATE_LIMITED - Always retry after the specified delay
  • INTERNAL_ERROR - Retry with exponential backoff
  • SERVICE_UNAVAILABLE - Retry with exponential backoff

Non-Retryable Errors

  • All 400 errors (except rate limits) - Fix the request first
  • All 401/403 errors - Authentication/authorization issues
  • All 404 errors - Resource doesn't exist
Back to home
Was this page helpful?