> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orsunpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Codes and Handling

> Complete reference for Orsunpay API error codes, HTTP statuses, and retry strategies

# Error Codes and Handling

This guide provides comprehensive information about error handling in the Orsunpay API, including error codes, retry strategies, and best practices.

## Error Response Format

All API errors follow a consistent format:

```json theme={null}
{
  "error": {
    "code": "error_code",
    "message": "Human-readable error description",
    "details": {
      "field": "Additional context about the error",
      "suggestion": "Recommended action to resolve"
    }
  }
}
```

## HTTP Status Codes

| Status | Name                  | Description                            | When to Retry  |
| ------ | --------------------- | -------------------------------------- | -------------- |
| `400`  | Bad Request           | Invalid request parameters             | ❌ Never        |
| `401`  | Unauthorized          | Invalid or missing API key             | ❌ Never        |
| `403`  | Forbidden             | Insufficient permissions               | ❌ Never        |
| `404`  | Not Found             | Resource doesn't exist                 | ❌ Never        |
| `409`  | Conflict              | Resource conflict (e.g., duplicate)    | ❌ Never        |
| `422`  | Unprocessable Entity  | Valid request, business rule violation | ❌ Never        |
| `429`  | Too Many Requests     | Rate limit exceeded                    | ✅ After delay  |
| `500`  | Internal Server Error | Server error                           | ✅ With backoff |
| `502`  | Bad Gateway           | Upstream service error                 | ✅ With backoff |
| `503`  | Service Unavailable   | Service temporarily down               | ✅ With backoff |
| `504`  | Gateway Timeout       | Request timeout                        | ✅ With backoff |

## Authentication Errors

### `authentication_required`

```json theme={null}
{
  "error": {
    "code": "authentication_required",
    "message": "No API key provided",
    "details": {
      "suggestion": "Include 'Authorization: Bearer your_api_key' header"
    }
  }
}
```

### `invalid_api_key`

```json theme={null}
{
  "error": {
    "code": "invalid_api_key",
    "message": "The provided API key is invalid",
    "details": {
      "suggestion": "Verify your API key is correct and active"
    }
  }
}
```

### `insufficient_permissions`

```json theme={null}
{
  "error": {
    "code": "insufficient_permissions",
    "message": "API key does not have permission for this operation",
    "details": {
      "required_permission": "transactions:write"
    }
  }
}
```

## Validation Errors

### `invalid_request`

```json theme={null}
{
  "error": {
    "code": "invalid_request",
    "message": "Missing required parameter: amount",
    "details": {
      "field": "amount",
      "location": "body"
    }
  }
}
```

### `invalid_parameter_value`

```json theme={null}
{
  "error": {
    "code": "invalid_parameter_value",
    "message": "Currency must be a valid ISO 4217 code",
    "details": {
      "field": "currency",
      "provided": "US",
      "expected": "USD"
    }
  }
}
```

### `parameter_out_of_range`

```json theme={null}
{
  "error": {
    "code": "parameter_out_of_range",
    "message": "Amount must be between 100 and 100000",
    "details": {
      "field": "amount",
      "min": 100,
      "max": 100000,
      "provided": 50
    }
  }
}
```

## Resource Errors

### `resource_not_found`

```json theme={null}
{
  "error": {
    "code": "resource_not_found", 
    "message": "Transaction tr_invalid123 not found",
    "details": {
      "resource_type": "transaction",
      "resource_id": "tr_invalid123"
    }
  }
}
```

### `resource_already_exists`

```json theme={null}
{
  "error": {
    "code": "resource_already_exists",
    "message": "Customer with buyerId 'customer_123' already exists",
    "details": {
      "field": "buyerId",
      "existing_id": "cu_clkj3h2n0000qjr8x4c5h6e7b"
    }
  }
}
```

## Business Logic Errors

### `transaction_not_capturable`

```json theme={null}
{
  "error": {
    "code": "transaction_not_capturable",
    "message": "Transaction must be in PROCESSING status to capture",
    "details": {
      "current_status": "SUCCESS",
      "required_status": "PROCESSING"
    }
  }
}
```

### `insufficient_balance`

```json theme={null}
{
  "error": {
    "code": "insufficient_balance",
    "message": "Merchant account has insufficient balance for payout",
    "details": {
      "available_balance": 1000,
      "requested_amount": 5000
    }
  }
}
```

### `payment_method_not_supported`

```json theme={null}
{
  "error": {
    "code": "payment_method_not_supported",
    "message": "Payment method 'crypto' not available in country 'BR'",
    "details": {
      "payment_method": "crypto",
      "country": "BR",
      "available_methods": ["card", "pix", "boleto"]
    }
  }
}
```

## Rate Limiting Errors

### `rate_limit_exceeded`

```json theme={null}
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Too many requests. Please retry after some time.",
    "details": {
      "limit": 1000,
      "window": "1 hour",
      "retry_after": 60
    }
  }
}
```

## Provider Errors

### `provider_error`

```json theme={null}
{
  "error": {
    "code": "provider_error",
    "message": "Payment provider returned an error",
    "details": {
      "provider": "stripe",
      "provider_code": "card_declined",
      "provider_message": "Your card was declined"
    }
  }
}
```

### `provider_unavailable`

```json theme={null}
{
  "error": {
    "code": "provider_unavailable",
    "message": "Payment provider is temporarily unavailable",
    "details": {
      "provider": "paypal",
      "estimated_recovery": "2023-11-15T11:00:00.000Z"
    }
  }
}
```

## Idempotency Errors

### `idempotency_conflict`

```json theme={null}
{
  "error": {
    "code": "idempotency_conflict",
    "message": "Request conflicts with previous request using same idempotency key",
    "details": {
      "idempotency_key": "user_123_order_456",
      "original_request_id": "req_abc123",
      "conflict_field": "amount"
    }
  }
}
```

## Retry Strategies

### Exponential Backoff

```javascript theme={null}
async function retryWithBackoff(apiCall, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await apiCall();
    } catch (error) {
      // Don't retry client errors (4xx)
      if (error.status >= 400 && error.status < 500) {
        throw error;
      }
      
      // Don't retry on last attempt
      if (attempt === maxRetries - 1) {
        throw error;
      }
      
      // Exponential backoff: 1s, 2s, 4s
      const delay = Math.pow(2, attempt) * 1000;
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

// Usage
const transaction = await retryWithBackoff(async () => {
  return await orsunpay.transactions.create(transactionData);
});
```

### Rate Limit Handling

```javascript theme={null}
async function handleRateLimit(apiCall) {
  try {
    return await apiCall();
  } catch (error) {
    if (error.status === 429) {
      const retryAfter = error.response?.headers?.['retry-after'] || 60;
      console.log(`Rate limited. Retrying after ${retryAfter} seconds`);
      
      await new Promise(resolve => 
        setTimeout(resolve, retryAfter * 1000)
      );
      
      return await apiCall();
    }
    throw error;
  }
}
```

### Circuit Breaker Pattern

```javascript theme={null}
class CircuitBreaker {
  constructor(threshold = 5, timeout = 60000) {
    this.threshold = threshold;
    this.timeout = timeout;
    this.failures = 0;
    this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
    this.nextAttempt = Date.now();
  }

  async call(apiCall) {
    if (this.state === 'OPEN') {
      if (Date.now() < this.nextAttempt) {
        throw new Error('Circuit breaker is OPEN');
      } else {
        this.state = 'HALF_OPEN';
      }
    }

    try {
      const result = await apiCall();
      this.onSuccess();
      return result;
    } catch (error) {
      this.onFailure();
      throw error;
    }
  }

  onSuccess() {
    this.failures = 0;
    this.state = 'CLOSED';
  }

  onFailure() {
    this.failures++;
    if (this.failures >= this.threshold) {
      this.state = 'OPEN';
      this.nextAttempt = Date.now() + this.timeout;
    }
  }
}

// Usage
const breaker = new CircuitBreaker();
const transaction = await breaker.call(async () => {
  return await orsunpay.transactions.create(transactionData);
});
```

## Error Handling Best Practices

### 1. Implement Proper Error Handling

```javascript theme={null}
async function processPayment(paymentData) {
  try {
    const transaction = await orsunpay.transactions.create(paymentData);
    return { success: true, transaction };
  } catch (error) {
    console.error('Payment processing error:', {
      code: error.code,
      message: error.message,
      orderId: paymentData.orderId
    });

    // Handle specific error types
    switch (error.code) {
      case 'payment_method_not_supported':
        return {
          success: false,
          error: 'This payment method is not available in your country',
          suggestedMethods: error.details?.available_methods
        };
        
      case 'invalid_parameter_value':
        return {
          success: false,
          error: `Invalid ${error.details?.field}: ${error.message}`
        };
        
      case 'rate_limit_exceeded':
        // Implement retry logic or queue the request
        return {
          success: false,
          error: 'Too many requests. Please try again in a few minutes.',
          retryAfter: error.details?.retry_after
        };
        
      default:
        return {
          success: false,
          error: 'Payment processing failed. Please try again.'
        };
    }
  }
}
```

### 2. Log Errors Appropriately

```javascript theme={null}
function logError(error, context = {}) {
  const logData = {
    timestamp: new Date().toISOString(),
    error_code: error.code,
    error_message: error.message,
    http_status: error.status,
    request_id: error.request_id,
    ...context
  };

  // Don't log sensitive information
  delete logData.api_key;
  delete logData.customer_data;

  console.error('API Error:', logData);
  
  // Send to monitoring service
  if (error.status >= 500) {
    monitoring.alert('API Error', logData);
  }
}
```

### 3. Graceful Degradation

```javascript theme={null}
async function getPaymentMethods(country, currency) {
  try {
    const methods = await orsunpay.paymentMethods.list({
      country,
      currency
    });
    return methods.data;
  } catch (error) {
    console.warn('Failed to fetch payment methods:', error.message);
    
    // Fall back to default payment methods
    return [
      { id: 'card', name: 'Credit/Debit Card' },
      { id: 'paypal', name: 'PayPal' }
    ];
  }
}
```

### 4. User-Friendly Error Messages

```javascript theme={null}
function getUserFriendlyMessage(error) {
  const messages = {
    'authentication_required': 'Please log in to continue.',
    'insufficient_permissions': 'You don\'t have permission to perform this action.',
    'resource_not_found': 'The requested item could not be found.',
    'rate_limit_exceeded': 'Too many requests. Please wait a moment and try again.',
    'payment_method_not_supported': 'This payment method is not available.',
    'provider_error': 'Payment processing failed. Please try a different payment method.',
    'provider_unavailable': 'Payment service is temporarily unavailable. Please try again later.'
  };

  return messages[error.code] || 'An unexpected error occurred. Please try again.';
}
```

## Monitoring and Alerting

### Error Rate Monitoring

Set up alerts for:

* Error rate > 5% over 5 minutes
* Specific error codes (authentication, provider errors)
* Rate limiting events
* Circuit breaker state changes

### Key Metrics

* **Error Rate**: Percentage of requests resulting in errors
* **Error Distribution**: Breakdown by error code and HTTP status
* **Recovery Time**: Time to recover from errors
* **Retry Success Rate**: Success rate of retry attempts

<Warning>
  Always implement proper error handling and never expose sensitive information in error messages or logs.
</Warning>

<Tip>
  Use idempotency keys for all state-changing operations to prevent duplicate processing in retry scenarios.
</Tip>
