Errors

Understanding and handling Shika Creators API errors.

Errors

Shika Creators uses conventional HTTP response codes to indicate the success or failure of an API request. Codes in the 2xx range indicate success, 4xx codes indicate an error from the information provided, and 5xx codes indicate a server error.

Error Response Format

All errors follow this format:

{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "The amount must be a positive integer",
    "param": "amount",
    "doc_url": "https://docs.shikacreators.com/errors/parameter_invalid"
  }
}

Error Object

FieldTypeDescription
typestringThe type of error
codestringSpecific error code
messagestringHuman-readable message
paramstringParameter that caused the error (if applicable)
doc_urlstringLink to documentation about this error

HTTP Status Codes

StatusDescription
200OK - Request succeeded
201Created - Resource created successfully
400Bad Request - Invalid parameters
401Unauthorized - Invalid API key
403Forbidden - Not allowed to access resource
404Not Found - Resource doesn't exist
409Conflict - Request conflicts with current state
422Unprocessable Entity - Request understood but cannot be processed
429Too Many Requests - Rate limit exceeded
500Internal Server Error - Something went wrong on our end

Error Types

api_error

Server-side errors. These are rare and indicate something went wrong on Shika Creators's end.

{
  "error": {
    "type": "api_error",
    "message": "An unexpected error occurred. Please try again."
  }
}

authentication_error

Invalid or missing API key.

{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "Invalid API key provided."
  }
}

invalid_request_error

The request has invalid parameters.

{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "Missing required parameter: amount",
    "param": "amount"
  }
}

rate_limit_error

Too many requests in a short period.

{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "Too many requests. Please retry after 60 seconds."
  }
}

card_error

Card payment-specific errors.

{
  "error": {
    "type": "card_error",
    "code": "payment_method_declined",
    "message": "The card was declined."
  }
}

idempotency_error

Conflicting idempotency key errors.

{
  "error": {
    "type": "idempotency_error",
    "code": "idempotent_request_mismatch",
    "message": "The request body does not match the original request with this idempotency key."
  }
}

Error Codes

Authentication Errors

CodeStatusDescription
invalid_api_key401The API key is invalid
api_key_expired401The API key has expired
missing_api_key401No API key provided
invalid_token401The authentication token is invalid
token_expired401The authentication token has expired
access_denied403You do not have permission to perform this action
insufficient_permissions403Your API key does not have the required permissions
secret_key_required403This endpoint requires a secret API key (sk_*)
live_mode_required403This action can only be performed in live mode
test_mode_required403This action can only be performed in test mode
two_factor_required403Two-factor authentication is required

Request Errors

CodeStatusDescription
invalid_request400The request was invalid
missing_required_param400A required parameter is missing
invalid_param400A parameter value is invalid
invalid_phone_number400The phone number is invalid
invalid_email400The email address is invalid
invalid_amount400The amount is invalid
invalid_provider400The payment provider is not supported
invalid_metadata400The metadata is invalid
metadata_limit_exceeded400The metadata exceeds the maximum allowed size
resource_not_found404Requested resource doesn't exist
resource_already_exists409A resource with this identifier already exists
customer_already_exists409A customer with this email or phone already exists
duplicate_coupon_code409A coupon with this code already exists

Idempotency Errors

CodeStatusDescription
idempotency_key_in_use409A request with this idempotency key is already being processed
idempotent_request_mismatch409The request body does not match the original request

Amount Errors

CodeStatusDescription
amount_too_small400Below minimum (GHS 1.00)
amount_too_large400Above maximum allowed
invalid_currency400Currency not supported

State Errors

CodeStatusDescription
invalid_state_transition400The requested state transition is not allowed
payment_already_completed400This payment has already been completed
payment_already_refunded400This payment has already been refunded
payment_cannot_be_refunded400This payment cannot be refunded in its current state
refund_amount_exceeds_payment400The refund amount exceeds the original payment amount
subscription_already_canceled400This subscription has already been canceled
invoice_already_paid400This invoice has already been paid
invoice_already_finalized400This invoice has already been finalized
dispute_already_closed400This dispute has already been closed
evidence_already_submitted400Evidence has already been submitted for this dispute
evidence_deadline_passed400The deadline for submitting evidence has passed

Balance & Limit Errors

CodeStatusDescription
insufficient_balance400Insufficient balance to complete this transaction
daily_limit_exceeded400Daily transaction limit exceeded
monthly_limit_exceeded400Monthly transaction limit exceeded
transaction_count_exceeded400Transaction count limit exceeded

Payment Provider Errors

CodeStatusDescription
payment_failed402The payment could not be processed
insufficient_funds402The account has insufficient funds
payment_method_declined402The payment method was declined
account_not_found402The payment account was not found
provider_error502The payment provider returned an error
provider_timeout504The payment provider did not respond in time
provider_unavailable503The payment provider is currently unavailable

Fraud & Security Errors

CodeStatusDescription
payment_blocked403This payment has been blocked due to suspected fraud
high_risk_transaction403This transaction has been flagged as high risk
blocklisted403This account or identifier is on the blocklist
velocity_exceeded403Too many transactions in a short period

File Upload Errors

CodeStatusDescription
file_too_large400The file exceeds the maximum allowed size
invalid_file_type400The file type is not supported
file_upload_failed500The file could not be uploaded

Webhook Errors

CodeStatusDescription
invalid_webhook_url400The webhook URL is invalid (must be HTTPS)
invalid_webhook_signature400The webhook signature is invalid

Rate Limit Errors

CodeStatusDescription
rate_limit_exceeded429Too many requests

Server Errors

CodeStatusDescription
internal_error500An internal error occurred
service_unavailable503The service is temporarily unavailable

Handling Errors

import Shika Creators, { Shika CreatorsError } from '@shikacreators/node'

const shikacreators = new Shika Creators('sk_test_...')

try {
  const payment = await shikacreators.payments.create({
    amount: 5000,
    currency: 'GHS',
    payment_method: 'mobile_money',
    phone: '0241234567'
  })
} catch (error) {
  if (error instanceof Shika CreatorsError) {
    switch (error.type) {
      case 'authentication_error':
        console.error('Check your API key')
        break

      case 'invalid_request_error':
        console.error(`Invalid parameter: ${error.param}`)
        break

      case 'payment_error':
        switch (error.code) {
          case 'insufficient_funds':
            // Tell customer to top up
            break
          case 'phone_unreachable':
            // Tell customer to check their phone
            break
          default:
            console.error(error.message)
        }
        break

      case 'rate_limit_error':
        // Wait and retry
        await sleep(60000)
        break

      case 'api_error':
        // Log and alert
        console.error('Shika Creators server error:', error.message)
        break
    }
  } else {
    // Network error or other
    console.error('Unexpected error:', error)
  }
}
import shikacreators
from shikacreators.errors import (
    Shika CreatorsError,
    AuthenticationError,
    InvalidRequestError,
    PaymentError,
    RateLimitError,
    APIError
)

client = shikacreators.Client('sk_test_...')

try:
    payment = client.payments.create(
        amount=5000,
        currency='GHS',
        payment_method='mobile_money',
        phone='0241234567'
    )
except AuthenticationError as e:
    print('Check your API key')

except InvalidRequestError as e:
    print(f'Invalid parameter: {e.param}')

except PaymentError as e:
    if e.code == 'insufficient_funds':
        print('Please top up your account')
    elif e.code == 'phone_unreachable':
        print('Please check your phone')
    else:
        print(e.message)

except RateLimitError:
    import time
    time.sleep(60)
    # Retry

except APIError as e:
    print(f'Shika Creators server error: {e.message}')

except Shika CreatorsError as e:
    print(f'Error: {e.message}')
use Shika Creators\Shika Creators;
use Shika Creators\Exception\Shika CreatorsException;
use Shika Creators\Exception\AuthenticationException;
use Shika Creators\Exception\InvalidRequestException;
use Shika Creators\Exception\PaymentException;
use Shika Creators\Exception\RateLimitException;
use Shika Creators\Exception\ApiException;

$shikacreators = new Shika Creators('sk_test_...');

try {
    $payment = $shikacreators->payments->create([
        'amount' => 5000,
        'currency' => 'GHS',
        'payment_method' => 'mobile_money',
        'phone' => '0241234567'
    ]);
} catch (AuthenticationException $e) {
    echo 'Check your API key';

} catch (InvalidRequestException $e) {
    echo 'Invalid parameter: ' . $e->getParam();

} catch (PaymentException $e) {
    switch ($e->getCode()) {
        case 'insufficient_funds':
            echo 'Please top up your account';
            break;
        case 'phone_unreachable':
            echo 'Please check your phone';
            break;
        default:
            echo $e->getMessage();
    }

} catch (RateLimitException $e) {
    sleep(60);
    // Retry

} catch (ApiException $e) {
    error_log('Shika Creators server error: ' . $e->getMessage());

} catch (Shika CreatorsException $e) {
    echo 'Error: ' . $e->getMessage();
}

Best Practices

1. Always Handle Errors

Never assume API calls will succeed:

// Bad - no error handling
const payment = await shikacreators.payments.create({...})

// Good - proper error handling
try {
  const payment = await shikacreators.payments.create({...})
} catch (error) {
  // Handle appropriately
}

2. Show Helpful Messages

Map error codes to user-friendly messages:

const errorMessages = {
  insufficient_funds: 'Your mobile money balance is too low. Please top up and try again.',
  phone_unreachable: 'We couldn\'t reach your phone. Make sure it\'s on and try again.',
  timeout: 'The request timed out. Please try again.',
  daily_limit_exceeded: 'You\'ve reached your daily limit. Try again tomorrow.'
}

function getErrorMessage(error) {
  return errorMessages[error.code] || 'Something went wrong. Please try again.'
}

3. Log Errors for Debugging

Log errors with context for debugging:

catch (error) {
  console.error('Payment failed', {
    type: error.type,
    code: error.code,
    message: error.message,
    param: error.param,
    requestId: error.requestId,
    orderId: order.id
  })
}

4. Retry Intelligently

Implement retries with exponential backoff for transient errors:

async function createPaymentWithRetry(params, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await shikacreators.payments.create(params)
    } catch (error) {
      if (error.type === 'api_error' && i < maxRetries - 1) {
        await sleep(Math.pow(2, i) * 1000) // 1s, 2s, 4s
        continue
      }
      throw error
    }
  }
}

Only retry on transient errors like api_error or rate_limit_error. Don't retry on invalid_request_error or payment_error.