NAV
python shell csharp ruby javascript java

Bienvenido a la API de Fingo 🚀

En Fingo, nos encanta simplificar las finanzas digitales, y nuestra API no es la excepción. Diseñada con los principios de REST, nuestra API te permite acceder a todos nuestros recursos de forma sencilla y predecible.

🔗 Organización intuitiva: Las URLs están orientadas a recursos, lo que facilita su uso.

📄 Compatibilidad JSON: Tanto las solicitudes como las respuestas se manejan en formato JSON.

Estándares garantizados: Utilizamos códigos de respuesta HTTP estándar, métodos HTTP comunes y autenticación robusta para garantizar una experiencia segura y consistente.

Sin estado (stateless): Cada solicitud es independiente, lo que significa que puedes confiar en que la API responderá correctamente siempre que proporciones la información necesaria en cada llamada.

Nuestra API es tu puerta de entrada para aprovechar al máximo las herramientas de Fingo. ¡Estamos aquí para ayudarte a innovar en el mundo financiero digital!

Autenticación

require 'httparty'

headers = {
  'Authorization' => 'Api-Key INSERT_KEY'
}

response = HTTParty.get('https://api.fingo.cl/v1/', headers: headers)
import requests

headers = {
  'Authorization': 'Api-Key INSERT_KEY'
}

response = requests.get('https://api.fingo.cl/v1/', headers=headers)
# With shell, you can just pass the correct header with each request
curl "https://api.fingo.cl/v1/" \
  -H "Authorization: Api-Key INSERT_KEY"
const fetch = require("node-fetch");

const headers = {
  Authorization: "Api-Key INSERT_KEY",
};

const response = await fetch("https://api.fingo.cl/v1/", { headers });
using System;
using System.Net.Http;
using System.Net.Http.Headers;

class Program
{
    static async System.Threading.Tasks.Task Main(string[] args)
    {
        using var client = new HttpClient();
        client.BaseAddress = new Uri("https://api.fingo.cl/v1/");

        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Api-Key", "INSERT_KEY");

        HttpResponseMessage response = await client.GetAsync("invoices");
        string responseBody = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseBody);
    }
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class AuthExample {
    public static void main(String[] args) {
        String url = "https://api.fingo.cl/v1/";
        String apiKey = "INSERT_KEY";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", "Api-Key " + apiKey)
                .GET()
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Todas las transacciones tienen que incluir un API Key entregado por Fingo en el header.

Para autorizar pueden usar el siguiente código.

Recursos

A continuación se listan los recursos disponibles en la API de Fingo.

Errores

Fingo Widgets

Widget de enrolamiento

Este widget permite a usuarios participar del flujo de enrolamiento del SII a través de Fingo.

Arquitectura y flujo

  1. En su backend, generar el enrollment-token con el payload correspondiente y enviarlo a tu frontend.
  2. En tu frontend, al momento de cargar el iframe mandar un mensaje a través de la API postMessage.
  3. Una vez que el usuario termine de subir sus credenciales, el widget se cerrará. El flujo termina cuando el suben las credenciales correctamente o cuando el usuario quiera salir del intento de enrolamiento cerrando el widget prematuramente.

Ejemplo del flujo

⚠️ Precaución: Después de la creación del enrollment-token el flujo de uso que se muestra en el diagrama está simplificado. El flujo real de una aplicación puede cambiar radicalmente, pero este ejemplo simplificado puede ser de gran ayuda para entender las interacciones entre las distintas entidades.

Enrollment Widget Flow

Implementación

Crear JWT

const jwt = require("jsonwebtoken");
const payload = {
  company: {
    rut: "7654321-1",
    name: "Ejemplo S.A.",
    client_type: 0
  },
  user: {
    email: "usuario@example.com",
    rut: "12345678-9",
    phone_number: "+56912345678",
    first_name: "Test",
    last_name: "Apellido",
  },
};
const token = jwt.sign(payload, process.env.FINGO_SECRET_KEY);
console.log(token);
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
import jwt
import os

payload = {
  "company": {
    "rut": "7654321-1",
    "name": "Ejemplo S.A.",
    "client_type": 0
  },
  "user": {
    "email": "usuario@example.com",
    "rut": "12345678-9",
    "phone_number": "+56912345678",
    "first_name": "Test",
    "last_name": "Apellido",
  },
}

token = jwt.encode(payload, os.getenv("FINGO_SECRET_KEY"), algorithm="HS256")
print(token)
require 'jwt'
require 'dotenv/load'

payload = {
  company: {
    rut: "7654321-1",
    name: "Ejemplo S.A.",
    client_type: 0
  },
  user: {
    email: "usuario@example.com",
    rut: "12345678-9",
    phone_number: "+56912345678",
    first_name: "Test",
    last_name: "Apellido"
  }
}

token = JWT.encode(payload, ENV["FINGO_SECRET_KEY"], 'HS256')
puts token

Para la autenticación se usan JWT, ya que tienen beneficios como el firmado y cifrado de la información, junto con que previene manipulaciones maliciosas externas.

Para generar el token, Fingo proporcionará una clave secreta. Al costado, se muestra un ejemplo de la creación de un JWT y del payload requerido.

company:

user:

Implementación del iframe con JWT creado

El tag HTML <iframe> te permite embeber un documento externo en tu página web, permitiendo así cargar diferentes aplicaciones sin dejar tu página. En esta guía te explicaré cómo usar iframes en tu aplicación web y en particular cómo implementar el widget de enrolamiento y comunicarte con el a través de la API postMessage.

Embeber un iframe

<div>
  <!-- Other web application content -->
  <iframe src="https://your-iframe-url.com" title="Your Iframe"></iframe>
</div>

Para embeber un iframe en tu aplicación web, usas el tag HTML <iframe> en tu código.

Reemplaza https://your-iframe-url.com con el link de prueba entregado anteriormente. Esto cargará la URL en específico del widget de enrolamiento.

Javascript vs HTML

<div id="iframe-container"></div>
<script>
  const iframe = document.createElement("iframe");
  iframe.src = "https://www.ejemplo.com";
  iframe.width = "100%";
  iframe.height = "600";

  const container = document.getElementById("iframe-container");
  container.appendChild(iframe);
</script>

En este ejemplo, el iFrame se implementa utilizando JavaScript para cargar la página web que se desea incrustar. Esto permite una mayor personalización y seguridad en la implementación:

Pros: - Mayor personalización y flexibilidad en la implementación del iFrame. - Mayor seguridad al cargar páginas externas a través de JavaScript.

Comunicación bidireccional con el iframe

El widget utiliza la API postMessage para establecer una comunicación bidireccional segura. Para garantizar una inicialización correcta en todos los navegadores es necesario esperar a que el widget esté listo antes de enviar el token de autenticación.

let pendingLogin = null;
let isWidgetReady = false;

function handleMessage(event) {
  const expectedOrigin = "https://your-iframe-url.com";
  if (event.origin !== expectedOrigin) {
    console.warn("Mensaje recibido de origen no autorizado:", event.origin);
    return;
  }

  if (event.data?.type === "WIDGET_READY") {
    isWidgetReady = true;

    if (pendingLogin) {
      sendMessageToIframe(pendingLogin);
      pendingLogin = null;
      isWidgetReady = false;
    }
  }
}

function sendMessageToIframe(message) {
  const iframe = document.querySelector("iframe");
  iframe.contentWindow.postMessage(message, "https://your-iframe-url.com");
}

function handleIframeLoad() {
  const loginMessage = {
    type: "LOGIN",
    data: { token: "your-auth-token" }
  };

  if (isWidgetReady) {
    sendMessageToIframe(loginMessage);
    isWidgetReady = false;
  } else {
    pendingLogin = loginMessage;
  }
}

// Configurar los event listeners
window.addEventListener("message", handleMessage);
const iframe = document.querySelector("iframe");
iframe.addEventListener("load", handleIframeLoad);

// Limpiar los event listeners cuando ya no sean necesarios
function cleanup() {
  window.removeEventListener("message", handleMessage);
  iframe.removeEventListener("load", handleIframeLoad);
}

Cerrar o destruir el iframe

// Enviar mensaje de cierre de iframe
const iframe = document.querySelector("iframe");
const message = { type: "LOGOUT" };
iframe.contentWindow.postMessage(message, "https://your-iframe-url.com");

Para cerrar o destruir el iframe y limpiar todas las cookies que este genera (para mantener la sesión activa con Fingo) es necesario que se envíe el siguiente mensaje desde el documento principal:

Configuraciones extra del tag iframe

<iframe
  src="url"
  width="width_value"
  height="height_value"
  frameborder="0"
  allow="permissions"
  sandbox="sandbox_options"
  scrolling="yes|no|auto"
  name="frame_name"
  title="frame_title"
></iframe>

Playground

Para un primer acercamiento con el widget puedes ingresar al siguiente link. En esta página vas al menú Santander, ingresas un token de prueba y haces click en "Abrir iframe".

Cesiones

Objeto Cesión

Información sobre las cesiones de la factura. Contiene la siguiente información:

Ceder Facturas en Batch

Ejemplo de solicitud

import requests

url = "https://api.fingo.cl/v1/cessions/batch"
headers = {
    "Authorization": "Api-Key YOUR_ACCESS_TOKEN",
    "Content-Type": "application/json"
}

payload = {
    "invoices": [
        {
            "invoice_id": 12345,
            "assignee_rut": "12345678-9",
            "assignee_email": "example@domain.com"
        },
        {
            "invoice_id": 12346,
            "assignee_rut": "98765432-1",
            "assignee_email": "example_2@domain.com"
        }
    ],
    "webhook_url": "https://example.com/webhook"
}

response = requests.post(url, headers=headers, json=payload)
print(response.text)
curl -X POST "https://api.fingo.cl/v1/cessions/batch" -H "Authorization: Api-Key YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"invoices": [{"invoice_id": 12345, "assignee_rut": "12345678-9", "assignee_email": "example@domain.com"}, {"invoice_id": 12346, "assignee_rut": "98765432-1", "assignee_email": "example_2@domain.com"}], "webhook_url": "https://example.com/webhook"}'
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

class Program
{
    static async Task Main()
    {
        using var client = new HttpClient();
        var url = "https://api.fingo.cl/v1/cessions/batch";

        var payload = new
        {
            invoices = new[]
            {
                new { 
                    invoice_id = 12345,
                    assignee_rut = "12345678-9",
                    assignee_email = "example@domain.com"
                },
                new { 
                    invoice_id = 12346,
                    assignee_rut = "98765432-1",
                    assignee_email = "example_2@domain.com"
                }
            },
            webhook_url = "https://example.com/webhook"
        };

        client.DefaultRequestHeaders.Add("Authorization", "Api-Key YOUR_ACCESS_TOKEN");

        var jsonContent = JsonConvert.SerializeObject(payload);
        var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

        try
        {
            var response = await client.PostAsync(url, content);
            response.EnsureSuccessStatusCode();
            var result = await response.Content.ReadAsStringAsync();
            Console.WriteLine(result);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}
require 'net/http'
require 'uri'
require 'json'

uri = URI('https://api.fingo.cl/v1/cessions/batch')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Api-Key YOUR_ACCESS_TOKEN'
request['Content-Type'] = 'application/json'

payload = {
  invoices: [
    {
      invoice_id: 12345,
      assignee_rut: '12345678-9',
      assignee_email: 'example@domain.com'
    },
    {
      invoice_id: 12346,
      assignee_rut: '98765432-1',
      assignee_email: 'example_2@domain.com'
    }
  ],
  webhook_url: 'https://example.com/webhook'
}

request.body = payload.to_json

begin
  response = http.request(request)
  puts response.body
rescue StandardError => e
  puts "Error making request: #{e.message}"
end
const batchCessions = async () => {
  const url = 'https://api.fingo.cl/v1/cessions/batch';

  const payload = {
    invoices: [
      {
        invoice_id: 12345,
        assignee_rut: '12345678-9',
        assignee_email: 'example@domain.com'
      },
      {
        invoice_id: 12346,
        assignee_rut: '98765432-1',
        assignee_email: 'example_2@domain.com'
      }
    ],
    webhook_url: 'https://example.com/webhook'
  };

  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Authorization': 'Api-Key YOUR_ACCESS_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    console.log(data);
    return data;

  } catch (error) {
    console.error('Error making batch cessions:', error);
    throw error;
  }
};

batchCessions()
  .then(data => console.log('Batch cessions successful:', data))
  .catch(error => console.error('Failed to make batch cessions:', error));
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class BatchCessionExample {
    public static void main(String[] args) {
        String url = "https://api.fingo.cl/v1/cessions/batch";
        String apiKey = "YOUR_ACCESS_TOKEN";
        String payload = "{" +
            "\"invoices\": [" +
                "{" +
                    "\"invoice_id\": 12345," +
                    "\"assignee_rut\": \"12345678-9\"," +
                    "\"assignee_email\": \"example@domain.com\"" +
                "}," +
                "{" +
                    "\"invoice_id\": 12346," +
                    "\"assignee_rut\": \"98765432-1\"," +
                    "\"assignee_email\": \"example_2@domain.com\"" +
                "}" +
            "]," +
            "\"webhook_url\": \"https://example.com/webhook\"" +
            "}";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", "Api-Key " + apiKey)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(payload))
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Ejemplos de respuesta

Caso Exitoso (202 Accepted)

{
  "request_id": "b3e9f3f9-8d7a-4b6c-9b1a-3e7f2d5c8a1b",
  "status": "accepted",
  "message": "Batch cession request received. Results will be sent to the webhook URL."
}

Error (400 Bad Request)

{
    "status": "error",
    "message": "Invalid request payload",
    "errors": {
        "webhook_url": ["This field is required."]
    }
}

Este endpoint permite ceder facturas de forma masiva, asumiendo que la empresa tiene configurada la cesión de facturas.

La respuesta se entregará a través de un webhook, el cual se debe definir en el momento de la solicitud.

URL: /cessions/batch

Método: POST

Parámetros requeridos en el body

Respuesta

La API responde de forma inmediata confirmando la recepción del lote. El resultado de cada cesión individual se enviará de forma asíncrona a la webhook_url proporcionada.

Respuestas del Webhook

La API envía respuestas individuales a través del webhook definido. Cada respuesta contiene el resultado de la cesión para una factura específica.

Ejemplos de respuesta del Webhook

Ejemplo de cesión exitosa

{
  "request_id": "b3e9f3f9-8d7a-4b6c-9b1a-3e7f2d5c8a1b",
  "invoice_id": 12345,
  "status": "success",
  "message": "Assignment completed successfully",
  "cession": {
    "pk": 123,
    "transferor_mail": "current_owner@domain.com",
    "assignee_mail": "example@domain.com",
    "cession_date": "2022-05-11T19:24:00Z",
    "transferor_rut": "11111111-1",
    "assignee_rut": "12345678-9"
  }
}

Ejemplo de cesión con error

{
  "request_id": "b3e9f3f9-8d7a-4b6c-9b1a-3e7f2d5c8a1b",
  "invoice_id": 12346,
  "status": "error", 
  "message": "Cession rejected by SII",
  "details": "Anotacion de Cesion Rechazada, Documento Invalido"
}

Formato de las respuestas del Webhook

Documentos

Los documentos son archivos que se pueden asociar a empresas. Estos pueden incluir CTEs, TGRs, y otros documentos de empresas.

Las siguientes secciones detallan los diferentes tipos de documentos de empresas que se pueden manejar a través de nuestra API y sus respectivos endpoints.

Obtención CTE

Para solicitar la Carpeta Tributaria Electrónica (CTE) usar el siguiente código:

require 'httparty'

base_url = "https://api.fingo.cl/v1"
rut = "123456789"
api_key = "YOUR_ACCESS_TOKEN"

response = HTTParty.get(
  "#{base_url}/cte/#{rut}", 
  headers: { "Authorization" => "Api-Key #{api_key}" }
)

puts response.body
import requests

base_url = "https://api.fingo.cl/v1"
rut = "123456789"
api_key = "YOUR_ACCESS_TOKEN"

headers = {
    "Authorization": f"Api-Key {api_key}"
}

response = requests.get(f"{base_url}/cte/{rut}", headers=headers)
print(response.content)
BASE_URL="https://api.fingo.cl/v1"
RUT="123456789"
API_KEY="YOUR_ACCESS_TOKEN"

# Obtener archivo base 64 cte
curl -X GET "${BASE_URL}/cte/${RUT}" \
     -H "Authorization: Api-Key ${API_KEY}"
const fetch = require("node-fetch");

const baseUrl = "https://api.fingo.cl/v1";
const rut = "123456789";
const apiKey = "YOUR_ACCESS_TOKEN";

const headers = {
  Authorization: `Api-Key ${apiKey}`,
};

fetch(`${baseUrl}/cte/${rut}`, { headers })
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.error(error));
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

public static class Program
{
    public static async Task Main(string[] args)
    {
        const string baseUrl = "https://api.fingo.cl/v1";
        const string rut = "123456789";
        const string apiKey = "YOUR_ACCESS_TOKEN";

        var client = new HttpClient();
        client.BaseAddress = new Uri(baseUrl);
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Api-Key", apiKey);

        var response = await client.GetAsync($"cte/{rut}");
        var responseContent = await response.Content.ReadAsStringAsync();

        Console.WriteLine(responseContent);
    }
}

Ejemplo de respuesta

{
  "base64_file": "JVBERi0xLjQKJeLjz9MKNCAwIG9iago8PC9UeXBlL1hPYmplY3QvTGFu\nZyhKL0QxT1MpL1N0cnVjdFRyZWVSb290..."
}

Este endpoint te permite obtener la Carpeta Tributaria Electrónica

URL: /cte/{rut}

Método: GET

Parámetros de consulta

Obtención TGR

Para solicitar el certificado de deuda emitido por la Tesorería General de la República (TGR) usar el siguiente código:

require 'httparty'

base_url = "https://api.fingo.cl/v1"
rut = "123456789"
api_key = "YOUR_ACCESS_TOKEN"

response = HTTParty.get(
  "#{base_url}/tgr/#{rut}", 
  headers: { "Authorization" => "Api-Key #{api_key}" }
)

puts response.body
import requests

base_url = "https://api.fingo.cl/v1"
rut = "123456789"
api_key = "YOUR_ACCESS_TOKEN"

headers = {
    "Authorization": f"Api-Key {api_key}"
}

response = requests.get(f"{base_url}/tgr/{rut}", headers=headers)
print(response.content)
BASE_URL="https://api.fingo.cl/v1"
RUT="123456789"
API_KEY="YOUR_ACCESS_TOKEN"

curl -X GET "${BASE_URL}/tgr/${RUT}" \
     -H "Authorization: Api-Key ${API_KEY}"
const fetch = require("node-fetch");

const baseUrl = "https://api.fingo.cl/v1";
const rut = "123456789";
const apiKey = "YOUR_ACCESS_TOKEN";

const headers = {
  Authorization: `Api-Key ${apiKey}`,
};

fetch(`${baseUrl}/tgr/${rut}`, { headers })
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.error(error));
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

public static class Program
{
    public static async Task Main(string[] args)
    {
        const string baseUrl = "https://api.fingo.cl/v1";
        const string rut = "123456789";
        const string apiKey = "YOUR_ACCESS_TOKEN";

        var client = new HttpClient();
        client.BaseAddress = new Uri(baseUrl);
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Api-Key", apiKey);

        var response = await client.GetAsync($"tgr/{rut}");
        var responseContent = await response.Content.ReadAsStringAsync();

        Console.WriteLine(responseContent);
    }
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class TGRExample {
    public static void main(String[] args) {
        final String baseUrl = "https://api.fingo.cl/v1";
        final String rut = "123456789";
        final String apiKey = "YOUR_ACCESS_TOKEN";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl + "/tgr/" + rut))
                .header("Authorization", "Api-Key " + apiKey)
                .GET()
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Ejemplo de respuesta

{
  "base64_file": "JVBERi0xLjQKJeLjz9MKNCAwIG9iago8PC9UeXBlL1hPYmplY3QvTGFu\nZyhKL0QxT1MpL1N0cnVjdFRyZWVSb290..."
}

Este endpoint te permite obtener un archivo base 64 correspondiente al certificado de deuda pendiente con la Tesorería General de la República.

URL: /tgr/{rut}

Método: GET

Parámetros de consulta

Empresas

Objeto Empresa

Representa la información de la empresa

Crear o Actualizar Empresa

Ejemplo de solicitud (Estándar o Encriptada)

require 'httparty'
require 'json'
require 'base64'

# Configuration
base_url = "https://api.fingo.cl/v1"
api_key = "YOUR_ACCESS_TOKEN"
use_encryption = true

# Data
company_rut = "12345678-9"
sii_password = "secretpassword"
company_email = "empresa@example.com"

# Prepare Payload
if use_encryption
  # OPTION A: Encrypted (Recommended)
  # Only password is encrypted, wrapped in JSON { taxKey: "..." }
  payload_to_encrypt = { taxKey: sii_password }

  # Pseudo-code: Encrypt JSON with AES-256
  # encrypted_bytes = aes256_encrypt(payload_to_encrypt.to_json, public_key)
  # encrypted_string = Base64.strict_encode64(encrypted_bytes)
  encrypted_string = "BASE64_ENCRYPTED_STRING..."

  body_data = {
    rut: company_rut,
    email: company_email,
    encrypted_password: encrypted_string
  }
else
  # OPTION B: Standard
  body_data = {
    rut: company_rut,
    password: sii_password,
    email: company_email
  }
end

# Send Request
response = HTTParty.post(
  "#{base_url}/companies",
  body: body_data.to_json,
  headers: {
    "Authorization" => "Api-Key #{api_key}",
    "Content-Type" => "application/json"
  }
)

puts response.body
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Text;

public static class Program
{
    public static async Task Main(string[] args)
    {
        const string baseUrl = "https://api.fingo.cl/v1";
        const string apiKey = "YOUR_ACCESS_TOKEN";
        bool useEncryption = true;

        // Data
        var rut = "12345678-9";
        var password = "secretpassword";
        var email = "empresa@example.com";

        using var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Api-Key", apiKey);

        object payload;

        // Prepare Payload
        if (useEncryption)
        {
            // OPTION A: Encrypted
            // Only password is encrypted, wrapped in JSON { taxKey: "..." }
            var rawPayload = new { taxKey = password };
            var jsonToEncrypt = JsonConvert.SerializeObject(rawPayload);

            // Pseudo-code: Encrypt
            // var encryptedBytes = Aes256Encrypt(jsonToEncrypt, publicKey);
            // var encryptedString = Convert.ToBase64String(encryptedBytes);
            var encryptedString = "BASE64_ENCRYPTED_STRING...";

            payload = new {
                rut = rut,
                email = email,
                encrypted_password = encryptedString
            };
        }
        else
        {
            // OPTION B: Standard
            payload = new {
                rut = rut,
                password = password,
                email = email
            };
        }

        var jsonContent = JsonConvert.SerializeObject(payload);
        var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

        // Send Request
        try
        {
            var response = await client.PostAsync($"{baseUrl}/companies", content);
            var responseContent = await response.Content.ReadAsStringAsync();
            Console.WriteLine(responseContent);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}
import requests
import json
import base64

# Configuration
base_url = "https://api.fingo.cl/v1"
api_key = "YOUR_ACCESS_TOKEN"
use_encryption = True

headers = {
    "Authorization": f"Api-Key {api_key}",
    "Content-Type": "application/json"
}

# Data
raw_data = {
    "rut": "12345678-9",
    "password": "secretpassword",
    "email": "empresa@example.com"
}

# Prepare Payload
if use_encryption:
    # OPTION A: Encrypted (Recommended)
    # Only password is encrypted, wrapped in JSON { "taxKey": "..." }
    payload_to_encrypt = {"taxKey": raw_data["password"]}

    # Pseudo-code: Encrypt JSON with AES-256
    # encrypted_bytes = aes256_encrypt(json.dumps(payload_to_encrypt), public_key)
    # encrypted_string = base64.b64encode(encrypted_bytes).decode('utf-8')
    encrypted_string = "BASE64_ENCRYPTED_STRING..."

    payload = {
        "rut": raw_data["rut"],
        "email": raw_data["email"],
        "encrypted_password": encrypted_string
    }
else:
    # OPTION B: Standard
    payload = raw_data

# Send Request
response = requests.post(f"{base_url}/companies", headers=headers, json=payload)
print(response.text)
# Define variables
BASE_URL="https://api.fingo.cl/v1"
API_KEY="YOUR_ACCESS_TOKEN"
USE_ENCRYPTION=true

# Data
RUT="12345678-9"
PASS="secretpassword"
EMAIL="empresa@example.com"

if [ "$USE_ENCRYPTION" = true ]; then
  # OPTION A: Encrypted
  # Only password is encrypted, wrapped in JSON { "taxKey": "..." }
  # Pseudo-command: Encrypt JSON string
  # PAYLOAD_JSON="{\"taxKey\": \"$PASS\"}"
  # ENCRYPTED_STRING=$(echo "$PAYLOAD_JSON" | encrypt_tool --key public_key)
  ENCRYPTED_STRING="BASE64_ENCRYPTED_STRING..."

  DATA="{\"rut\": \"$RUT\", \"email\": \"$EMAIL\", \"encrypted_password\": \"${ENCRYPTED_STRING}\"}"
else
  # OPTION B: Standard
  DATA="{\"rut\": \"$RUT\", \"password\": \"$PASS\", \"email\": \"$EMAIL\"}"
fi

# Send Request
curl -X POST "${BASE_URL}/companies" \
     -H "Authorization: Api-Key ${API_KEY}" \
     -H "Content-Type: application/json" \
     -d "$DATA"
const fetch = require("node-fetch");

const baseUrl = "https://api.fingo.cl/v1";
const apiKey = "YOUR_ACCESS_TOKEN";
const useEncryption = true;

const headers = {
  Authorization: `Api-Key ${apiKey}`,
  "Content-Type": "application/json",
};

// Data
const rawData = {
  rut: "12345678-9",
  password: "secretpassword",
  email: "empresa@example.com",
};

let body;

// Prepare Payload
if (useEncryption) {
  // OPTION A: Encrypted
  // Only password is encrypted, wrapped in JSON { taxKey: "..." }
  const payloadToEncrypt = { taxKey: rawData.password };

  // Pseudo-code: Encrypt
  // const encryptedBytes = aes256Encrypt(JSON.stringify(payloadToEncrypt), publicKey);
  // const encryptedString = encryptedBytes.toString('base64');
  const encryptedString = "BASE64_ENCRYPTED_STRING...";

  body = JSON.stringify({
    rut: rawData.rut,
    email: rawData.email,
    encrypted_password: encryptedString
  });
} else {
  // OPTION B: Standard
  body = JSON.stringify(rawData);
}

// Send Request
fetch(`${baseUrl}/companies`, {
  method: "POST",
  headers: headers,
  body: body,
})
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.error(error));
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.io.IOException;

public class CreateCompanyExample {
    public static void main(String[] args) {
        final String baseUrl = "https://api.fingo.cl/v1";
        final String apiKey = "YOUR_ACCESS_TOKEN";
        final boolean useEncryption = true;

        // Data
        String rut = "12345678-9";
        String password = "secretpassword";
        String email = "empresa@example.com";

        String jsonBody;

        // Prepare Payload
        if (useEncryption) {
            // OPTION A: Encrypted
            // Only password is encrypted, wrapped in JSON { "taxKey": "..." }
            String rawJson = String.format("{\"taxKey\": \"%s\"}", password);

            // Pseudo-code: Encrypt
            // byte[] encryptedBytes = aes256Encrypt(rawJson, publicKey);
            // String encryptedString = Base64.getEncoder().encodeToString(encryptedBytes);
            String encryptedString = "BASE64_ENCRYPTED_STRING...";

            jsonBody = String.format(
                "{\"rut\": \"%s\", \"email\": \"%s\", \"encrypted_password\": \"%s\"}",
                rut, email, encryptedString
            );
        } else {
            // OPTION B: Standard
            jsonBody = String.format(
                "{\"rut\": \"%s\", \"password\": \"%s\", \"email\": \"%s\"}",
                rut, password, email
            );
        }

        try {
            HttpClient client = HttpClient.newBuilder().build();

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl + "/companies"))
                .header("Authorization", "Api-Key " + apiKey)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Ejemplo de respuesta

{
  "id": 1,
  "rut": "12345678-9",
  "created_at": "2022-03-21T14:35:00Z",
  "updated_at": "2022-03-21T14:35:00Z"
}

Este endpoint permite registrar una nueva empresa en Fingo o actualizar las credenciales de una existente. Soporta dos métodos de envío:

  1. Estándar: Credenciales enviadas en texto plano (vía HTTPS).
  2. Encriptado: Credenciales encriptadas con AES-256.

URL: /companies

Método: POST

Este endpoint tiene comportamiento de "Upsert":

Parámetros (Modo Estándar)

Parámetros (Modo Encriptado)

Obtener Empresa por RUT

Ejemplo de solicitud

require 'httparty'

base_url = "https://api.fingo.cl/v1"
api_key = "YOUR_ACCESS_TOKEN"
rut = "76086427-7"

response = HTTParty.get(
  "#{base_url}/companies",
  query: { rut: rut },
  headers: { "Authorization" => "Api-Key #{api_key}" }
)

puts response.body
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

public static class Program
{
    public static async Task Main(string[] args)
    {
        const string baseUrl = "https://api.fingo.cl/v1";
        const string apiKey = "YOUR_ACCESS_TOKEN";
        const string rut = "76086427-7";

        using var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Api-Key", apiKey);

        var response = await client.GetAsync($"{baseUrl}/companies?rut={rut}");
        var content = await response.Content.ReadAsStringAsync();
        Console.WriteLine(content);
    }
}
import requests

base_url = "https://api.fingo.cl/v1"
api_key = "YOUR_ACCESS_TOKEN"

headers = {"Authorization": f"Api-Key {api_key}"}
params = {"rut": "76086427-7"}

response = requests.get(f"{base_url}/companies", headers=headers, params=params)
print(response.text)
BASE_URL="https://api.fingo.cl/v1"
API_KEY="YOUR_ACCESS_TOKEN"
RUT="76086427-7"

curl -X GET "${BASE_URL}/companies?rut=${RUT}" \
     -H "Authorization: Api-Key ${API_KEY}"
const fetch = require("node-fetch");

const baseUrl = "https://api.fingo.cl/v1";
const apiKey = "YOUR_ACCESS_TOKEN";
const rut = "76086427-7";

fetch(`${baseUrl}/companies?rut=${encodeURIComponent(rut)}`, {
  method: "GET",
  headers: { Authorization: `Api-Key ${apiKey}` },
})
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.error(error));
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.io.IOException;

public class LookupCompanyExample {
    public static void main(String[] args) {
        final String baseUrl = "https://api.fingo.cl/v1";
        final String apiKey = "YOUR_ACCESS_TOKEN";
        final String rut = "76086427-7";

        try {
            HttpClient client = HttpClient.newBuilder().build();

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl + "/companies?rut=" + rut))
                .header("Authorization", "Api-Key " + apiKey)
                .GET()
                .build();

            HttpResponse<String> response =
                client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Ejemplo de respuesta

{
  "id": 12345,
  "rut": "76086427-7",
  "created_at": "2023-05-10T14:22:00Z",
  "updated_at": "2024-01-15T09:10:00Z"
}

Códigos de respuesta

200 OK          → Empresa encontrada o creada exitosamente.
400 Bad Request → RUT inválido o faltante.
403 Forbidden   → API Key inválida o no encontrada.

Errores de validación

rut faltante

{"rut": ["This field is required."]}

Formato de RUT inválido

{"rut": ["Invalid national identifier format"]}

Dígito verificador inválido

{"rut": ["Invalid verification digit"]}

Busca una empresa por RUT.

URL: /companies?rut=<RUT>

Método: GET

Este endpoint es idempotente: llamarlo múltiples veces con el mismo RUT siempre retorna la misma empresa.

Nota: Este endpoint no crea credenciales SII. Para registrar una empresa con credenciales, utiliza POST /companies.

Parámetros de consulta

Respuesta

Invalidar Empresa

Para invalidar una credencial puedes usar el siguiente código:

require 'httparty'

base_url = "https://api.fingo.cl/v1"
rut = "123456789"
api_key = "YOUR_ACCESS_TOKEN"

response = HTTParty.delete(
  "#{base_url}/companies/#{rut}",
  headers: { "Authorization" => "Api-Key #{api_key}" }
)

puts response.body
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

public static class Program
{
    public static async Task Main(string[] args)
    {
        const string baseUrl = "https://api.fingo.cl/v1";
        const string rut = "123456789";
        const string apiKey = "YOUR_ACCESS_TOKEN";

        var client = new HttpClient();
        client.BaseAddress = new Uri(baseUrl);
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Api-Key", apiKey);

        var response = await client.DeleteAsync($"companies/{rut}");
        var content = await response.Content.ReadAsStringAsync();

        Console.WriteLine(content);
    }
}
import requests

base_url = "https://api.fingo.cl/v1"
rut = "123456789"
api_key = "YOUR_ACCESS_TOKEN"

headers = {
    "Authorization": f"Api-Key {api_key}"
}

response = requests.delete(f"{base_url}/companies/{rut}", headers=headers)
print(response.content)
# Define variables
BASE_URL="https://api.fingo.cl/v1"
RUT="123456789"
API_KEY="YOUR_ACCESS_TOKEN"

# Eliminar una empresa
curl -X DELETE "${BASE_URL}/companies/${RUT}" \
     -H "Authorization: Api-Key ${API_KEY}"
const fetch = require("node-fetch");

const baseUrl = "https://api.fingo.cl/v1";
const rut = "123456789";
const apiKey = "YOUR_ACCESS_TOKEN";

const headers = {
  Authorization: `Api-Key ${apiKey}`,
};

fetch(`${baseUrl}/companies/${rut}`, {
  method: "DELETE",
  headers: headers,
})
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.error(error));

Ejemplo de respuesta

{
  "id": 1,
  "rut": "12345678-9",
  "message": "La empresa con RUT 12345678-9 ha sido eliminada exitosamente"
}

Este endpoint te permite invalidar una credencial de una empresa, entregando el RUT de la empresa.

URL: /companies/{RUT}

Método: DELETE

Parámetros en la URL

RUT (requerido): RUT de la empresa a eliminar.

Validar Certificado Digital *

Ejemplo de solicitud

import requests

url = "https://api.fingo.cl/v1/companies/{company_id}/digital_certificate"
headers = {
    "Authorization": "Api-Key YOUR_ACCESS_TOKEN"
}

response = requests.get(url, headers=headers)
print(response.text)
curl -X GET "https://api.fingo.cl/v1/companies/{company_id}/digital_certificate" -H "Authorization: Api-Key YOUR_ACCESS_TOKEN"
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var client = new HttpClient();
        var url = "https://api.fingo.cl/v1/companies/{company_id}/digital_certificate";

        client.DefaultRequestHeaders.Add("Authorization", "Api-Key YOUR_ACCESS_TOKEN");

        try
        {
            var response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode();
            var result = await response.Content.ReadAsStringAsync();
            Console.WriteLine(result);
        }
        catch (HttpRequestException e)
        {
            Console.WriteLine($"Error making request: {e.Message}");
        }
    }
}
require 'net/http'
require 'uri'

uri = URI('https://api.fingo.cl/v1/companies/{company_id}/digital_certificate')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Api-Key YOUR_ACCESS_TOKEN'

begin
  response = http.request(request)
  puts response.body
rescue StandardError => e
  puts "Error making request: #{e.message}"
end
const validateDigitalCertificate = async () => {
  const url = 'https://api.fingo.cl/v1/companies/{company_id}/digital_certificate';

  try {
    const response = await fetch(url, {
      headers: {
        'Authorization': 'Api-Key YOUR_ACCESS_TOKEN'
      }
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    console.log(data);
    return data;

  } catch (error) {
    console.error('Error validating digital certificate:', error);
    throw error;
  }
};

validateDigitalCertificate()
  .then(data => console.log('Certificate validation:', data))
  .catch(error => console.error('Validation failed:', error));
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ValidateDigitalCertificateExample {
    public static void main(String[] args) {
        String url = "https://api.fingo.cl/v1/companies/{company_id}/digital_certificate";
        String apiKey = "YOUR_ACCESS_TOKEN";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", "Api-Key " + apiKey)
                .GET()
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            System.err.println("Error validating digital certificate: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Ejemplo de respuesta

# Cargado correctamente
{
  "status": 1,
  "message": "Digital certificate uploaded successfully",
  "expiration_date": "2030-01-01",
  "uploaded_at": "2023-08-15"
},
# Pendiente, nunca ha sido cargado
{
  "status": 0,
  "message": "Digital certificate not uploaded",
  "expiration_date": null,
  "uploaded_at": null
},
# Cargado correctamente, requiere contraseña
{
  "status": 2,
  "message": "Digital certificate uploaded successfully, requires password",
  "expiration_date": "2030-01-01",
  "uploaded_at": "2023-08-15"
},
# Cargado y posteriormente invalidado o expirado
{
  "status": 3,
  "message": "Digital certificate expired",
  "expiration_date": "2020-01-01",
  "uploaded_at": "2019-12-15"
}

Este endpoint permite validar el certificado digital de la empresa.

URL: /companies/{company_id}/digital_certificate

Método: GET

Status

Cargar Certificado Digital

Este endpoint permite cargar el certificado digital (.pfx o .p12) de la empresa. Soporta dos métodos de envío:

  1. Estándar: Certificado y contraseña enviados en texto plano (vía HTTPS).
  2. Encriptado: Payload encriptado con AES-256 (recomendado para mayor seguridad).

Ejemplo de solicitud (Estándar o Encriptada)

import requests
import base64
import json

# Config
base_url = "https://api.fingo.cl/v1"
company_id = "{company_id}"
api_key = "YOUR_ACCESS_TOKEN"
certificate_path = "certificate.pfx"
certificate_password = "password"
use_encryption = True # Set to False for standard upload

# 1. Read and encode certificate
with open(certificate_path, "rb") as cert_file:
    certificate_base64 = base64.b64encode(cert_file.read()).decode('utf-8')

headers = {
    "Authorization": f"Api-Key {api_key}",
    "Content-Type": "application/json"
}

# 2. Prepare Payload
if use_encryption:
    # OPTION A: Encrypted (Recommended)
    # Using legacy keys 'certi' and 'key' for inner JSON
    payload_to_encrypt = {
        "certi": certificate_base64,
        "key": certificate_password
    }
    # Pseudo-code: Encrypt JSON with AES-256
    # encrypted_bytes = aes256_encrypt(json.dumps(payload_to_encrypt), public_key)
    # encrypted_string = base64.b64encode(encrypted_bytes).decode('utf-8')
    encrypted_string = "BASE64_ENCRYPTED_STRING..."

    payload = {"encrypted_payload": encrypted_string}
else:
    # OPTION B: Standard
    payload = {
        "certificate": certificate_base64,
        "password": certificate_password
    }

# 3. Send Request
response = requests.post(
    f"{base_url}/companies/{company_id}/digital_certificate",
    headers=headers,
    json=payload
)

print(response.text)
# Define variables
BASE_URL="https://api.fingo.cl/v1"
COMPANY_ID="{company_id}"
API_KEY="YOUR_ACCESS_TOKEN"
CERT_PATH="certificate.pfx"
CERT_PASSWORD="password"
USE_ENCRYPTION=true

# Encode certificate in base64
CERT_BASE64=$(base64 -w 0 "$CERT_PATH")

if [ "$USE_ENCRYPTION" = true ]; then
  # OPTION A: Encrypted
  # Using legacy keys 'certi' and 'key' for inner JSON
  # Pseudo-command: Encrypt JSON string
  # PAYLOAD_JSON="{\"certi\": \"${CERT_BASE64}\", \"key\": \"${CERT_PASSWORD}\"}"
  # ENCRYPTED_STRING=$(echo "$PAYLOAD_JSON" | encrypt_tool --key public_key)
  ENCRYPTED_STRING="BASE64_ENCRYPTED_STRING..."

  DATA="{\"encrypted_payload\": \"${ENCRYPTED_STRING}\"}"
else
  # OPTION B: Standard
  DATA="{\"certificate\": \"${CERT_BASE64}\", \"password\": \"${CERT_PASSWORD}\"}"
fi

# Upload
curl -X POST "${BASE_URL}/companies/${COMPANY_ID}/digital_certificate" \
     -H "Authorization: Api-Key ${API_KEY}" \
     -H "Content-Type: application/json" \
     -d "$DATA"
using System;
using System.Net.Http;
using System.IO;
using System.Threading.Tasks;
using System.Text;
using Newtonsoft.Json;

class Program
{
    static async Task Main()
    {
        const string baseUrl = "https://api.fingo.cl/v1";
        const string companyId = "{company_id}";
        const string apiKey = "YOUR_ACCESS_TOKEN";
        const string certificatePath = "certificate.pfx";
        const string certificatePassword = "password";
        bool useEncryption = true;

        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Authorization", $"Api-Key {apiKey}");

        // 1. Read Certificate
        var certificateBytes = File.ReadAllBytes(certificatePath);
        var certificateBase64 = Convert.ToBase64String(certificateBytes);

        object payloadData;

        // 2. Prepare Payload
        if (useEncryption)
        {
            // OPTION A: Encrypted
            // Using legacy keys 'certi' and 'key' for inner JSON
            var rawPayload = new { certi = certificateBase64, key = certificatePassword };
            var jsonToEncrypt = JsonConvert.SerializeObject(rawPayload);

            // Pseudo-code: Encrypt
            // var encryptedBytes = Aes256Encrypt(jsonToEncrypt, publicKey);
            // var encryptedString = Convert.ToBase64String(encryptedBytes);
            var encryptedString = "BASE64_ENCRYPTED_STRING...";

            payloadData = new { encrypted_payload = encryptedString };
        }
        else
        {
            // OPTION B: Standard
            payloadData = new { certificate = certificateBase64, password = certificatePassword };
        }

        var jsonContent = JsonConvert.SerializeObject(payloadData);
        var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

        // 3. Send Request
        try
        {
            var response = await client.PostAsync(
                $"{baseUrl}/companies/{companyId}/digital_certificate",
                content
            );
            var result = await response.Content.ReadAsStringAsync();
            Console.WriteLine(result);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}
require 'rest-client'
require 'base64'
require 'json'

base_url = "https://api.fingo.cl/v1"
company_id = "{company_id}"
api_key = "YOUR_ACCESS_TOKEN"
certificate_path = "certificate.pfx"
certificate_password = "password"
use_encryption = true

# 1. Read Certificate
certificate_base64 = Base64.encode64(File.read(certificate_path)).gsub("\n", '')

# 2. Prepare Payload
if use_encryption
  # OPTION A: Encrypted
  # Using legacy keys 'certi' and 'key' for inner JSON
  payload_to_encrypt = {
    certi: certificate_base64,
    key: certificate_password
  }
  # Pseudo-code: Encrypt
  # encrypted_bytes = aes256_encrypt(payload_to_encrypt.to_json, public_key)
  # encrypted_string = Base64.strict_encode64(encrypted_bytes)
  encrypted_string = "BASE64_ENCRYPTED_STRING..."

  payload = { encrypted_payload: encrypted_string }
else
  # OPTION B: Standard
  payload = {
    certificate: certificate_base64,
    password: certificate_password
  }
end

# 3. Send Request
begin
  response = RestClient.post(
    "#{base_url}/companies/#{company_id}/digital_certificate",
    payload.to_json,
    {
      Authorization: "Api-Key #{api_key}",
      content_type: :json
    }
  )
  puts response.body
rescue RestClient::Exception => e
  puts "Error: #{e.response}"
end
const fs = require("fs");
const fetch = require("node-fetch");

async function uploadCertificate() {
  const baseUrl = "https://api.fingo.cl/v1";
  const companyId = "{company_id}";
  const apiKey = "YOUR_ACCESS_TOKEN";
  const certificatePath = "certificate.pfx";
  const certificatePassword = "password";
  const useEncryption = true;

  // 1. Read Certificate
  const certificateBase64 = fs.readFileSync(certificatePath, { encoding: "base64" });

  const headers = {
    Authorization: `Api-Key ${apiKey}`,
    "Content-Type": "application/json",
  };

  let body;

  // 2. Prepare Payload
  if (useEncryption) {
    // OPTION A: Encrypted
    // Using legacy keys 'certi' and 'key' for inner JSON
    const rawPayload = {
      certi: certificateBase64,
      key: certificatePassword,
    };
    // Pseudo-code: Encrypt
    // const encryptedBytes = aes256Encrypt(JSON.stringify(rawPayload), publicKey);
    // const encryptedString = encryptedBytes.toString('base64');
    const encryptedString = "BASE64_ENCRYPTED_STRING...";

    body = JSON.stringify({ encrypted_payload: encryptedString });
  } else {
    // OPTION B: Standard
    body = JSON.stringify({
      certificate: certificateBase64,
      password: certificatePassword,
    });
  }

  // 3. Send Request
  try {
    const response = await fetch(`${baseUrl}/companies/${companyId}/digital_certificate`, {
      method: "POST",
      headers: headers,
      body: body,
    });

    const data = await response.text();
    console.log(data);
  } catch (error) {
    console.error("Error:", error);
  }
}

uploadCertificate();
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.util.Base64;

public class UploadCertificateExample {
    public static void main(String[] args) {
        final String baseUrl = "https://api.fingo.cl/v1";
        final String companyId = "{company_id}";
        final String apiKey = "YOUR_ACCESS_TOKEN";
        final String certificatePath = "certificate.pfx";
        final String certificatePassword = "password";
        final boolean useEncryption = true;

        try {
            HttpClient client = HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_1_1)
                .build();

            // 1. Read Certificate
            File certificateFile = new File(certificatePath);
            byte[] certificateBytes = Files.readAllBytes(certificateFile.toPath());
            String certificateBase64 = Base64.getEncoder().encodeToString(certificateBytes);

            String jsonBody;

            // 2. Prepare Payload
            if (useEncryption) {
                // OPTION A: Encrypted
                // Using legacy keys 'certi' and 'key' for inner JSON
                String rawPayload = String.format(
                    "{\"certi\": \"%s\", \"key\": \"%s\"}",
                    certificateBase64, certificatePassword
                );

                // Pseudo-code: Encrypt
                // byte[] encryptedBytes = aes256Encrypt(rawPayload, publicKey);
                // String encryptedString = Base64.getEncoder().encodeToString(encryptedBytes);
                String encryptedString = "BASE64_ENCRYPTED_STRING...";

                jsonBody = String.format("{\"encrypted_payload\": \"%s\"}", encryptedString);
            } else {
                // OPTION B: Standard
                jsonBody = String.format(
                    "{\"certificate\": \"%s\", \"password\": \"%s\"}",
                    certificateBase64, certificatePassword
                );
            }

            // 3. Send Request
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl + "/companies/" + companyId + "/digital_certificate"))
                .header("Authorization", "Api-Key " + apiKey)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Ejemplo de respuesta

{
  "status": 1,
  "message": "Digital certificate uploaded successfully",
  "expiration_date": "2030-01-01"
}

URL: /companies/{company_id}/digital_certificate

Método: POST

Parámetros (Modo Estándar)

Parámetros (Modo Encriptado)

Validar Facturador Electrónico *

Ejemplo de solicitud

import requests

url = "https://api.fingo.cl/v1/companies/{company_id}/invoice_provider"
headers = {"Authorization": "Api-Key YOUR_ACCESS_TOKEN"}

response = requests.get(url, headers=headers)
print(response.text)
curl -X GET "https://api.fingo.cl/v1/companies/{company_id}/invoice_provider" -H "Authorization: Api-Key YOUR_ACCESS_TOKEN"
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var client = new HttpClient();
        var url = "https://api.fingo.cl/v1/companies/{company_id}/invoice_provider";

        client.DefaultRequestHeaders.Add("Authorization", "Api-Key YOUR_ACCESS_TOKEN");

        try
        {
            var response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode();
            var result = await response.Content.ReadAsStringAsync();
            Console.WriteLine(result);
        }
        catch (HttpRequestException e)
        {
            Console.WriteLine($"Error making request: {e.Message}");
        }
    }
}
require 'net/http'
require 'uri'

uri = URI('https://api.fingo.cl/v1/companies/{company_id}/invoice_provider')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Api-Key YOUR_ACCESS_TOKEN'

begin
  response = http.request(request)
  puts response.body
rescue StandardError => e
  puts "Error making request: #{e.message}"
end
const validateInvoiceProvider = async () => {
  const url = 'https://api.fingo.cl/v1/companies/{company_id}/invoice_provider';

  try {
    const response = await fetch(url, {
      headers: {
        'Authorization': 'Api-Key YOUR_ACCESS_TOKEN'
      }
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    console.log(data);
    return data;

  } catch (error) {
    console.error('Error validating invoice provider:', error);
    throw error;
  }
};

validateInvoiceProvider()
  .then(data => console.log('Validation result:', data))
  .catch(error => console.error('Validation failed:', error));
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ValidateInvoiceProviderExample {
    public static void main(String[] args) {
        String url = "https://api.fingo.cl/v1/companies/{company_id}/invoice_provider";
        String apiKey = "YOUR_ACCESS_TOKEN";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", "Api-Key " + apiKey)
                .GET()
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            System.err.println("Error validating invoice provider: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Ejemplo de respuesta

# Cargado correctamente
{
  "status": 1,
  "message": "Invoice provider credentials uploaded successfully",
  "invoice_provider": "MI_PYME"
},
# Pendiente, nunca ha sido cargado
{
  "status": 0,
  "message": "Invoice provider credentials not uploaded",
  "invoice_provider": null
},
# Cargado y posteriormente invalidado
{
  "status": 0,
  "message": "Invoice provider credentials invalidated",
  "invoice_provider": null
}

Este endpoint permite validar la credencial del facturador electrónico de la empresa.

URL: /companies/{company_id}/invoice_provider

Método: GET

Status

Posibles facturadores electrónicos

Cargar Facturador Electrónico *

Ejemplo de solicitud

import requests

base_url = "https://api.fingo.cl/v1"
company_id = "{company_id}"
api_key = "YOUR_ACCESS_TOKEN"

headers = {
    "Authorization": f"Api-Key {api_key}"
}

payload = {
    "username": "123456789",
    "password": "password",
    "invoice_provider": "MI_PYME"
}

response = requests.post(
    f"{base_url}/companies/{company_id}/invoice_provider",
    headers=headers,
    json=payload
)

print(response.text)
# Define variables
BASE_URL="https://api.fingo.cl/v1"
COMPANY_ID="{company_id}"
API_KEY="YOUR_ACCESS_TOKEN"

# Upload invoice provider
curl -X POST "${BASE_URL}/companies/${COMPANY_ID}/invoice_provider" \
     -H "Authorization: Api-Key ${API_KEY}" \
     -H "Content-Type: application/json" \
     -d '{
       "username": "123456789",
       "password": "password",
       "invoice_provider": "MI_PYME"
     }'
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

class Program
{
    static async Task Main()
    {
        const string baseUrl = "https://api.fingo.cl/v1";
        const string companyId = "{company_id}";
        const string apiKey = "YOUR_ACCESS_TOKEN";

        var payload = new
        {
            username = "123456789",
            password = "password",
            invoice_provider = "MI_PYME"
        };

        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Authorization", $"Api-Key {apiKey}");

        var jsonContent = JsonConvert.SerializeObject(payload);
        var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

        try
        {
            var response = await client.PostAsync(
                $"{baseUrl}/companies/{companyId}/invoice_provider",
                content
            );
            response.EnsureSuccessStatusCode();
            var result = await response.Content.ReadAsStringAsync();
            Console.WriteLine(result);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}
require 'net/http'
require 'uri'
require 'json'

base_url = "https://api.fingo.cl/v1"
company_id = "{company_id}"
api_key = "YOUR_ACCESS_TOKEN"

uri = URI("#{base_url}/companies/#{company_id}/invoice_provider")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

headers = {
  'Authorization' => "Api-Key #{api_key}",
  'Content-Type' => 'application/json'
}

payload = {
  username: '123456789',
  password: 'password',
  invoice_provider: 'MI_PYME'
}

request = Net::HTTP::Post.new(uri, headers)
request.body = payload.to_json

begin
  response = http.request(request)
  puts response.body
rescue StandardError => e
  puts "Error making request: #{e.message}"
end
const uploadInvoiceProvider = async () => {
  const baseUrl = 'https://api.fingo.cl/v1';
  const companyId = '{company_id}';
  const apiKey = 'YOUR_ACCESS_TOKEN';

  const headers = {
    'Authorization': `Api-Key ${apiKey}`,
    'Content-Type': 'application/json'
  };

  const payload = {
    username: '123456789',
    password: 'password',
    invoice_provider: 'MI_PYME'
  };

  try {
    const response = await fetch(
      `${baseUrl}/companies/${companyId}/invoice_provider`,
      {
        method: 'POST',
        headers: headers,
        body: JSON.stringify(payload)
      }
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    console.log(data);
    return data;

  } catch (error) {
    console.error('Error uploading invoice provider:', error);
    throw error;
  }
};

uploadInvoiceProvider()
  .then(data => console.log('Upload successful:', data))
  .catch(error => console.error('Upload failed:', error));
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class UploadInvoiceProviderExample {
    public static void main(String[] args) {
        final String baseUrl = "https://api.fingo.cl/v1";
        final String companyId = "{company_id}";
        final String apiKey = "YOUR_ACCESS_TOKEN";

        final String payload = "{"
            + "\"username\": \"123456789\","
            + "\"password\": \"password\","
            + "\"invoice_provider\": \"MI_PYME\""
            + "}";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl + "/companies/" + companyId + "/invoice_provider"))
                .header("Authorization", "Api-Key " + apiKey)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(payload))
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            System.err.println("Error uploading invoice provider: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Ejemplo de respuesta

# Cargado correctamente
{
  "status": "success",
  "message": "Invoice provider uploaded successfully",
  "invoice_provider": "MI_PYME"
}

# Credenciales inválidas
{
  "status": "error",
  "message": "Invalid username or password",
  "invoice_provider": "ACEPTA"
}

Este endpoint permite cargar el facturador electrónico de la empresa.

URL: /companies/{company_id}/invoice_provider

Método: POST

Parámetros requeridos en el body

Configuración de Cesión *

Ejemplo de solicitud

import requests

url = "https://api.fingo.cl/v1/companies/{company_id}/cession_configuration"
headers = {"Authorization": "Api-Key YOUR_ACCESS_TOKEN"}

response = requests.post(url, headers=headers, json={"option": 0})
print(response.text)
curl -X POST "https://api.fingo.cl/v1/companies/{company_id}/cession_configuration" -H "Authorization: Api-Key YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"option": 0}'
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

class Program
{
    static async Task Main()
    {
        var url = "https://api.fingo.cl/v1/companies/{company_id}/cession_configuration";

        var payload = new
        {
            option = 0
        };

        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Authorization", "Api-Key YOUR_ACCESS_TOKEN");

        var jsonContent = JsonConvert.SerializeObject(payload);
        var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

        try
        {
            var response = await client.PostAsync(url, content);
            response.EnsureSuccessStatusCode();
            var result = await response.Content.ReadAsStringAsync();
            Console.WriteLine(result);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}
require 'net/http'
require 'uri'
require 'json'

uri = URI('https://api.fingo.cl/v1/companies/{company_id}/cession_configuration')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Api-Key YOUR_ACCESS_TOKEN'
request['Content-Type'] = 'application/json'

payload = {
  option: 0
}

request.body = payload.to_json

begin
  response = http.request(request)
  puts response.body
rescue StandardError => e
  puts "Error making request: #{e.message}"
end
const configureCession = async () => {
  const url = 'https://api.fingo.cl/v1/companies/{company_id}/cession_configuration';

  const payload = {
    option: 0
  };

  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Authorization': 'Api-Key YOUR_ACCESS_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    console.log(data);
    return data;

  } catch (error) {
    console.error('Error configuring cession:', error);
    throw error;
  }
};

configureCession()
  .then(data => console.log('Configuration successful:', data))
  .catch(error => console.error('Configuration failed:', error));
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class CessionConfigurationExample {
    public static void main(String[] args) {
        String url = "https://api.fingo.cl/v1/companies/{company_id}/cession_configuration";
        String apiKey = "YOUR_ACCESS_TOKEN";
        String payload = "{\"option\": 0}";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", "Api-Key " + apiKey)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(payload))
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            System.err.println("Error configuring cession: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Ejemplo de respuesta

# Cliente tiene certificado digital y facturador electrónico cargados
{
  "status": "success",
  "message": "Cession configuration updated successfully"
}

# Cliente no tiene certificado digital cargado
{
  "status": "error",
  "message": "Missing digital certificate credentials"
}
# Cliente no tiene facturador electrónico cargado y no es Mi pyme.
{
  "status": "error",
  "message": "Missing invoice provider credentials"
}

Este endpoint permite configurar la cesión de facturas. Indica si la cesión requerirá la contraseña o no del ceritifcado digital. Para esto se debe tener cargado el certificado digital y en caso de que el facturador electrónico no sea Mi Pyme, se debe tener cargado el facturador electrónico.

URL: /companies/{company_id}/cession_configuration

Método: POST

Parámetros requeridos en el body

Opciones de configuración

Evaluación de Riesgo

Evaluación de Riesgo de una Factura

Para obtener la aprobación o rechazo de una factura se debe obtener la siguiente data:

require 'net/http'
require 'uri'
require 'json'

url = URI("https://api.fingo.cl/v1/evaluation_request")

https = Net::HTTP.new(url.host, url.port);
https.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["cache-control"] = "no-cache"
request.body = JSON.dump({
  "invoices": [
    {
      "invoice_id": 12345,
      "payment_date": "2022-04-19"
    }
  ],
  "origin_rut": "77666888-9",
  "user_email": "example@domain.com",
  "webhook_url": "https://example.com/evaluation_request"
})

response = https.request(request)
puts response.read_body
using System;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var client = new HttpClient();
            var uri = new Uri("https://api.fingo.cl/v1/evaluation_request");

            var data = new
            {
                invoices = new[]
                {
                    new { invoice_id = "12345", payment_date = "2022-04-19" }
                },
                webhook_url = "https://example.com/webhook"
            };

            var json = JsonConvert.SerializeObject(data);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var response = client.PostAsync(uri, content).Result;

            Console.WriteLine(response.Content.ReadAsStringAsync().Result);
        }
    }
}
import requests
import json

url = "https://api.fingo.cl/v1/evaluation_request"

payload = {
    "invoices": [
        {
            "invoice_id": 12345,
            "payment_date": "2022-04-19",
        }
    ],
    "origin_rut": "77666888-9",
    "user_email": "example@domain.com",
    "webhook_url": "https://example.com/webhook"
}

headers = {
    'Content-Type': 'application/json'
}

response = requests.post(url, headers=headers, data=json.dumps(payload))

print(response.text)
curl --location --request POST 'https://api.fingo.cl/v1/evaluation_request' \
--header 'Content-Type: application/json' \
--data-raw '{
    "invoices": [
        {
            "invoice_id": "12345",
            "payment_date": "2022-04-19"
        }
    ],
    "origin_rut": "77666888-9",
    "user_email": "example@domain.com",
    "webhook_url": "https://example.com/webhook"
}'
const https = require("https");
const data = JSON.stringify({
  invoices: [
    {
      invoice_id: "12345",
      payment_date: "2022-04-19",
    },
  ],
  origin_rut: "77666888-9",
  user_email: "example@domain.com",
  webhook_url: "https://example.com/webhook",
});

const options = {
  hostname: "api.fingo.cl",
  path: "/v1/evaluation_request",
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
};

const req = https.request(options, (res) => {
  console.log(`statusCode: ${res.statusCode}`);

  res.on("data", (d) => {
    process.stdout.write(d);
  });
});

req.on("error", (error) => {
  console.error(error);
});

req.write(data);
req.end();

Ejemplos de respuesta API

{
  "list_invoices": [
    {
      "invoice_id": 12345,
      "decision": 3,
      "company_rut": "92929399"
    }
  ]
}
{
  "list_invoices": [
    {
      "invoice_id": 12345,
      "decision": 3,
      "company_rut": "92929399"
    }
  ],
  "conflicts": {
    "sii_rejected": [9398],
    "already_evaluated": [8882, 8922],
    "with_credit_note": [3213],
    "not_invoices": [99129],
    "already_paid": [93598],
    "expired": [88582, 89522],
    "loaned": [3213]
  }
}

Este endpoint te permite solicitar una evaluación de riesgo a Fingo.

Es importante destacar que no funciona en tiempo real, ya que va a devolver la respuesta a través de un webhook. En el webhook se expone un endpoint en el que Fingo te va a entregar por factura la decisión de Aprobación, En Espera de Documentos, o Rechazo. En el caso de que esté en Espera de Documentos se irán enviando actualizaciones de los estados en la medida que se entreguen los documentos. Luego de entregados todos los documentos Fingo enviará la decisión de Aprobación o Rechazo. Existen ejemplos de todos estos casos.

URL: /evaluation_request

Método: POST (webhook)

Parámetros de consulta

Formato Respuesta

Formato Webhook

Ejemplo de respuesta WEBHOOK

{
  "invoice_id": 12345,
  "company_rut": "92929399",
  "decision": 2,
  "monthly_rate": 2.0,
  "default_rate": 2.15,
  "retention_percentage": 1.0,
  "required_documents": []
}

El cliente debe implementar una API Rest que reciba un JSON con el siguiente formato:

Las respuestas a través del webhook van a ser individuales por factura, indicando su ID y sus datos respectivos.

En el caso que se apruebe se devolverá el resultado que se muestra en el ejemplo de evaluación.

En el caso de que existan condiciones antes de la operación se enviará el estado en Espera de Documentos.

Ejemplo de respuesta WEBHOOK en Espera de Documentos

{
  "invoice_id": 12345,
  "company_rut": "92929399",
  "decision": 4,
  "required_documents": [
      {"PDF": 0}, 
      {"PURCHASE_ORDER": 0}, 
      {"PAYMENT_STATUS": 0}
  ]
}

En caso de que previamente ya existan documentos cargados, se enviará el estado correspondiente en el campo del documento. En el ejemplo se observa que está cargado el PDF pero aún está pendiente la orden de compra.

Ejemplo N°2 de respuesta WEBHOOK en Espera de Documentos

{
  "invoice_id": 12345,
  "company_rut": "92929399",
  "decision": 4,
  "required_documents": [
      {"PDF": 1}, 
      {"PURCHASE_ORDER": 0}, 
      {"PAYMENT_STATUS": 0}
  ]
}

En el caso de que exista un rechazo solo se devolverá el rechazo. Ver la evaluación con de la invoice ID 12345 en los ejemplos de código.

Ejemplo de respuesta WEBHOOK en Rechazo

{
  "invoice_id": 12345,
  "company_rut": "92929399",
  "decision": 5
}

A continuación se identifican los códigos de los distintos campos:

required_documents

Cada documento requerido va acompañado de su estado.

decision

Respecto a los valores de decision, los códigos son los siguientes:

Resolución de Evaluación de Riesgo*

Este endpoint debe ser implementado para enviar las resoluciones de riesgo resueltas internamente. Máximo 50 resoluciones por request.

URL: /evaluation_resolution

Método: POST

Ejemplo de payload

{
  "resolutions": [
    {
      "invoice_id": "12345",
      "status": "approved",
      "resolved_at": "2024-03-20T10:30:00Z",
      "reason": "Valid client"
    },
    {
      "invoice_id": "12346",
      "status": "rejected",
      "rejection_details": {
        "type": "credit_line_exceeded",
        "credit_line": {
          "available_amount": 50000.00,
          "currency": "CLP",
          "required_amount": 75000.00
        }
      },
      "reason": "Required amount exceeds available credit line",
      "resolved_at": "2024-03-20T10:30:00Z"
    }
  ]
}

Formato del Payload

Respuesta Exitosa

{
  "status": "success",
  "resolutions": [
    {
      "invoice_id": "12345",
      "status": "success",
      "resolution_id": "1000"
    },
    {
      "invoice_id": "12346",
      "status": "success",
      "resolution_id": "1001"
    }
  ]
}

Ejemplo de error

{
  "status": "error",
  "errors": [
    {
      "invoice_id": "12345",
      "status": "error",
      "message": "Invoice with id 12345 does not exist",
    }
  ]
}

Facturas

Objeto Factura

Una factura representa un documento tributario electrónico (DTE) emitido por una empresa a otra, que detalla la información de una transacción comercial y es enviado al Servicio de Impuestos Internos (SII) para su registro y control. Las facturas se pueden buscar y filtrar por diferentes criterios.

A continuación, se describen los parámetros de una factura:

Aquí se describen los códigos de los estados:

sii_status

loaned_status

available_for_financing

credit_note_status

evaluation_status

collected

Obtener Lista de Facturas

Para pedir facturas usen el siguiente código:

require 'net/http'
require 'json'

url = URI("https://api.fingo.cl/v1/invoices/?credit_note_status=Partial+credit+note&page=1&page_size=10")

http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Api-Key meowmeowmeow"

response = http.request(request)

data = JSON.parse(response.read_body)
puts data
import requests

url = "https://api.fingo.cl/v1/invoices/"

payload = {
    "credit_note_status": "Partial+credit+note",
    "page": 2,
    "page_size": 2,
    "id": "1,2,3",
    "dte_type": "33,61",
    "date_issued": "2021-02-01",
    "folio__exact": 1234,
    "amount_with_iva__gte": 1000,
    "company__master_entity__rut": 13521895,
    "company__master_entity__name__icontains": "biomar",
    "reception_date__lte": "2022-11-01",
    "receiver__rut": "76003885-7,96512650-3"
}

headers = {
    "Authorization": "Api-Key %INSERT_KEY_HERE%"
}

response = requests.get(url, params=payload, headers=headers)

if response.status_code == 200:
    data = response.json()
    # Procesar los datos de las facturas
else:
    print(f"Error al obtener las facturas: {response.status_code} - {response.text}")
curl -X GET \
  'http://api.fingo.cl/v1/invoices/?credit_note_status=Partial+credit+note&page=2&page_size=2&id=1%2C2%2C3&dte_type=33%2C61&date_issued=2022-01-01&folio__gte=100&folio__lte=200&amount_with_iva__exact=15000&company__master_entity__rut=13521895&company__master_entity__name__icontains=biomar&reception_date__lte=2022-11-01&receiver__rut=76003885-7%2C96512650-3' \
  -H 'Authorization: Api-Key INSERT_KEY_HERE'
const apiUrl = "https://api.fingo.cl/v1/invoices/";
const apiKey = "INSERT_API_KEY_HERE";
const creditNoteStatus = "Partial+credit+note";
const sortBy = "date_issued";

const headers = {
  Authorization: `Api-Key ${apiKey}`,
};

const params = {
  credit_note_status: creditNoteStatus,
  ordering: sortBy,
};
const queryString = new URLSearchParams(params).toString();
fetch(`${apiUrl}?${queryString}`, { headers })
  .then((response) => response.json())
  .then((data) => {
    console.log(data.results); // Lista de facturas
  })
  .catch((error) => {
    console.error(error);
  });
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace FacturasExample
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string url = "https://api.fingo.cl/v1/invoices/";

            var queryStringParams = new System.Collections.Specialized.NameValueCollection()
            {
                { "credit_note_status", "Partial credit note" },
                { "page", "2" },
                { "page_size", "2" },
                { "id", "1,2,3" },
                { "dte_type", "33,61" },
                { "date_issued", "2021-02-01" },
                { "folio__exact", "1234" },
                { "amount_with_iva__gte", "1000" },
                { "company__master_entity__rut", "13521895" },
                { "company__master_entity__name__icontains", "biomar" },
                { "reception_date__lte", "2022-11-01" },
                { "receiver__rut", "76003885-7,96512650-3" }
            };

            using var client = new HttpClient();

            client.DefaultRequestHeaders.Add("Authorization", "Api-Key %INSERT_KEY_HERE%");

            var response = await client.GetAsync(url + "?" + queryStringParams.ToString());

            if (response.IsSuccessStatusCode)
            {
                var jsonString = await response.Content.ReadAsStringAsync();
                var data = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);
                // Procesar los datos de las facturas
            }
            else
            {
                Console.WriteLine($"Error al obtener las facturas: {response.StatusCode} - {response.ReasonPhrase}");
            }
        }
    }
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class InvoicesExample {
    public static void main(String[] args) {
        String url = "https://api.fingo.cl/v1/invoices/";
        String apiKey = "INSERT_KEY_HERE";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", "Api-Key " + apiKey)
                .GET()
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Ejemplo de respuesta

{
   {
    "count": 201,
    "next": "https://api.fingo.cl/v1/invoices/?page=2&page_size=1",
    "previous": null,
    "results": [
        {
            "pk": 186917,
            "dte_type": {
                "pk": 33,
                "code": "33",
                "name": "Factura afecta",
                "currency": "CLP"
            },
            "issuer": {
                "pk": 76973369,
                "rut_with_dv": "76973369-8",
                "name": "SERVICIOS PATRICIO ANDRES MELLADO MELLADO E.I.R.L."
            },
            "receiver": {
                "pk": 76003885,
                "rut_with_dv": "76003885-7",
                "name": "AUSTRALIS MAR S.A."
            },
            "cessions": [
                {
                    "pk": 93,
                    "mail_transferor": "jrivera@bolsadeproductos.cl",
                    "mail_assignee": "dario@fingo.cl",
                    "cession_date": "2022-05-11T19:24:00Z",
                    "transferor": {
                        "pk": 99575550,
                        "rut_with_dv": "99575550-5",
                        "name": "BOLSA DE PRODUCTOS DE CHILE BOLSA DE PRODUCTOS AGROPECUARIOS S A"
                    },
                    "assignee": {
                        "pk": 77078244,
                        "rut_with_dv": "77078244-9",
                        "name": "FINGO SPA"
                    }
                }
            ],
            "traces": [],
            "folio": "293",
            "date_issued": "2022-01-02",
            "reception_date": "2022-01-03T01:12:57Z",
            "amount_with_iva": 846733,
            "sii_status": 8,
            "loaned_status": 1,
            "credit_note_status": 1,
            "references": [
                {
                    "pk": 287512,
                    "folio": "31",
                    "dte_type": {
                        "pk": 61,
                        "code": "61",
                        "name": "Nota de crédito",
                        "currency": "CLP"
                    },
                    "amount_with_iva": 714000
                }
            ],
            "evaluation_status": 2,
            "payed_in_cash": false,
            "collected": 0,
            "financed_amount": 420000,
            "rate": 1.2,
            "avialble_for_financing": 0
        }
    ]
}
}

Este endpoint te permite listar las facturas y filtrar en base a parámetros de las facturas

URL: /invoices

Método: GET

Parámetros de consulta:

Parámetros de ordenamiento:

Se pueden utilizar los siguientes parámetros para ordenar las facturas:

Obtener Detalles de la Factura *

Para obtener el detalle de una factura:

import requests
import json

url = "https://api.fingo.cl/v1/invoices/182378"

headers = {
    'Authorization': 'Api-Key YOUR_ACCESS_TOKEN'
    'Content-Type': 'application/json'
}

response = requests.post(url, headers=headers, data=json.dumps(payload))

print(response.text)
curl -X GET https://api.fingo.cl/v1/invoices/182378 \
-H "Authorization: Api-Key YOUR_ACCESS_TOKEN" \
-H 'Content-Type: application/json'
require 'net/http'
require 'json'

url = URI("https://api.fingo.cl/v1/invoices/182378")

http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Api-Key YOUR_ACCESS_TOKEN"
request["Content-Type"] = "application/json"

response = http.request(request)

data = JSON.parse(response.read_body)
puts data
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

public static class Program
{
    public static async Task Main(string[] args)
    {
        var url = "https://api.fingo.cl/v1/invoices/182378";

        var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Api-Key", "YOUR_ACCESS_TOKEN");
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var response = await client.PostAsync(url, null);
        var responseContent = await response.Content.ReadAsStringAsync();

        Console.WriteLine(responseContent);
    }
}
const fetch = require('node-fetch');

const url = "https://api.fingo.cl/v1/invoices/182378";
const accessToken = 'YOUR_ACCESS_TOKEN';

const headers = {
    'Authorization': `Api-Key ${accessToken}`,
    'Content-Type': 'application/json'
};

fetch(url, {
    method: 'POST',
    headers: headers,
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class InvoiceDetailExample {
    public static void main(String[] args) {
        String url = "https://api.fingo.cl/v1/invoices/182378";
        String apiKey = "YOUR_ACCESS_TOKEN";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", "Api-Key " + apiKey)
                .header("Content-Type", "application/json")
                .GET()
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Ejemplo de respuesta:

{
    "pk": 186917,
    "dte_type": {
        "pk": 33,
        "code": "33",
        "name": "Factura afecta",
        "currency": "CLP"
    },
    "issuer": {
        "pk": 76973369,
        "rut_with_dv": "76973369-8",
        "name": "SERVICIOS PATRICIO ANDRES MELLADO MELLADO E.I.R.L."
    },
    "receiver": {
        "pk": 76003885,
        "rut_with_dv": "76003885-7",
        "name": "MAR S.A."
    },
    "cessions": [
        {
          "pk": 93,
          "mail_transferor": "jrivera@bolsadeproductos.cl",
          "mail_assignee": "dario@fingo.cl",
          "cession_date": "2022-05-11T19:24:00Z",
          "transferor": {
              "pk": 99575550,
              "rut_with_dv": "99575550-5",
              "name": "BOLSA DE PRODUCTOS DE CHILE BOLSA DE PRODUCTOS AGROPECUARIOS S A"
          },
          "assignee": {
              "pk": 77078244,
              "rut_with_dv": "77078244-9",
              "name": "FINGO SPA"
          }
        }
    ],
    "traces": [
        {
          "pk": 8537,
          "event_code": "CED",
          "event_time": "2022-01-04T22:07:01Z",
          "event_description": "DTE Cedido"
        }
    ],
    "preoffer": {
      "pk": 857,
      "monthly_rate": 1.6,
      "default_rate": 2.2,
      "retention_rate": 1
    },
    "folio": "293",
    "date_issued": "2022-01-02",
    "reception_date": "2022-01-03T01:12:57Z",
    "amount_with_iva": 846733,
    "sii_status": 8,
    "loaned_status": 1,
    "credit_note_status": 1,
    "references": [
        {
          "pk": 287512,
          "folio": "31",
          "dte_type": {
              "pk": 61,
              "code": "61",
              "name": "Nota de crédito",
              "currency": "CLP"
          },
          "amount_with_iva": 714000
        }
    ],
    "evaluation_status": 2,
    "financed_amount": 420000,
    "rate": 1.2,
    "payed_in_cash": false,
    "collected": 1,
    "required_documents": [
        {"PDF": 0}, 
        {"PURCHASE_ORDER": 0}, 
        {"HES": 0}
    ]
}

Este endpoint permite ver el detalle de una factura.

URL: /invoices/<int:invoice_id>

Método: GET

Ceder Factura

Ejemplo de solicitud:

import requests

url = "https://api.fingo.cl/v1/invoices/12345/cession"

payload = {
    "transferor_rut": "76123456-7",
    "assignee_rut": "76543210-8",
    "assignee_mail": "empresa@example.com",
    "transferor_mail": "cedente@example.com",
    "webhook_url": "https://example.com/webhook"
}

headers = {
    "Authorization": "Api-Key YOUR_ACCESS_TOKEN",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
curl -X POST "https://api.fingo.cl/v1/invoices/12345/cession" -d '{"transferor_rut": "76123456-7", "assignee_rut": "76543210-8", "assignee_mail": "empresa@example.com", "transferor_mail": "cedente@example.com", "webhook_url": "https://example.com/webhook"}' -H "Authorization: Api-Key YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

class Program
{
    static async Task Main()
    {
        using var client = new HttpClient();
        var url = "https://api.fingo.cl/v1/invoices/12345/cession";

        var payload = new
        {
            transferor_rut = "76123456-7",
            assignee_rut = "76543210-8",
            assignee_mail = "empresa@example.com",
            transferor_mail = "cedente@example.com",
            webhook_url = "https://example.com/webhook"
        };

        var content = new StringContent(
            System.Text.Json.JsonSerializer.Serialize(payload),
            Encoding.UTF8,
            "application/json"
        );

        client.DefaultRequestHeaders.Add("Authorization", "Api-Key YOUR_ACCESS_TOKEN");

        var response = await client.PostAsync(url, content);
        var responseContent = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseContent);
    }
}
require 'net/http'
require 'json'

url = URI("https://api.fingo.cl/v1/invoices/12345/cession")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = "Api-Key YOUR_ACCESS_TOKEN"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
  "transferor_rut" => "76123456-7",
  "assignee_rut" => "76543210-8",
  "assignee_mail" => "empresa@example.com",
  "transferor_mail" => "cedente@example.com",
  "webhook_url" => "https://example.com/webhook"
})

response = http.request(request)
puts response.read_body
const fetch = require("node-fetch");

const url = "https://api.fingo.cl/v1/invoices/12345/cession";
const payload = {
  transferor_rut: "76123456-7",
  assignee_rut: "76543210-8",
  assignee_mail: "empresa@example.com",
  transferor_mail: "cedente@example.com",
  webhook_url: "https://example.com/webhook",
};

fetch(url, {
  method: "POST",
  headers: {
    Authorization: "Api-Key YOUR_ACCESS_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify(payload),
})
  .then((response) => response.text())
  .then((text) => console.log(text))
  .catch((err) => console.error(err));
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class CessionExample {
    public static void main(String[] args) {
        String url = "https://api.fingo.cl/v1/invoices/12345/cession";
        String apiKey = "YOUR_ACCESS_TOKEN";
        String payload = "{\"transferor_rut\": \"76123456-7\", \"assignee_rut\": \"76543210-8\", \"assignee_mail\": \"empresa@example.com\", \"transferor_mail\": \"cedente@example.com\", \"webhook_url\": \"https://example.com/webhook\"}";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", "Api-Key " + apiKey)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(payload))
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Ejemplo de respuesta exitosa

{
  "status": "success",
  "message": "Cession request received and is being processed. The result will be sent to the webhook URL.",
  "request_id": "b3e9f3f9-8d7a-4b6c-9b1a-3e7f2d5c8a1b"
}

Ejemplo de respuesta de error

{
  "status": "error",
  "message": "Validation failed. Please check the provided data.",
  "errors": {
    "transferor_rut": ["Only the owner (76000000) can transfer this invoice"],
    "certificate_password": ["The provided digital certificate password is not valid."],
    "webhook_url": ["This field is required."]
  }
}

Ejemplo de respuesta (a través de webhook):

Ejemplo de respuesta exitosa

{
  "request_id": "b3e9f3f9-8d7a-4b6c-9b1a-3e7f2d5c8a1b",
  "invoice_id": 12345,
  "status": "success",
  "message": "Assignment completed successfully",
  "cession": {
    "pk": 123,
    "transferor_mail": "cedente@example.com",
    "assignee_mail": "empresa@example.com",
    "cession_date": "2022-01-01T00:00:00Z",
    "transferor_rut": "76543210-8",
    "assignee_rut": "98765432-1"
  }
}

Ejemplo de respuesta de error

{
  "request_id": "b3e9f3f9-8d7a-4b6c-9b1a-3e7f2d5c8a1b",
  "invoice_id": 12345,
  "status": "error",
  "message": "Cession rejected by SII",
  "details": "{SII error details}"
}

Este endpoint permite ceder una factura a otra empresa de forma asíncrona. La respuesta se notificará a través de un webhook. Para ceder más de una factura, se debe utilizar el endpoint de Ceder Facturas en Batch.

URL: /invoices/{invoice_id}/cession

Método: POST

Parámetros requeridos

Formato de las respuestas del Webhook

Cargar Documentos de una Factura

Para subir documentos se entregan los siguientes ejemplos:

import requests
import json

url = "https://api.fingo.cl/v1/invoices/182378/documents"

payload = {
    "document_type": "PURCHASE_ORDER",
    "document_file": "archivo en b64"
}

headers = {
    'Content-Type': 'application/json'
}

response = requests.post(url, headers=headers, data=json.dumps(payload))

print(response.text)
curl -X POST https://api.fingo.cl/v1/invoices/182378/documents \
-H 'Content-Type: application/json' \
-d '{"document_type": "PURCHASE_ORDER", "document_file": "archivo en b64"}'
require 'uri'
require 'net/http'
require 'json'

url = URI("https://api.fingo.cl/v1/invoices/182378/documents")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request.body = JSON.dump({
  "document_type" => "PURCHASE_ORDER",
  "document_file" => "archivo en b64"
})

response = http.request(request)
puts response.read_body
const fetch = require("node-fetch");

const url = "https://api.fingo.cl/v1/invoices/182378/documents";
const payload = {
  document_type: "PURCHASE_ORDER",
  document_file: "archivo en b64",
};

fetch(url, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify(payload),
})
  .then((response) => response.text())
  .then((text) => console.log(text))
  .catch((err) => console.error(err));
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var url = "https://api.fingo.cl/v1/invoices/182378/documents";
        var payload = new
        {
            document_type = "PURCHASE_ORDER",
            document_file = "archivo en b64"
        };

        using var client = new HttpClient();
        var json = JsonConvert.SerializeObject(payload);
        var data = new StringContent(json, Encoding.UTF8, "application/json");
        var response = await client.PostAsync(url, data);

        string result = await response.Content.ReadAsStringAsync();
        Console.WriteLine(result);
    }
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class UploadDocumentExample {
    public static void main(String[] args) {
        String url = "https://api.fingo.cl/v1/invoices/182378/documents";
        String payload = "{\"document_type\": \"PURCHASE_ORDER\", \"document_file\": \"archivo en b64\"}";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(payload))
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Ejemplos de respuesta:

{
    "status": "success",
    "message": "Document uploaded successfully",
    "data": {
        "document_id": 123,
        "invoice_id": 182378,
    }
}

{
    "status": "error",
    "message": "Invalid Base64 encoding"
}

Este endpoint permite subir documentos asociados a una factura, permite subir un documento por request.

URL: invoices/{invoiceId}/documents

Método: POST

Parámetros requeridos

Tipos de documento

Validación de Factura

Ejemplo de solicitud

import requests

url = "https://api.fingo.cl/v1/invoices/feasibility"
params = {
    "issuer_rut": "12345678-9",
    "folio": "12345",
    "dte_type": "33"
}
headers = {
    "Authorization": "Api-Key YOUR_ACCESS_TOKEN"
}

response = requests.get(url, params=params, headers=headers)
print(response.text)
curl -X GET "https://api.fingo.cl/v1/invoices/feasibility?issuer_rut=12345678-9&folio=12345&dte_type=33" \
  -H "Authorization: Api-Key YOUR_ACCESS_TOKEN"
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using (var client = new HttpClient())
        {
            var url = "https://api.fingo.cl/v1/invoices/feasibility";
            var queryString = $"?issuer_rut=12345678-9&folio=12345&dte_type=33";

            client.DefaultRequestHeaders.Add("Authorization", "Api-Key YOUR_ACCESS_TOKEN");

            try
            {
                var response = await client.GetAsync(url + queryString);
                response.EnsureSuccessStatusCode();
                var result = await response.Content.ReadAsStringAsync();
                Console.WriteLine(result);
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Error making request: {e.Message}");
            }
        }
    }
}
require 'net/http'
require 'uri'

begin
  params = {
    issuer_rut: '12345678-9',
    folio: '12345',
    dte_type: '33'
  }

  uri = URI('https://api.fingo.cl/v1/invoices/feasibility')
  uri.query = URI.encode_www_form(params)

  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Get.new(uri)
  request['Authorization'] = 'Api-Key YOUR_ACCESS_TOKEN'

  response = http.request(request)

  if response.is_a?(Net::HTTPSuccess)
    puts response.body
  else
    puts "Error: #{response.code} - #{response.message}"
  end

rescue StandardError => e
  puts "Error making request: #{e.message}"
end
const checkFeasibility = async () => {
  const params = new URLSearchParams({
    issuer_rut: '12345678-9',
    folio: '12345',
    dte_type: '33'
  });

  const url = `https://api.fingo.cl/v1/invoices/feasibility?${params}`;

  const options = {
    method: 'GET',
    headers: {
      'Authorization': 'Api-Key YOUR_ACCESS_TOKEN'
    }
  };

  try {
    const response = await fetch(url, options);

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    console.log(data);
    return data;

  } catch (error) {
    console.error('Error making request:', error);
    throw error;
  }
};

checkFeasibility()
  .then(data => {
    console.log('Feasibility check successful:', data);
    if (data.status === 'Valid') {
      console.log('Invoice is valid with ID:', data.invoice_id);
    } else {
      console.log('Invoice is invalid:', data.message); 
    }
  })
  .catch(error => {
    console.error('Failed to check feasibility:', error.message);
  });
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;

public class InvoiceFeasibilityExample {
    public static void main(String[] args) {
        try {
            String baseUrl = "https://api.fingo.cl/v1/invoices/feasibility";
            String queryString = String.format("?issuer_rut=%s&folio=%s&dte_type=%s",
                URLEncoder.encode("12345678-9", StandardCharsets.UTF_8),
                URLEncoder.encode("12345", StandardCharsets.UTF_8),
                URLEncoder.encode("33", StandardCharsets.UTF_8));

            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl + queryString))
                .header("Authorization", "Api-Key YOUR_ACCESS_TOKEN")
                .GET()
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Ejemplos de respuesta

# Factura válida
{
    "status": "Valid",
    "message": "Feasibility validated successfully",
    "invoice_id": 123
}

# Factura ya cedida
{
    "status": "Invalid",
    "message": "Invoice already ceded",
    "invoice_id": 124
}

# Factura con nota de crédito
{
    "status": "Invalid",
    "message": "Invoice has a credit note",
    "invoice_id": 125
}

# Factura rechazada en el SII
{
    "status": "Invalid",
    "message": "Invoice rejected by SII",
    "invoice_id": 126
}

Este endpoint permite verificar si una factura es válida y si está disponible para cesión.

El proceso de validación realiza dos comprobaciones principales:

  1. Verificación en el SII: Primero se verifica que la factura esté correctamente emitida en el Servicio de Impuestos Internos (SII).

  2. Evaluación para cesión: Si la factura es válida, evaluamos si está disponible para cesión. En caso de no estarlo, se informa el motivo específico, siguiendo el siguiente orden de prioridad:

    • La factura ya ha sido cedida.
    • Si no ha sido cedida, se verifica si tiene nota de crédito.
    • Si no tiene nota de crédito, se verifica si fue rechazada por el SII.

En caso de que la factura sea válida y disponible para cesión, se retornará el id de la factura.

URL: /invoices/feasibility

Método: GET

Parámetros requeridos

Validación de Facturas en Batch

Ejemplo de solicitud


import requests

url = "https://api.fingo.cl/v1/invoices/feasibility/batch"

payload = {
    "invoices": [
        {
            "issuer_rut": "70000000-7",
            "folio": "1234",
            "dte_type": "33"
        },
        {
            "issuer_rut": "70000001-8",
            "folio": "5678",
            "dte_type": "33"
        }
    ],
    "webhook_url": "https://your-webhook-url.com"
}

headers = {
    "Authorization": "Api-Key YOUR_ACCESS_TOKEN",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
curl -X POST "https://api.fingo.cl/v1/invoices/feasibility/batch" -d '{"invoices": [{"issuer_rut": "70000000-7", "folio": "1234", "dte": "33"}, {"issuer_rut": "70000001-8", "folio": "5678", "dte": "33"}], "webhook_url": "https://your-webhook-url.com"}' -H "Authorization: Api-Key YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

class Program
{
    static async Task Main()
    {
        var url = "https://api.fingo.cl/v1/invoices/feasibility/batch";

        var payload = new
        {
            invoices = new[]
            {
                new { issuer_rut = "70000000-7", folio = "1234", dte_type = "33" },
                new { issuer_rut = "70000001-8", folio = "5678", dte_type = "33" }
            },
            webhook_url = "https://your-webhook-url.com"
        };

        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Authorization", "Api-Key YOUR_ACCESS_TOKEN");

        var jsonContent = JsonConvert.SerializeObject(payload);
        var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

        var response = await client.PostAsync(url, content);
        var result = await response.Content.ReadAsStringAsync();
        Console.WriteLine(result);
    }
}
require 'net/http'
require 'json'

url = URI("https://api.fingo.cl/v1/invoices/feasibility/batch")

payload = {
  invoices: [
    {
      issuer_rut: "70000000-7",
      folio: "1234",
      dte_type: "33"
    },
    {
      issuer_rut: "70000001-8", 
      folio: "5678",
      dte_type: "33"
    }
  ],
  webhook_url: "https://your-webhook-url.com"
}

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = "Api-Key YOUR_ACCESS_TOKEN"
request["Content-Type"] = "application/json"
request.body = payload.to_json

response = http.request(request)
puts response.body
const fetch = require('node-fetch');

const url = "https://api.fingo.cl/v1/invoices/feasibility/batch";

const payload = {
  invoices: [
    {
      issuer_rut: "70000000-7",
      folio: "1234",
      dte_type: "33"
    },
    {
      issuer_rut: "70000001-8",
      folio: "5678", 
      dte_type: "33"
    }
  ],
  webhook_url: "https://your-webhook-url.com"
};

const headers = {
  'Authorization': 'Api-Key YOUR_ACCESS_TOKEN',
  'Content-Type': 'application/json'
};

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class BatchFeasibilityExample {
    public static void main(String[] args) {
        String url = "https://api.fingo.cl/v1/invoices/feasibility/batch";
        String payload = "{" +
            "\"invoices\": [" +
                "{" +
                    "\"issuer_rut\": \"70000000-7\"," +
                    "\"folio\": \"1234\"," +
                    "\"dte_type\": \"33\"" +
                "}," +
                "{" +
                    "\"issuer_rut\": \"70000001-8\"," +
                    "\"folio\": \"5678\"," +
                    "\"dte_type\": \"33\"" +
                "}" +
            "]," +
            "\"webhook_url\": \"https://your-webhook-url.com\"" +
            "}";

        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(payload))
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Ejemplos de respuesta

Caso Exitoso (200 OK)

{
    "batch_id": "2fdb73c3-a98b-4346-a066-0ee16744762a",
    "results": [
        {
            "request_id": "b8c54dac-8787-4522-962f-fc7eb2415c79",
            "status": "accepted",
            "invoice_data": {
                "issuer_rut": "76735582",
                "folio": "218",
                "dte_type": 33
            }
        },
        {
            "request_id": "22a227f5-effb-4646-b7c0-c6ea84d5621a",
            "status": "accepted",
            "invoice_data": {
                "issuer_rut": "76261029",
                "folio": "1078",
                "dte_type": 33
            }
        }
    ],
    "message": "All invoices validated successfully"
}

Respuesta Parcial (207 Multi-Status)

{
    "batch_id": "422745d6-625b-4d44-a50d-46264d2b4d58",
    "results": [
        {
            "request_id": "31da485b-4bea-43e9-9d6e-d458814e8318",
            "status": "accepted",
            "invoice_data": {
                "issuer_rut": "76261029",
                "folio": "1078",
                "dte_type": 33
            }
        },
        {
            "request_id": null,
            "status": "error",
            "errors": {
                "folio": [
                    "This field is required."
                ]
            },
            "invoice_data": {
                "issuer_rut": "76735582-3",
                "wrong_folio": "218",
                "dte_type": 33
            }
        }
    ],
    "message": "Partial validation success"
}

Error (400 Bad Request)

{
    "batch_id": "57778c1d-8832-4c08-bb73-6e3f9af0ab54",
    "results": [
        {
            "request_id": null,
            "status": "error",
            "errors": {
                "folio": [
                    "This field is required."
                ]
            },
            "invoice_data": {
                "issuer_rut": "76735582-3",
                "wrong_folio": "218",
                "dte_type": 33
            }
        },
        {
            "request_id": null,
            "status": "error",
            "errors": {
                "folio": [
                    "This field is required."
                ]
            },
            "invoice_data": {
                "issuer_rut": "76261029-9",
                "wrong_folio": "1078",
                "dte_type": 33
            }
        }
    ],
    "message": "All invoices failed validation"
}

Este endpoint permite validar una lista de facturas en batch. Replica la lógica del endpoint de Validación de Factura. La respuesta de este endpoint es de forma asíncrona y se entregarán de forma individual a través del webhook definido en el parámetro webhook_url.

URL: /invoices/feasibility/batch

Método: POST

Parámetros requeridos

Respuesta

La API responde inmediatamente con un código de estado HTTP y un objeto JSON que contiene:

Respuestas del Webhook

La API envía respuestas individuales a través del webhook definido. Cada respuesta contiene el resultado de la validación de una factura específica.

Ejemplos de respuesta del Webhook

Ejemplo de respuesta de factura válida

{
    "status": "accepted",
    "message": "Factura válida",
    "batch_id": "123e4567-e89b-12d3-a456-426614174000",
    "invoice_id": "123e4567-e89b-12d3-a456-426614174000",
    "request_id": "123e4567-e89b-12d3-a456-426614174000",
    "invoice_data": {
        "folio": "1234",
        "dte_type": 33,
        "issuer_rut": "76735582"
    }
}

Ejemplo de respuesta de factura inválida

{
  "status": "Invalid", 
  "message": "Document has not been received in SII platform.", 
  "batch_id": "af680bba-de12-4233-bea2-b5db9ac26930", 
  "request_id": "8ca16524-cd2a-4182-91e2-c48a0875b6d2", 
  "invoice_data": {
    "folio": "218", 
    "dte_type": 33, 
    "issuer_rut": "76735582"
  }
}

Formato de las respuestas del Webhook

El cliente debe implementar una API que reciba un JSON con el siguiente formato. Las respuestas a través del webhook son individuales por factura, detallando sus datos específicos y el resultado de la validación:

Para cada factura en el lote, se realizará una llamada independiente al webhook, enviando el resultado correspondiente.

Operaciones

Crear Operación

Para crear una operación se entregan los siguientes ejemplos:

require 'net/http'
require 'uri'
require 'json'

url = URI("https://api.fingo.cl/v1/operation")

https = Net::HTTP.new(url.host, url.port);
https.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["cache-control"] = "no-cache"
request.body = JSON.dump({
  "invoices": [
    {
      "invoice_id": 12345,
      "payment_date": "2023-05-10"
    }
  ],
  "origin_rut": "77888999-6",
  "webhook_url": "https://example.com/webhook",
  "amount_operation": 15000,
  "commission": 1000,
  "amount_interest": 500,
  "amount_to_deposit": 13500,
  "amount_retention": 1500
})

response = https.request(request)
puts response.read_body
using System;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var client = new HttpClient();
            var uri = new Uri("https://api.fingo.cl/v1/operation");

            var data = new
            {
                invoices = new[] {
                    new {
                        invoice_id = 12345,
                        payment_date = "2023-05-10"
                    }
                },
                amount_operation = 15000,
                commission = 1000,
                amount_interest = 500,
                amount_to_deposit = 13500,
                amount_retention = 1500
            };

            var json = JsonConvert.SerializeObject(data);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var response = client.PostAsync(uri, content).Result;

            Console.WriteLine(response.Content.ReadAsStringAsync().Result);
        }
    }
}

import requests
import json

url = "https://api.fingo.cl/v1/operation"

payload = {
    "invoices": [
        {
            "invoice_id": 12345,
            "payment_date": "2023-05-10"
        }
    ],
    "origin_rut": "77888999-6",
    "webhook_url": "https://example.com/webhook",
    "amount_operation": 15000,
    "commission": 1000,
    "amount_interest": 500,
    "amount_to_deposit": 13500,
    "amount_retention": 1500
}

headers = {
    'Content-Type': 'application/json'
}

response = requests.post(url, headers=headers, data=json.dumps(payload))

print(response.text)
curl --location --request POST 'https://api.fingo.cl/v1/operation' \
--header 'Content-Type: application/json' \
--data-raw '{
    "invoices": [
        {
            "invoice_id": "12345",
            "payment_date": "2023-05-10"
        }
    ],
    "origin_rut": "77888999-6",
    "webhook_url": "https://example.com/webhook",
    "amount_operation": 15000,
    "commission": 1000,
    "amount_interest": 500,
    "amount_to_deposit": 13500,
    "amount_retention": 1500
}'

const https = require("https");
const data = JSON.stringify({
  invoices: [
    {
      invoice_id: 12345,
      payment_date: "2023-05-10",
    },
  ],
  origin_rut: "77888999-6",
  webhook_url: "https://example.com/webhook",
  amount_operation: 15000,
  commission: 1000,
  amount_interest: 500,
  amount_to_deposit: 13500,
  amount_retention: 1500,
});

const options = {
  hostname: "api.fingo.cl",
  path: "/v1/operation",
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
};

const req = https.request(options, (res) => {
  console.log(`statusCode: ${res.statusCode}`);

  res.on("data", (d) => {
    process.stdout.write(d);
  });
});

req.on("error", (error) => {
  console.error(error);
});

req.write(data);
req.end();

Ejemplo de respuesta

{
  "operation_id": 67890,
  "valid": "True"
}

Este endpoint valida el giro final de Fingo y crea la operación que finalmente será cedida a Fingo. Se recomienda llamarlo justo antes de girar para validar que está ok el giro.

URL: /operation

Método: POST

Parámetros requeridos

Parámetros de respuesta

Preofertas

Objeto Preoferta

Contiene los siguientes campos sobre las tasas en pre evaluación. Contiene la siguiente información:

Tipo de Documento Tributario

Objeto Tipo de Documento Tributario

El recurso dte_type representa el tipo de documento tributario electrónico (DTE) de la factura. Contiene la siguiente información:

Trazas

Objeto Traza

Información sobre las trazas de la factura. Contiene la siguiente información: