Skip to main content

Overview

NIP (Notificação Instantânea de Pagamento) is Akatus’s webhook system that sends instant notifications to your server when a transaction’s status changes. This is the recommended way to track payment status instead of polling the status API.

How NIP Works

1

Configure Webhook URL

Set up your webhook endpoint URL in the Akatus dashboard. This is where Akatus will POST notifications.
2

Receive POST Request

When a transaction status changes, Akatus sends a POST request to your endpoint with transaction details.
3

Process Notification

Use the SDK to validate and process the notification data.
4

Update Your System

Update your order status, inventory, and send confirmation emails based on the notification.

Webhook Configuration

Required Configuration

Before implementing NIP, configure the following in your Web.config:
<appSettings>
  <!-- Akatus - Environment ('producao' or 'testes')-->
  <add key="AkatusAmbiente" value="testes"/>
  
  <!-- Akatus - API Key -->
  <add key="AkatusApiKey" value="YOUR-API-KEY"/>
  
  <!-- Akatus - NIP Token (for webhook validation) -->
  <add key="AkatusTokenNIP" value="YOUR-NIP-TOKEN"/>
  
  <!-- Akatus - Account Email -->
  <add key="AkatusEmail" value="your@email.com"/>
</appSettings>
The NIP Token is critical for security. It validates that notifications are genuinely from Akatus and not from malicious sources.

Implementing the Webhook Endpoint

Basic Implementation

using System;
using System.Web.UI;
using Akatus.NotificacaoPagamento;

public partial class RecebeNotificacaoPagamento : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Get posted parameters from Akatus
        string token = Request.Form["token"];
        string transacao_id = Request.Form["transacao_id"];
        string status = Request.Form["status"];
        string referencia = Request.Form["referencia"];
        
        // Process the notification
        Retorno retorno = Notificacao.processaRetorno(token, transacao_id, status, referencia);
        
        if (retorno != null)
        {
            // Notification is valid, update your system
            UpdateOrderStatus(retorno);
        }
        else
        {
            // Invalid notification (bad token or data)
            Response.StatusCode = 400;
        }
    }
    
    private void UpdateOrderStatus(Retorno notificacao)
    {
        // Your business logic here
        Console.WriteLine($"Transaction {notificacao.TransacaoId} status: {notificacao.Status}");
    }
}

POST Parameters

Akatus sends the following parameters in the POST request:
ParameterTypeDescription
tokenstringSecurity token (must match your configured NIP token)
transacao_idstringUnique transaction ID (UUID)
statusstringNew transaction status
referenciastringYour reference code for the transaction

Response Object

The Retorno object from processaRetorno() contains:
PropertyTypeDescription
StatusStatusTransacaoTransaction status enum
TransacaoIdstringTransaction unique identifier
ReferenciastringYour reference code
If the token validation fails, processaRetorno() returns null. Always check for null before processing.

Complete Implementation Example

using System;
using System.Web.UI;
using Akatus.NotificacaoPagamento;
using Akatus.Enums;

public partial class AkatusWebhook : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            // Log the incoming request
            LogWebhookRequest();
            
            // Get POST parameters
            string token = Request.Form["token"];
            string transacaoId = Request.Form["transacao_id"];
            string status = Request.Form["status"];
            string referencia = Request.Form["referencia"];
            
            // Validate parameters
            if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(transacaoId))
            {
                LogError("Missing required parameters");
                Response.StatusCode = 400;
                Response.End();
                return;
            }
            
            // Process notification with token validation
            Retorno retorno = Notificacao.processaRetorno(token, transacaoId, status, referencia);
            
            if (retorno != null)
            {
                // Valid notification received
                LogSuccess($"Valid notification for transaction {retorno.TransacaoId}");
                
                // Update your database
                UpdateOrderInDatabase(retorno);
                
                // Send email notifications if needed
                SendCustomerNotification(retorno);
                
                // Return success
                Response.StatusCode = 200;
                Response.Write("OK");
            }
            else
            {
                // Invalid token or notification
                LogError("Invalid notification - token validation failed");
                Response.StatusCode = 401;
                Response.Write("Unauthorized");
            }
        }
        catch (Exception ex)
        {
            // Log error but still return 200 to prevent retries
            LogError($"Exception processing webhook: {ex.Message}");
            Response.StatusCode = 500;
        }
        finally
        {
            Response.End();
        }
    }
    
    private void UpdateOrderInDatabase(Retorno notificacao)
    {
        // Your database update logic
        string orderId = notificacao.Referencia;
        StatusTransacao status = notificacao.Status;
        
        switch (status)
        {
            case StatusTransacao.completo:
                // Mark order as paid
                // Release inventory
                // Trigger fulfillment
                break;
                
            case StatusTransacao.aprovado:
                // Mark order as approved
                // Prepare for shipping
                break;
                
            case StatusTransacao.cancelado:
            case StatusTransacao.estornado:
                // Cancel order
                // Release inventory
                // Process refund
                break;
                
            case StatusTransacao.chargeback:
                // Alert fraud team
                // Update accounting
                break;
                
            default:
                // Log status for monitoring
                break;
        }
    }
    
    private void SendCustomerNotification(Retorno notificacao)
    {
        // Send email based on status
        if (notificacao.Status == StatusTransacao.completo)
        {
            // Send payment confirmation email
        }
        else if (notificacao.Status == StatusTransacao.cancelado)
        {
            // Send cancellation notice
        }
    }
    
    private void LogWebhookRequest()
    {
        // Log for debugging and audit
        string logMessage = $"[{DateTime.Now}] Webhook received from {Request.UserHostAddress}";
        // Your logging implementation
    }
    
    private void LogSuccess(string message)
    {
        // Your logging implementation
    }
    
    private void LogError(string message)
    {
        // Your logging implementation
    }
}

MVC Implementation

For ASP.NET MVC applications:
using System.Web.Mvc;
using Akatus.NotificacaoPagamento;
using Akatus.Enums;

public class WebhookController : Controller
{
    [HttpPost]
    public ActionResult AkatusNotification()
    {
        try
        {
            // Get POST parameters
            string token = Request.Form["token"];
            string transacaoId = Request.Form["transacao_id"];
            string status = Request.Form["status"];
            string referencia = Request.Form["referencia"];
            
            // Process notification
            Retorno retorno = Notificacao.processaRetorno(token, transacaoId, status, referencia);
            
            if (retorno != null)
            {
                // Update order
                var orderService = new OrderService();
                orderService.UpdatePaymentStatus(retorno.Referencia, retorno.Status);
                
                return new HttpStatusCodeResult(200, "OK");
            }
            
            return new HttpStatusCodeResult(401, "Unauthorized");
        }
        catch
        {
            return new HttpStatusCodeResult(500, "Internal Server Error");
        }
    }
}

Web API Implementation

For ASP.NET Web API:
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Akatus.NotificacaoPagamento;

public class NotificationController : ApiController
{
    [HttpPost]
    [Route("api/webhooks/akatus")]
    public HttpResponseMessage ReceiveNotification()
    {
        try
        {
            var form = Request.Content.ReadAsFormDataAsync().Result;
            
            string token = form["token"];
            string transacaoId = form["transacao_id"];
            string status = form["status"];
            string referencia = form["referencia"];
            
            Retorno retorno = Notificacao.processaRetorno(token, transacaoId, status, referencia);
            
            if (retorno != null)
            {
                // Process the notification
                ProcessPaymentNotification(retorno);
                
                return Request.CreateResponse(HttpStatusCode.OK, "Notification processed");
            }
            
            return Request.CreateResponse(HttpStatusCode.Unauthorized, "Invalid token");
        }
        catch (Exception ex)
        {
            return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
        }
    }
    
    private void ProcessPaymentNotification(Retorno notification)
    {
        // Your business logic
    }
}

Security Best Practices

Always validate the NIP token to ensure notifications are from Akatus:
Retorno retorno = Notificacao.processaRetorno(token, transacaoId, status, referencia);

if (retorno == null)
{
    // INVALID TOKEN - Do not process
    LogSecurityAlert("Invalid NIP token received");
    return;
}
Handle duplicate notifications gracefully:
private bool IsNotificationProcessed(string transacaoId)
{
    // Check if this notification was already processed
    return db.ProcessedNotifications.Any(n => n.TransacaoId == transacaoId);
}

if (!IsNotificationProcessed(retorno.TransacaoId))
{
    UpdateOrderStatus(retorno);
    MarkNotificationAsProcessed(retorno.TransacaoId);
}
Configure your webhook URL to use HTTPS only:
  • Protects notification data in transit
  • Prevents man-in-the-middle attacks
  • Required for production environments
Return appropriate HTTP status codes:
// Success - Akatus will not retry
Response.StatusCode = 200;

// Invalid data - Akatus will not retry
Response.StatusCode = 400;

// Server error - Akatus may retry
Response.StatusCode = 500;

Testing Webhooks

Local Testing

Use a tool like ngrok to expose your local development server:
ngrok http 80
Then configure the ngrok URL in your Akatus test account.

Test Notification

Create a test page to simulate notifications:
<form action="/RecebeNotificacaoPagamento.aspx" method="post">
    <input type="text" name="token" value="YOUR-NIP-TOKEN" />
    <input type="text" name="transacao_id" value="00000000-0000-0000-0000-000000000000" />
    <input type="text" name="status" value="completo" />
    <input type="text" name="referencia" value="TEST-ORDER-001" />
    <button type="submit">Send Test Notification</button>
</form>

Debugging Tips

Log all incoming webhook requests for debugging:
private void LogWebhookDetails()
{
    var log = new StringBuilder();
    log.AppendLine($"Timestamp: {DateTime.Now}");
    log.AppendLine($"IP: {Request.UserHostAddress}");
    log.AppendLine($"Token: {Request.Form["token"]}");
    log.AppendLine($"Transaction: {Request.Form["transacao_id"]}");
    log.AppendLine($"Status: {Request.Form["status"]}");
    log.AppendLine($"Reference: {Request.Form["referencia"]}");
    
    File.AppendAllText("webhook-log.txt", log.ToString());
}

Status Codes Reference

Refer to Transaction Status for complete list of status values you might receive in notifications.

Next Steps

Transaction Status

Learn about all transaction status values

Error Handling

Handle errors and exceptions properly

Processing Transactions

Learn how to create transactions

Build docs developers (and LLMs) love