Documentación para desarrolladores

Integrá facturación con Fisnodo

Esta guía resume el flujo de integración para ERP, POS, ecommerce y sistemas internos que necesitan enviar documentos, validar datos, consultar estados y recibir eventos.

Antes de integrar

Estos son los conceptos que aparecen en casi todos los endpoints de la API.

Base URL

  • Producción: https://api.fisnodo.sun.com.py

Autenticación

  • Usá Authorization: Bearer <api-key> para integraciones de sistema.
  • Los endpoints de consola usan sesión HTTP-only y no son el camino recomendado para integraciones externas.

Tenant y empresa

  • Los endpoints v1 trabajan con X-Tenant-Id.
  • La empresa, sucursal, punto de emisión y canal de facturación deben estar configurados antes de operar documentos reales.

Idempotencia

  • POST /v1/documents requiere Idempotency-Key para evitar duplicar documentos ante reintentos de red.

Moneda

  • El documento puede emitirse en PYG u otra moneda ISO.
  • Cuando currency no es PYG, enviá exchange_rate con el tipo de cambio a PYG.

Flujo recomendado

Empezá con sandbox y validación. Pasá a facturación real cuando el contrato, la configuración y el seguimiento estén claros.

  1. 1

    Configurar

    Creá o seleccioná tenant, empresa, sucursal, punto de emisión, canal de facturación, certificado o datos de autoimpresor según corresponda.

  2. 2

    Validar

    Usá /v1/documents/validate para revisar estructura, readiness y prevalidación SIFEN v150; usá sandbox cuando necesites artefactos sin emitir.

  3. 3

    Procesar

    Creá el documento con Idempotency-Key y seguí su estado hasta una respuesta final del canal configurado.

  4. 4

    Sincronizar

    Consultá artefactos y usá webhooks para actualizar el sistema origen sin polling constante.

Primera factura en sandbox en 15 minutos

El objetivo de la primera prueba no es emitir con validez fiscal. Es confirmar que el sistema origen puede enviar JSON, validar datos, generar artefactos de prueba y reconciliar estados.

  1. 1

    Preparar credenciales

    Usá una llave de sandbox, X-Tenant-Id y un Idempotency-Key estable por documento de prueba.

  2. 2

    Validar payload

    Llamá POST /v1/documents/validate hasta que el contrato canónico y las reglas SIFEN v150 no devuelvan errores bloqueantes.

  3. 3

    Previsualizar artefactos

    Usá POST /v1/sandbox/preview para revisar XML, KUDE o imprimible sin remisión a DNIT/SIFEN.

  4. 4

    Conectar estado

    Guardá document_id, status_url y external_id para que el ERP/POS pueda consultar el resultado y mostrarlo al usuario.

Ejemplo mínimo

El payload exacto depende del tipo de documento y del canal, pero el patrón de llamada es el mismo.

fetch

JavaScript / TypeScript

await fetch("https://api.fisnodo.sun.com.py/v1/documents", {
  method: "POST",
  headers: {
    "Authorization": "Bearer <api-key>",
    "X-Tenant-Id": "<tenant-id>",
    "Idempotency-Key": "invoice-001",
    "Content-Type": "application/json"
  },
  body: JSON.stringify(documento)
});
requests

Python

requests.post(
  "https://api.fisnodo.sun.com.py/v1/documents",
  headers={
    "Authorization": "Bearer <api-key>",
    "X-Tenant-Id": "<tenant-id>",
    "Idempotency-Key": "invoice-001"
  },
  json=documento,
)
curl

PHP

$ch = curl_init("https://api.fisnodo.sun.com.py/v1/documents");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer <api-key>",
    "X-Tenant-Id: <tenant-id>",
    "Idempotency-Key: invoice-001",
    "Content-Type: application/json"
  ],
  CURLOPT_POSTFIELDS => json_encode($documento),
]);
HttpClient

C#

using var request = new HttpRequestMessage(HttpMethod.Post, "/v1/documents");
request.Headers.Authorization = new("Bearer", "<api-key>");
request.Headers.Add("X-Tenant-Id", "<tenant-id>");
request.Headers.Add("Idempotency-Key", "invoice-001");
request.Content = JsonContent.Create(documento);
await client.SendAsync(request);

Payloads y artefactos

Estos ejemplos cubren las piezas que suelen necesitar ERP, POS y ecommerce antes de pasar a producción.

JSON

Factura PYG

{
  "external_id": "erp-001",
  "type": "invoice",
  "issue_datetime": "2026-05-02T10:30:00-04:00",
  "currency": "PYG",
  "seller": { "ruc": "80000000-1", "legal_name": "Empresa Demo SA" },
  "buyer": { "ruc": "1234567-8", "legal_name": "Cliente Demo" },
  "items": [{
    "description": "Servicio mensual",
    "quantity": 1,
    "unit_price": 100000,
    "tax_rate": 10,
    "tax_amount": 9091,
    "total_amount": 100000
  }],
  "totals": { "subtotal": 90909, "tax_total": 9091, "grand_total": 100000 },
  "payment_terms": { "condition": "cash", "method": "bank_transfer" }
}
fetch

Descarga de artefactos

const response = await fetch(
  `https://api.fisnodo.sun.com.py/v1/documents/${documentId}/artifacts`,
  { headers: { Authorization: "Bearer <api-key>", "X-Tenant-Id": tenantId } }
);
const artifacts = await response.json();
// Buscar KUDE, XML firmado, PDF/imprimible, payload normalizado y respuesta del canal.
header

Webhook firmado

X-Webhook-Signature: t=1762000000,v1=<hmac-sha256>

{
  "type": "document.accepted",
  "document_id": "doc_123",
  "external_id": "erp-001",
  "status": "accepted"
}
JavaScript

Verificación de firma

const signedPayload = `${timestamp}.${rawBody}`;
const expected = createHmac("sha256", webhookSecret)
  .update(signedPayload)
  .digest("hex");
const valid = signature.length === expected.length
  && timingSafeEqual(Buffer.from(signature), Buffer.from(expected));

Ejemplos mantenidos en el repo

Los ejemplos de JavaScript, Python, PHP y C# incluyen creación de documentos, manejo de errores, sandbox preview y verificación de webhooks.

Endpoints principales

La referencia completa sigue disponible como OpenAPI JSON para importar en herramientas técnicas.

Documentos

POST/v1/documents/validate
Prevalida contrato, configuración y reglas SIFEN v150 sin emitir.
POST/v1/documents
Crea y procesa un documento.
GET/v1/documents/{id}
Consulta estado y datos del documento.
POST/v1/documents/{id}/retry
Reintenta un documento recuperable.
GET/v1/documents/{id}/timeline
Obtiene el historial operativo.

Sandbox

POST/v1/sandbox/preview
Genera validación, XML, imprimible o respuesta de prueba sin emitir realmente.

Configuración

GET/v1/companies
Lista empresas del tenant.
GET/v1/emission-channels
Lista canales de facturación configurados.
GET/v1/certificates
Consulta certificados disponibles.

Webhooks

GET/v1/webhooks
Lista suscripciones.
POST/v1/webhooks/{id}/replay
Reenvía un evento para diagnóstico.

Contrato OpenAPI

Usá el JSON para generar clientes, revisar schemas completos y automatizar pruebas de integración.

Descargar OpenAPI JSON

Estados, errores y preparación

La integración debe tratar estados y errores como parte del contrato operativo, no como texto libre.

Ciclo de estados

  • received: Fisnodo recibió el documento.
  • validated: el contrato pasó validación local.
  • queued / signing / submitting: el documento está en procesamiento.
  • accepted / rejected / retrying / failed_terminal: resultado operativo para reconciliar.

Errores comunes

  • validation_error: payload inválido o regla fiscal incumplida.
  • configuration_error: falta empresa, sucursal, punto, canal, timbrado o rango.
  • certificate_error: certificado ausente, inválido o vencido.
  • upstream_error: SIFEN/e-Kuatia o proveedor externo respondió con falla temporal.

Sandbox vs producción

  • Sandbox genera previews y respuestas de prueba sin validez fiscal.
  • Producción requiere datos reales de empresa, sucursal, punto, certificado, timbrado, numeración por tipo y credenciales.
  • No mezcles llaves, tenant ni endpoint de sandbox con datos reales de go-live.

Readiness antes del go-live

  • Empresa, sucursales y puntos de emisión cargados.
  • Canal SIFEN/e-Kuatia o autoimpresor en estado ready.
  • Certificado y credenciales vigentes.
  • Webhook, artefactos y reintentos probados con el sistema origen.

Checklist SIFEN

Usá el checklist de producción para ordenar responsabilidades entre negocio, contabilidad y desarrollo antes de enviar documentos reales.

Abrir checklist SIFEN