Error Codes

Reference for all API error codes and their meanings.

HTTP Status Codes

WiaPay API uses conventional HTTP status codes to indicate the success or failure of requests.

Status CodeMeaningDescription
200OKRequest succeeded
201CreatedResource created successfully
400Bad RequestInvalid request parameters or body
401UnauthorizedInvalid or missing authentication
403ForbiddenAccess denied (IP not whitelisted, etc.)
404Not FoundResource not found
409ConflictDuplicate resource (e.g., transaction ID)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer error (contact support)

Error Response Format

All error responses follow a consistent JSON format:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message"
  },
  "timestamp": 1705320000
}

Error Codes

Authentication Errors (401)

CodeDescriptionSolution
MISSING_API_KEYX-API-Key header not providedInclude X-API-Key header in your request
INVALID_API_KEYAPI key is invalid or disabledCheck your API key or contact support
MISSING_SIGNATUREX-Signature header not providedInclude X-Signature header in your request
INVALID_SIGNATURESignature verification failedCheck your signature generation logic
MISSING_TIMESTAMPX-Timestamp header not providedInclude X-Timestamp header in your request
INVALID_TIMESTAMPTimestamp format is invalidUse Unix timestamp in seconds
TIMESTAMP_EXPIREDRequest timestamp is too old (>5 min)Use current timestamp, sync server clock

Authorization Errors (403)

CodeDescriptionSolution
SITE_INACTIVEYour account is suspended or inactiveContact support to reactivate your account
IP_NOT_WHITELISTEDRequest IP is not in whitelistAdd your server IP to the whitelist
INSUFFICIENT_BALANCENot enough balance for withdrawalDeposit funds or reduce withdrawal amount

Validation Errors (400)

CodeDescriptionSolution
VALIDATION_ERRORRequest body validation failedCheck required fields and data types
INVALID_AMOUNTAmount is invalid (negative, zero, etc.)Provide a positive number
AMOUNT_OUT_OF_RANGEAmount outside bank limitsCheck min/max limits from available-banks
INVALID_BANKBank ID not found or inactiveUse valid bank ID from available-banks
INVALID_IBANIBAN format is invalidVerify IBAN format (TR + 24 digits)
INVALID_CURRENCYCurrency not supportedUse supported currency (TRY)

Resource Errors (404, 409)

CodeHTTPDescriptionSolution
TRANSACTION_NOT_FOUND404Transaction ID not foundVerify transaction ID exists
BANK_NOT_FOUND404Bank not found or unavailableUse ID from available-banks endpoint
DUPLICATE_TRANSACTION409processId already existsUse a unique transaction ID

Server Errors (500)

CodeDescriptionSolution
INTERNAL_SERVER_ERRORUnexpected server errorRetry request; contact support if persists
SERVICE_UNAVAILABLEService temporarily unavailableRetry after a few minutes

Example Error Responses

401 - Invalid Signature
{
  "success": false,
  "error": {
    "code": "INVALID_SIGNATURE",
    "message": "Signature verification failed"
  },
  "timestamp": 1705320000
}
400 - Validation Error
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "processId and amount are required"
  },
  "timestamp": 1705320000
}
403 - IP Not Whitelisted
{
  "success": false,
  "error": {
    "code": "IP_NOT_WHITELISTED",
    "message": "Your IP address is not whitelisted"
  },
  "timestamp": 1705320000
}
409 - Duplicate Transaction
{
  "success": false,
  "error": {
    "code": "DUPLICATE_TRANSACTION",
    "message": "Transaction with this processId already exists"
  },
  "timestamp": 1705320000
}

Error Handling Best Practices

Recommendations

  • Always check the success field in responses
  • Log error codes and messages for debugging
  • Implement retry logic with exponential backoff for 5xx errors
  • Don't retry 4xx errors without fixing the request
  • Show user-friendly error messages to customers
  • Monitor error rates and alert on anomalies
Error Handling Example (JavaScript)
async function createTransaction(data) {
  try {
    const response = await fetch('/v1/deposit', {
      method: 'POST',
      headers: { /* ... */ },
      body: JSON.stringify(data)
    });

    const result = await response.json();

    if (!result.success) {
      // Handle specific error codes
      switch (result.error.code) {
        case 'DUPLICATE_TRANSACTION':
          // Transaction already exists, maybe return existing one
          return handleDuplicateTransaction(data.processId);

        case 'AMOUNT_OUT_OF_RANGE':
          throw new Error('Amount must be between min and max limits');

        case 'INVALID_SIGNATURE':
          // Log and alert - this shouldn't happen in production
          console.error('Signature error - check implementation');
          throw new Error('Authentication error');

        default:
          throw new Error(result.error.message);
      }
    }

    return result.data;
  } catch (error) {
    // Handle network errors
    if (error.name === 'TypeError') {
      // Network error - maybe retry
      console.error('Network error:', error);
    }
    throw error;
  }
}