aalonzolu / digifact
PHP SDK for Digifact FEL Guatemala e-invoicing API (v2)
Package info
Language:Python
pkg:composer/aalonzolu/digifact
Requires
- php: >=8.1
- ext-bcmath: *
- ext-curl: *
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^10 || ^11
README
SDKs para la API Digifact FEL NUC GT — facturación electrónica SAT Guatemala.
| SDK | Paquete | Versión mínima |
|---|---|---|
| Python | digifact-sdk (PyPI) |
Python 3.10+ |
| JavaScript | digifact-sdk (npm) |
Node 18+ |
| PHP | aalonzolu/digifact (Packagist) |
PHP 8.1+ |
| C# / .NET | Digifact.Fel (NuGet) |
.NET 8+ |
Instalación rápida
# Python pip install digifact-sdk # JavaScript npm install digifact-sdk # PHP composer require aalonzolu/digifact # C# / .NET dotnet add package Digifact.Fel
Uso básico (los 4 SDKs)
# Python from digifact_sdk import DigifactClient client = DigifactClient( taxid="12345678", username="FELUSER", password="...", environment="test", # o "production" ) result = client.invoice("CF", [ {"description": "Servicio", "qty": 1, "price": 100}, ]) print(result.auth_number)
// JavaScript import { DigifactClient } from 'digifact-sdk'; const client = new DigifactClient({ taxid: '12345678', username: 'FELUSER', password: '...', environment: 'test', }); const result = await client.invoice('CF', [ { description: 'Servicio', qty: 1, price: 100 }, ]); console.log(result.authNumber);
// PHP use Digifact\Fel\DigifactClient; $client = new DigifactClient([ 'taxid' => '12345678', 'username' => 'FELUSER', 'password' => '...', 'environment' => 'test', ]); $result = $client->invoice('CF', [ ['description' => 'Servicio', 'qty' => 1, 'price' => 100], ]); echo $result->authNumber;
// C# / .NET using Digifact.Fel; using var client = new DigifactClient(new DigifactOptions { Taxid = "12345678", Username = "FELUSER", Password = "...", Environment = "test", }); var result = await client.InvoiceAsync("CF", new[] { new LineItem { Description = "Servicio", Qty = 1, Price = 100 }, }); Console.WriteLine(result.AuthNumber);
Tipos de DTE soportados
| Método | DTE | Descripción |
|---|---|---|
invoice() |
FACT | Factura de consumidor final o NIT |
invoice() |
FCAM | Factura cambiaria con cuotas |
invoice() |
NABN | Nota de abono |
invoice() |
FESP | Factura especial (retención) |
invoice() |
RDON | Recibo por donación |
invoice() |
RECI | Recibo de colegiatura |
invoice() |
FPEQ | Factura pequeño contribuyente |
debitNote() |
NDEB | Nota de débito |
creditNote() |
NCRE | Nota de crédito parcial |
creditNoteTotal() |
— | Nota de crédito total (anulación) |
cancel() |
— | Anulación de DTE |
fuelInvoice() |
FACT+Combustible | Factura con IVA + impuesto PETROLEO |
ccaInvoice() |
FACT+CCA | Cobro por cuenta ajena |
lookupNit() |
— | Consulta nombre/dirección de un NIT en SAT |
lookupCui() |
— | Consulta el nombre de un CUI (DPI) en SAT |
getDte() |
— | Descarga un DTE ya emitido |
Configuración del cliente (común a los 4 SDKs)
Ordenados de más usados a menos usados.
| Parámetro | Requerido | Descripción |
|---|---|---|
taxid / Taxid |
✔ | NIT del emisor. |
username / Username |
✔ | Usuario Digifact (la parte después de GT.<NIT>.). |
password / Password |
✔* | Contraseña. *O bien token. |
token / Token |
✔* | Bearer token preobtenido. *O bien password. |
environment / Environment |
"test" (default) o "production". |
|
seller_name / SellerName |
Nombre del emisor. Para NIT individual es el nombre de la persona; para S.A. / S.E. es la razón social. Auto-consulta en SAT si se omite. | |
seller_address / SellerAddress |
Dirección del emisor. Auto-consulta en SAT si se omite. | |
branch_code / BranchCode |
Código del establecimiento (RTU). Default "1". |
|
branch_name / BranchName |
Nombre comercial de la sucursal, el mismo que aparece en la patente de comercio. Default "ESTABLECIMIENTO PRINCIPAL". |
|
afiliacion_iva / AfiliacionIva |
"GEN" (default), "PEQ" o "EXE". |
|
tipo_frase / TipoFrase |
Override global de TipoFrase (legacy). Mutuamente exclusivo con frases. |
|
escenario / Escenario |
Override global de CodigoEscenario (legacy). Mutuamente exclusivo con frases. |
|
frases / Frases |
Nuevo. Lista de frases {tipo_frase, escenario}. Reemplaza a tipo_frase/escenario. Mutuamente exclusivo con ellos. |
|
petroleo_rates / PetroleoRates |
Mapa código→tarifa PETROLEO para fuelInvoice() (sólo gasolineras). |
|
timeout / Timeout |
Timeout HTTP. Default 120s (JS: 120000 ms). | |
tipo_personeria / TipoPersoneria |
Código de personería del RTU. Sólo aplica a RDON. Default "1". |
Ver detalles y ejemplos por lenguaje en los READMEs respectivos.
Subsidio combustibles
El subsidio a la gasolina y al diésel finalizó el jueves 2 de julio de 2026 a las 24:00, antes de lo
previsto: el presupuesto de Q2 mil millones (Decreto 11-2026, reglamentado por el Acuerdo Gubernativo
64-2026) se agotó por la demanda. Por eso los SDKs nunca envían las frases TipoFrase=9, Escenario=18
ni TipoFrase=9, Escenario=19 por su cuenta — no hay fecha de corte que valga para todos.
Las estaciones con inventario adquirido bajo el subsidio deben mantener el precio rebajado hasta agotar ese
producto, sujeto a verificación. Mientras te quede ese inventario, manda las frases explícitamente con
frases; al agotarlo, deja de mandarlas:
client.fuel_invoice("CF", items, frases=[ {"tipo_frase": "1", "escenario": "1"}, # frase base {"tipo_frase": "9", "escenario": "18"}, {"tipo_frase": "9", "escenario": "19"}, ])
La leyenda del subsidio en la representación gráfica la genera Digifact a partir del XML certificado, no estos SDKs: al dejar de mandar las frases, deja de imprimirse sola.
Variables de entorno
DIGIFACT_TAXID=12345678 DIGIFACT_USERNAME=FELUSER DIGIFACT_PASSWORD=...
Estructura del repositorio
digifact-sdk/
├── python/ SDK Python — pyproject.toml, digifact_sdk/
├── javascript/ SDK JavaScript — package.json, src/
├── php/ SDK PHP — composer.json, src/
├── dotnet/ SDK C#/.NET — Digifact.Fel.csproj, *.cs
├── docs/ Documentación y colección Postman
│ └── postman/ Colección y ambiente para Postman
├── scripts/ Herramientas de validación y smoke tests
└── .github/
└── workflows/
├── ci.yml Tests en cada push/PR
└── publish.yml Publicación a PyPI/npm/Packagist/NuGet al hacer tag
Publicar una release
# Actualizar versiones en pyproject.toml y package.json, luego:
git tag v1.2.3
git push origin v1.2.3
El workflow publish.yml se activa automáticamente y publica los cuatro paquetes.