Skip to main content

Overview

The Akatus .NET SDK uses the RestExcepction class (note the spelling) to handle API errors. Proper error handling ensures your application can gracefully manage failed requests and provide meaningful feedback to users.

RestExcepction Class

The SDK throws Akatus.RestExcepction when API requests fail. This exception provides detailed information about what went wrong.

Properties

PropertyTypeDescription
StatusCodeintHTTP status code (e.g., 400, 401, 500)
StatusDesciptionstringHTTP status description (e.g., “Bad Request”)
ErrorMessagesList<string>List of specific error messages from the API
Note the spelling: StatusDesciption (not “Description”). This is the actual property name in the SDK.

Basic Error Handling

Try-Catch Pattern

Always wrap SDK calls in try-catch blocks:
using Akatus;
using Akatus.Carrinho;

try
{
    Carrinho carrinho = new Carrinho();
    // ... configure cart ...
    
    Retorno retorno = carrinho.processaTransacao();
    
    // Success - process the result
    if (retorno != null)
    {
        Console.WriteLine($"Transaction ID: {retorno.Transacao}");
    }
}
catch (RestExcepction ex)
{
    // Handle Akatus API errors
    Console.WriteLine($"API Error: {ex.StatusCode} - {ex.StatusDesciption}");
    
    foreach (string error in ex.ErrorMessages)
    {
        Console.WriteLine($"  - {error}");
    }
}
catch (Exception ex)
{
    // Handle other exceptions
    Console.WriteLine($"Unexpected error: {ex.Message}");
}

Common HTTP Status Codes

The request was malformed or contains invalid data.Common Causes:
  • Missing required fields
  • Invalid field formats (e.g., invalid credit card number)
  • Invalid enum values
  • Incorrect data types
Example:
catch (RestExcepction ex)
{
    if (ex.StatusCode == 400)
    {
        Console.WriteLine("Invalid request data:");
        foreach (string error in ex.ErrorMessages)
        {
            Console.WriteLine($"  - {error}");
            
            // Log specific validation errors
            if (error.Contains("cartao"))
            {
                LogError("Invalid credit card information");
            }
        }
    }
}
Authentication failed. The API key is invalid or missing.Common Causes:
  • Invalid API key in Web.config
  • Missing API key configuration
  • Using test API key in production (or vice versa)
Example:
catch (RestExcepction ex)
{
    if (ex.StatusCode == 401)
    {
        LogError("Authentication failed. Check API key configuration.");
        
        // Verify configuration
        string apiKey = ConfigurationManager.AppSettings["AkatusApiKey"];
        if (string.IsNullOrEmpty(apiKey))
        {
            Console.WriteLine("API Key is not configured!");
        }
    }
}
The request is valid, but you don’t have permission to perform this action.Common Causes:
  • Payment method not enabled in your account
  • Account limitations or restrictions
  • Trying to access resources you don’t own
Example:
catch (RestExcepction ex)
{
    if (ex.StatusCode == 403)
    {
        Console.WriteLine("Access denied. Check account permissions.");
        
        // Check if payment method is enabled
        ShowUserMessage("This payment method is not available. Please contact support.");
    }
}
The requested resource doesn’t exist.Common Causes:
  • Invalid transaction ID in status queries
  • Querying transactions from wrong environment (test vs production)
Example:
catch (RestExcepction ex)
{
    if (ex.StatusCode == 404)
    {
        Console.WriteLine($"Transaction not found.");
        
        // Verify environment
        var ambiente = Config.Ambiente;
        Console.WriteLine($"Current environment: {ambiente}");
    }
}
The Akatus server encountered an error.Common Causes:
  • Temporary API outage
  • Akatus server issues
Example:
catch (RestExcepction ex)
{
    if (ex.StatusCode == 500)
    {
        LogError("Akatus server error. Will retry.");
        
        // Implement retry logic
        Thread.Sleep(5000);
        // Retry the request
    }
}
The API is temporarily unavailable.Common Causes:
  • Scheduled maintenance
  • High traffic periods
Example:
catch (RestExcepction ex)
{
    if (ex.StatusCode == 503)
    {
        Console.WriteLine("Service temporarily unavailable.");
        ShowUserMessage("Payment system is under maintenance. Please try again later.");
    }
}

Complete Error Handling Example

using System;
using System.Collections.Generic;
using System.Threading;
using Akatus;
using Akatus.Carrinho;

public class PaymentProcessor
{
    private const int MaxRetries = 3;
    
    public Retorno ProcessPaymentWithRetry(Carrinho carrinho)
    {
        int retryCount = 0;
        
        while (retryCount < MaxRetries)
        {
            try
            {
                return ProcessPayment(carrinho);
            }
            catch (RestExcepction ex)
            {
                if (ShouldRetry(ex.StatusCode))
                {
                    retryCount++;
                    
                    if (retryCount < MaxRetries)
                    {
                        int delayMs = retryCount * 2000; // Exponential backoff
                        Console.WriteLine($"Retrying in {delayMs}ms... (attempt {retryCount + 1}/{MaxRetries})");
                        Thread.Sleep(delayMs);
                    }
                    else
                    {
                        throw; // Max retries exceeded
                    }
                }
                else
                {
                    // Don't retry for client errors
                    throw;
                }
            }
        }
        
        return null;
    }
    
    private Retorno ProcessPayment(Carrinho carrinho)
    {
        try
        {
            Retorno retorno = carrinho.processaTransacao();
            
            if (retorno != null)
            {
                LogSuccess($"Transaction successful: {retorno.Transacao}");
                return retorno;
            }
            
            LogWarning("No response data returned");
            return null;
        }
        catch (RestExcepction ex)
        {
            HandleApiError(ex);
            throw;
        }
        catch (Exception ex)
        {
            HandleUnexpectedError(ex);
            throw;
        }
    }
    
    private void HandleApiError(RestExcepction ex)
    {
        // Log detailed error information
        LogError($"API Error: {ex.StatusCode} - {ex.StatusDesciption}");
        
        if (ex.ErrorMessages != null && ex.ErrorMessages.Count > 0)
        {
            LogError("Error Details:");
            foreach (string error in ex.ErrorMessages)
            {
                LogError($"  - {error}");
            }
        }
        
        // Send alerts for critical errors
        if (ex.StatusCode == 401)
        {
            SendAlert("Authentication failed - check API credentials");
        }
        else if (ex.StatusCode >= 500)
        {
            SendAlert($"Akatus server error: {ex.StatusCode}");
        }
    }
    
    private void HandleUnexpectedError(Exception ex)
    {
        LogError($"Unexpected error: {ex.GetType().Name}");
        LogError($"Message: {ex.Message}");
        LogError($"Stack trace: {ex.StackTrace}");
    }
    
    private bool ShouldRetry(int statusCode)
    {
        // Retry only for server errors and rate limiting
        return statusCode >= 500 || statusCode == 429;
    }
    
    private void LogSuccess(string message)
    {
        Console.WriteLine($"[SUCCESS] {message}");
    }
    
    private void LogWarning(string message)
    {
        Console.WriteLine($"[WARNING] {message}");
    }
    
    private void LogError(string message)
    {
        Console.WriteLine($"[ERROR] {message}");
    }
    
    private void SendAlert(string message)
    {
        // Send email/SMS alert for critical errors
        Console.WriteLine($"[ALERT] {message}");
    }
}

User-Friendly Error Messages

Translate technical errors into user-friendly messages:
public class ErrorMessageTranslator
{
    public string GetUserFriendlyMessage(RestExcepction ex)
    {
        // Check for specific error messages
        if (ex.ErrorMessages != null)
        {
            foreach (string error in ex.ErrorMessages)
            {
                if (error.Contains("cartão inválido") || error.Contains("invalid card"))
                    return "The credit card information is invalid. Please check the card number and try again.";
                    
                if (error.Contains("CPF"))
                    return "The CPF number is invalid. Please verify and try again.";
                    
                if (error.Contains("expirado") || error.Contains("expired"))
                    return "This credit card has expired. Please use a different card.";
                    
                if (error.Contains("saldo") || error.Contains("insufficient"))
                    return "The transaction was declined due to insufficient funds.";
            }
        }
        
        // Generic messages based on status code
        switch (ex.StatusCode)
        {
            case 400:
                return "There was a problem with your payment information. Please review and try again.";
            case 401:
                return "We're experiencing technical difficulties. Please try again later or contact support.";
            case 403:
                return "This payment method is not available. Please select a different option.";
            case 500:
            case 503:
                return "Our payment system is temporarily unavailable. Please try again in a few minutes.";
            default:
                return "An error occurred while processing your payment. Please try again or contact support.";
        }
    }
}

Web Application Example

using System;
using System.Web.UI;
using Akatus;
using Akatus.Carrinho;

public partial class Checkout : Page
{
    protected void btnPay_Click(object sender, EventArgs e)
    {
        try
        {
            Carrinho carrinho = BuildCart();
            Retorno retorno = carrinho.processaTransacao();
            
            if (retorno != null)
            {
                // Success - redirect to confirmation
                Session["TransactionId"] = retorno.Transacao;
                Response.Redirect($"OrderConfirmation.aspx?ref={retorno.Referencia}");
            }
        }
        catch (RestExcepction ex)
        {
            // Show user-friendly error
            var translator = new ErrorMessageTranslator();
            string userMessage = translator.GetUserFriendlyMessage(ex);
            
            lblError.Text = userMessage;
            pnlError.Visible = true;
            
            // Log technical details
            LogError(ex);
        }
        catch (Exception ex)
        {
            // Generic error message
            lblError.Text = "An unexpected error occurred. Please try again.";
            pnlError.Visible = true;
            
            // Log exception
            LogException(ex);
        }
    }
    
    private Carrinho BuildCart()
    {
        // Your cart building logic
        return new Carrinho();
    }
    
    private void LogError(RestExcepction ex)
    {
        string logEntry = $"[{DateTime.Now}] API Error {ex.StatusCode}: {ex.StatusDesciption}\n";
        logEntry += string.Join("\n", ex.ErrorMessages);
        
        System.IO.File.AppendAllText(Server.MapPath("~/Logs/errors.txt"), logEntry);
    }
    
    private void LogException(Exception ex)
    {
        string logEntry = $"[{DateTime.Now}] Exception: {ex.Message}\n{ex.StackTrace}\n";
        System.IO.File.AppendAllText(Server.MapPath("~/Logs/exceptions.txt"), logEntry);
    }
}

Validation Before API Calls

Validate data before making API calls to catch errors early:
public class CartValidator
{
    public List<string> ValidateCart(Carrinho carrinho)
    {
        var errors = new List<string>();
        
        // Validate customer info
        if (string.IsNullOrEmpty(carrinho.Pagador.Nome))
            errors.Add("Customer name is required");
            
        if (string.IsNullOrEmpty(carrinho.Pagador.Email))
            errors.Add("Customer email is required");
        else if (!IsValidEmail(carrinho.Pagador.Email))
            errors.Add("Customer email is invalid");
        
        // Validate products
        if (carrinho.Produtos == null || carrinho.Produtos.Count == 0)
            errors.Add("At least one product is required");
        
        foreach (var produto in carrinho.Produtos)
        {
            if (produto.Preco <= 0)
                errors.Add($"Product {produto.Descricao} has invalid price");
            if (produto.Quantidade <= 0)
                errors.Add($"Product {produto.Descricao} has invalid quantity");
        }
        
        // Validate credit card if applicable
        if (IsCartaoPayment(carrinho.Transacao.MeioDePagamento))
        {
            if (string.IsNullOrEmpty(carrinho.Transacao.Cartao.Numero))
                errors.Add("Card number is required");
            if (string.IsNullOrEmpty(carrinho.Transacao.Cartao.CodigoSeguranca))
                errors.Add("Security code is required");
            if (string.IsNullOrEmpty(carrinho.Transacao.Cartao.Expiracao))
                errors.Add("Card expiration is required");
        }
        
        return errors;
    }
    
    private bool IsValidEmail(string email)
    {
        try
        {
            var addr = new System.Net.Mail.MailAddress(email);
            return addr.Address == email;
        }
        catch
        {
            return false;
        }
    }
    
    private bool IsCartaoPayment(Akatus.Enums.MeioDePagamento meio)
    {
        return meio.ToString().StartsWith("cartao_");
    }
}

Best Practices

Always Use Try-Catch

Wrap all SDK calls in try-catch blocks to handle exceptions gracefully.

Log Everything

Log all errors with timestamps, request details, and error messages for debugging.

User-Friendly Messages

Show clear, helpful messages to users instead of technical error details.

Validate Early

Validate input data before making API calls to catch errors early.

Implement Retry Logic

Retry failed requests for temporary errors (500, 503) with exponential backoff.

Monitor Errors

Set up alerts for critical errors like authentication failures.
Never expose API keys, tokens, or detailed error messages to end users. Always sanitize error information before displaying.

Next Steps

Processing Transactions

Learn how to process payments

Transaction Status

Query transaction status

Payment Notifications

Receive webhook notifications

Build docs developers (and LLMs) love