Preloader

Error Handling

Robust error handling ensures your integration stays reliable when things go wrong. Always handle errors gracefully — never expose raw API errors to your end users.

Common Error Scenarios
Error Cause Resolution
invalid token Expired or incorrect access token Re-authenticate: POST to /authentication to get a fresh token
invalid client_id Wrong client ID in credentials Verify Client ID in your merchant dashboard
invalid secret Wrong secret key Re-copy secret key from dashboard. Regenerate if compromised.
amount required Missing amount parameter Include 'amount' as a decimal with 2 precision (e.g. 5000.00)
currency invalid Unknown or lowercase currency code Use ISO 4217 UPPERCASE codes: XAF, USD, EUR
return_url required Missing return URL Provide a full HTTPS return URL
token not found Payment token expired or invalid Tokens expire after the session ends. Initiate a new payment.
Recommended Error Handling Pattern
<?php
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;

try {
    $response = $client->request('POST', '{{base_url}}/payment/create', $options);
    $data     = json_decode($response->getBody(), true);

    if ($data['type'] === 'success') {
        header('Location: ' . $data['data']['payment_url']);
        exit;
    }

    // API returned an error in the JSON body
    $errors = $data['message']['error'] ?? ['Payment initiation failed'];
    // Show user-friendly message, log the full $data internally

} catch (ClientException $e) {
    // 4xx error — bad request or auth failure
    $errorBody = json_decode($e->getResponse()->getBody(), true);
    $code      = $e->getResponse()->getStatusCode();
    // Log $errorBody, show friendly message to user

} catch (ServerException $e) {
    // 5xx error — server side issue
    // Log and show "please try again" message

} catch (\Exception $e) {
    // Network error, timeout, etc.
    // Log $e->getMessage(), show generic error
}
const initiatePayment = async (payload) => {
  try {
    const response = await fetch('{{base_url}}/payment/create', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer {{access_token}}',
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(payload),
    });

    const data = await response.json();

    if (!response.ok) {
      // HTTP 4xx or 5xx
      const errorMsg = data?.message?.error?.[0] || 'Payment failed';
      console.error('API Error:', response.status, errorMsg);
      throw new Error(errorMsg);
    }

    if (data.type !== 'success') {
      // HTTP 200 but logical error
      const errorMsg = data?.message?.error?.[0] || 'Unknown error';
      throw new Error(errorMsg);
    }

    return data.data; // { token, payment_url }

  } catch (err) {
    // Handle or rethrow — never show raw errors to users
    console.error('Payment initiation error:', err.message);
    throw err;
  }
};
import requests
import logging

logger = logging.getLogger(__name__)

def initiate_payment(amount, currency, return_url, order_id):
    try:
        response = requests.post(
            "{{base_url}}/payment/create",
            json={
                "amount": amount,
                "currency": currency,
                "return_url": return_url,
                "custom": order_id,
            },
            headers={
                "Authorization": "Bearer {{access_token}}",
                "Accept": "application/json",
            },
            timeout=30,
        )
        response.raise_for_status()  # raises for 4xx/5xx

        data = response.json()
        if data.get("type") != "success":
            errors = data.get("message", {}).get("error", ["Unknown error"])
            logger.error("Payment API error: %s", errors)
            return None, errors[0]

        return data["data"]["payment_url"], None

    except requests.exceptions.HTTPError as e:
        logger.error("HTTP error %s: %s", e.response.status_code, e.response.text)
        return None, "Payment service unavailable. Please try again."

    except requests.exceptions.RequestException as e:
        logger.error("Network error: %s", str(e))
        return None, "Network error. Please check your connection."
Security Note: Never expose raw API error messages (which may contain system details) directly to end users. Log errors server-side and show only generic user-friendly messages in your UI.