Webhook
TusFacturasAPP: API para Facturas A de AFIP/ARCA. Confiable desde 2015. Creada por devs y respaldada por expertos impositivos. ¡Los desarrolladores la aman!
Ejemplos de Webhook
Segun tu lenguaje de programacion
- Obtener los headers recibidos 
- Evaluar si el header incluye el token esperado de TF 
- Si el token coincide: - Obtener la informacion recibida 
- Ejecutar la consulta avanzada por ext. reference para traer la info del comprobante en cuestion. 
- Devolver un codigo http = 200 
 
- Si el token no coincide, salir del proceso. 
<?php
$tf_token 	= 'TOKEN_TF';  
$headers 	= getallheaders();
$header_token 	= ($headers['TF-WebhookToken'] ??  ($headers['tf-webhooktoken'] ?? '')  );
if ($header_token !== $tf_token) 
{
	http_response_code(403);
	echo 'El Token recibido no coincide con el esperado';
	exit;
}else{
	$data = file_get_contents('php://input');
	// Consulto en TF la info asociada a la ext. reference recibida
	consultar_por_ext_ref($data['external_reference']);
	// Respondo a TF con 200 para evitar entrar en el workflow de reintentos
	http_response_code(200);
	echo 'OK';
	
}
// -------------------------------------------------------------------------------------------------------
// Funcion que usa la consulta avanzada por ext. ref
// Docu: 
// https://developers.tusfacturas.app/web-services-afip-api-arca/consulta-avanzada-por-external-reference
// -------------------------------------------------------------------------------------------------------
function consultar_por_ext_ref(string $ext_ref)
{
	//
}
?>import os
from flask import Flask, request, abort, jsonify
# Create a Flask application instance
app = Flask(__name__)
# --- Configuration ---
# Your secret token from TusFacturasAPP
# It's better practice to load this from environment variables
# For example: os.environ.get('TF_WEBHOOK_TOKEN', 'YOUR_DEFAULT_TOKEN_IF_ENV_VAR_NOT_SET')
TF_WEBHOOK_TOKEN = 'TOKEN_TF'
# --- Webhook Endpoint ---
# This is the URL where TusFacturasAPP will send webhooks (e.g., http://yourserver.com:5000/webhook)
@app.route('/webhook', methods=['POST'])
def webhook():
    app.logger.info('Webhook received!')
    # 1. Get the token from the request headers
    # Headers in Flask's request.headers are case-insensitive by default, but it's good to check common casings.
    header_token = request.headers.get('TF-WebhookToken') or \
                   request.headers.get('tf-webhooktoken')
    # 2. Validate the token
    if header_token != TF_WEBHOOK_TOKEN:
        app.logger.warning('Unauthorized webhook access: Token mismatch.')
        # Use abort() for Flask to handle HTTP responses more cleanly
        abort(403, description='El Token recibido no coincide con el esperado')
    # 3. Token is valid, process the webhook data
    # request.json automatically parses JSON bodies
    data = request.json
    if not data:
        app.logger.error('No JSON data received in webhook request.')
        abort(400, description='No se recibió información en formato JSON.')
    app.logger.info(f'Webhook data: {data}')
    # Call your function to consult info based on external_reference
    # In a real application, this would involve database operations,
    # calling external APIs, or other backend logic.
    # We'll use a try-except block for robust error handling.
    try:
        # Ensure 'external_reference' exists in the payload
        external_reference = data.get('external_reference')
        if external_reference:
            consultar_por_ext_ref(external_reference)
        else:
            app.logger.warning("Webhook data missing 'external_reference' key.")
        # 4. Respond with 200 OK to prevent re-attempts from TusFacturasAPP
        app.logger.info('Webhook processed successfully. Sending 200 OK.')
        return 'OK', 200
    except Exception as e:
        app.logger.error(f'Error processing webhook: {e}', exc_info=True)
        # For webhook handlers, sending 200 OK even on internal processing errors
        # is often desired to acknowledge receipt and prevent re-attempts from sender.
        # Handle the error internally.
        return 'OK (processed with internal error)', 200
# --- Helper Function (simulating PHP's consultar_por_ext_ref) ---
def consultar_por_ext_ref(ext_ref: str):
    """
    Simulates a function to consult information associated with an external reference.
    In a real scenario, this would involve database operations, calling external APIs, etc.
    """
    app.logger.info(f'Consulting info for external_reference: {ext_ref}')
    # Implement your actual logic here (e.g., call TusFacturasAPP API, update database)
    # This could be an asynchronous operation if using a framework like FastAPI or Quart
    # For Flask, if you need async, you'd use a library like 'gevent' or 'eventlet' or move to FastAPI.
    pass # Placeholder for actual implementation
# --- Start the server ---
if __name__ == '__main__':
    # When running with 'flask run' (development server):
    # Flask will automatically handle port and debug mode.
    # To run directly as a script (for basic testing, not production):
    app.run(host='0.0.0.0', port=5000, debug=True)
    # For production, use a WSGI server like Gunicorn or uWSGI.
// Import necessary modules
const express = require('express');
const bodyParser = require('body-parser'); // To parse incoming JSON bodies
// Create an Express application
const app = express();
const port = 3000; // Choose a port for your webhook listener
// --- Configuration ---
// Your secret token from TusFacturasAPP
// It's better practice to load this from environment variables (e.g., process.env.TF_WEBHOOK_TOKEN)
const TF_WEBHOOK_TOKEN = 'TOKEN_TF';
// Middleware to parse JSON request bodies
app.use(bodyParser.json());
// --- Webhook Endpoint ---
// This is the URL where TusFacturasAPP will send webhooks (e.g., http://yourserver.com:3000/webhook)
app.post('/webhook', (req, res) => {
    console.log('Webhook received!');
    // 1. Get the token from the request headers
    // Headers are typically lowercase in Node.js/Express
    const headerToken = req.headers['tf-webhooktoken'];
    // 2. Validate the token
    if (headerToken !== TF_WEBHOOK_TOKEN) {
        console.warn('Unauthorized webhook access: Token mismatch.');
        // Return a 403 Forbidden response
        return res.status(403).send('El Token recibido no coincide con el esperado');
    }
    // 3. Token is valid, process the webhook data
    const data = req.body; // The parsed JSON body of the webhook
    if (!data) {
        console.error('No JSON data received in webhook request.');
        return res.status(400).send('No se recibió información en formato JSON.');
    }
    console.log('Webhook data:', data);
    // Call your function to consult info based on external_reference
    // In a real application, this would involve database operations,
    // calling external APIs, or other backend logic.
    // We'll use a try-catch block for robust error handling.
    try {
        // Ensure 'external_reference' exists in the payload
        const externalReference = data.external_reference; // Access directly from parsed JSON object
        if (externalReference) {
            consultarPorExtRef(externalReference);
        } else {
            console.warn("Webhook data missing 'external_reference' key.");
        }
        // 4. Respond with 200 OK to prevent re-attempts from TusFacturasAPP
        console.log('Webhook processed successfully. Sending 200 OK.');
        res.status(200).send('OK');
    } catch (error) {
        console.error('Error processing webhook:', error);
        // For webhook handlers, sending 200 OK even on internal processing errors
        // is often desired to acknowledge receipt and prevent re-attempts from sender.
        // Handle the error internally.
        res.status(200).send('OK (processed with internal error)');
    }
});
// --- Helper Function (simulating PHP's consultar_por_ext_ref) ---
/**
 * Simulates a function to consult information associated with an external reference.
 * In a real scenario, this would likely be an async operation (e.g., database query, API call).
 * @param {string} extRef The external reference from the webhook.
 */
function consultarPorExtRef(extRef) {
    console.log(`Consulting info for external_reference: ${extRef}`);
    // Implement your actual logic here (e.g., call TusFacturasAPP API, update database)
    // This function can be async if it involves promises (e.g., network requests, database calls)
    // Example:
    // return new Promise(resolve => {
    //     setTimeout(() => {
    //         console.log(`Information for ${extRef} consulted.`);
    //         resolve();
    //     }, 100); // Simulate network delay
    // });
}
// --- Start the server ---
app.listen(port, () => {
    console.log(`Node.js Webhook listener running on http://localhost:${port}`);
    console.log('Remember to expose this server to the internet if TusFacturasAPP needs to reach it!');
});
# Import necessary gems
require 'sinatra'
require 'json' # To parse incoming JSON bodies
# --- Configuration ---
# Your secret token from TusFacturasAPP
# It's better practice to load this from environment variables (e.g., ENV['TF_WEBHOOK_TOKEN'])
TF_WEBHOOK_TOKEN = 'TOKEN_TF'
# Set the port for your webhook listener
# This can also be set via environment variable: PORT=4567 ruby app.rb
set :port, 4567
# Disable Sinatra's default error pages for a cleaner response
disable :show_exceptions
disable :raise_errors
# --- Webhook Endpoint ---
# This is the URL where TusFacturasAPP will send webhooks (e.g., http://yourserver.com:4567/webhook)
post '/webhook' do
  puts 'Webhook received!'
  # 1. Get the token from the request headers
  # Headers in Rack (which Sinatra uses) are prefixed with HTTP_ and uppercase,
  # with hyphens converted to underscores.
  header_token = request.env['HTTP_TF_WEBHOOKTOKEN']
  # 2. Validate the token
  if header_token != TF_WEBHOOK_TOKEN
    warn 'Unauthorized webhook access: Token mismatch.'
    status 403 # Set HTTP status code to 403 Forbidden
    body 'El Token recibido no coincide con el esperado'
    return # Stop processing
  end
  # 3. Token is valid, process the webhook data
  # request.body is an IO object, read its content
  request_body = request.body.read
  data = nil
  begin
    data = JSON.parse(request_body)
  rescue JSON::ParserError => e
    warn "Invalid JSON received: #{e.message}"
    status 400 # Bad Request
    body 'No se recibió información válida en formato JSON.'
    return
  end
  puts "Webhook data: #{data}"
  # Call your function to consult info based on external_reference
  # In a real application, this would involve database operations,
  # calling external APIs, or other backend logic.
  # We'll use a begin-rescue block for robust error handling.
  begin
    # Ensure 'external_reference' exists in the payload
    external_reference = data['external_reference'] # Access directly from parsed JSON hash
    if external_reference
      consultar_por_ext_ref(external_reference)
    else
      warn "Webhook data missing 'external_reference' key."
    end
    # 4. Respond with 200 OK to prevent re-attempts from TusFacturasAPP
    puts 'Webhook processed successfully. Sending 200 OK.'
    status 200 # Set HTTP status code to 200 OK
    body 'OK'
  rescue StandardError => e
    warn "Error processing webhook: #{e.message}"
    # For webhook handlers, sending 200 OK even on internal processing errors
    # is often desired to acknowledge receipt and prevent re-attempts from sender.
    # Handle the error internally.
    status 200
    body 'OK (processed with internal error)'
  end
end
# --- Helper Function (simulating PHP's consultar_por_ext_ref) ---
# This is a synchronous function for simplicity, but in a real app,
# it might involve network requests or database calls that could be async.
def consultar_por_ext_ref(ext_ref)
  puts "Consulting info for external_reference: #{ext_ref}"
  # Implement your actual logic here (e.g., call TusFacturasAPP API, update database)
  # Example:
  # some_api_client.fetch_data(ext_ref)
end
Información sobre Webhooks: 
Para una comprensión completa de cómo integrar y utilizar el webhook, consultá la documentación detallada desde aquí.
TusFacturasAPP es un software de facturación y un software de gestión diseñado para empresas que facturen en Argentina. Conoce más de TusFacturasAPP.
¿Aún te quedan dudas? ¡Contactános!
En caso que requieras asistencia o tengas alguna duda relacionada con tu plan API DEV, envíanos un mensaje a [email protected] o contactanos por el chat que tenemos disponible en la web www.tusfacturas.app.
Last updated
