Primeros pasos¶
De cero a una factura emitida.
1. Instalar¶
Se instala como smartdocpy y se importa como smartdoc.
2. Conseguir una API Key¶
Generala desde el panel de SmartDoc, en la sección de API Keys del contribuyente. Al crearla, marcá los permisos que va a usar.
Los permisos no son jerárquicos
write_invoices no habilita nada que pida read_invoices. Para seguir esta
guía marcá read_taxpayer, read_stamps, read_establishments,
read_dispatch_points, read_invoices y write_invoices.
Si falta alguno, el SDK levanta un PermissionError que dice cuál.
La clave se muestra una sola vez. Guardala en una variable de entorno:
El SDK apunta a la instancia de producción de SmartDoc. Si tu contribuyente está en una instancia propia, indicá su URL:
3. Crear el cliente¶
Si el contribuyente tiene más de un establecimiento o punto de expedición, indicá cuál usar:
4. Emitir una factura¶
factura = sd.invoices.create(
recipient=smartdoc.Recipient.entity(
ruc="80012345-1",
social_name="Cliente Ejemplo S.A.",
email="facturas@cliente.com.py",
),
items=[
smartdoc.Item("Consultoría de octubre", quantity=1, unit_amount=1100000),
],
)
print(factura.id, factura.status)
El estado inicial es pending o generated: la factura se encoló y todavía no
está aprobada.
El IVA de cada ítem¶
Sin indicar nada, el ítem se emite al 10%. Para los demás tratamientos:
sd.invoices.create(
recipient=...,
items=[
smartdoc.Item("Consultoría", quantity=1, unit_amount=1100000), # 10%
smartdoc.Item("Arroz", quantity=2, unit_amount=105000,
iva=smartdoc.Iva.FIVE), # 5%
smartdoc.Item("Libro", quantity=1, unit_amount=80000,
iva=smartdoc.Iva.EXEMPT), # exento
smartdoc.Item("Combo", quantity=1, unit_amount=1000000,
iva=smartdoc.Iva.MIXED_TEN, iva_base=60), # mixto
],
)
Los mixtos exigen iva_base: el porcentaje de la línea que está gravado.
Los precios van con IVA incluido
En Paraguay el IVA está contenido en el precio, no se suma. Si tu sistema guarda precios sin IVA, sumáselo antes de armar el ítem.
5. Esperar la aprobación¶
factura = sd.invoices.wait_until_final(factura.id)
print(factura.status) # DocumentStatus.APPROVED_BY_SET
print(factura.cdc)
print(factura.is_approved) # True
Esto es para probar, no para producción
wait_until_final consulta hasta que el documento llegue a su estado final,
y eso consume cuota del límite de solicitudes por segundo.
En producción no se espera: se escucha. La aprobación llega por webhook. Ver Cómo integrar.
6. Descargar el KuDE¶
Devuelve una URL temporal al PDF, disponible una vez que el documento se generó.
7. Anular¶
sd.invoices.cancel(factura.id, reason="Error en el monto facturado")
anulada = sd.invoices.wait_until_final(factura.id)
print(anulada.status) # DocumentStatus.CANCELLED
Solo se puede anular un documento aprobado, y el motivo es obligatorio.
Si estás en una cuenta demo¶
Los documentos se generan de forma válida pero no se envían a la DNIT: la respuesta se simula. Todo lo anterior funciona igual, y además podés provocar los errores a voluntad.
Para que la DNIT rechace, usá uno de los dos RUC de receptor reservados:
rechazada = sd.invoices.create(
recipient=smartdoc.Recipient.entity(
ruc="99999901-7",
social_name="Prueba de rechazo",
),
items=[smartdoc.Item("Servicio", quantity=1, unit_amount=100000)],
)
rechazada = sd.invoices.wait_until_final(rechazada.id)
print(rechazada.is_error) # True
print(rechazada.error_code) # "0160"
print(rechazada.error_message)
| RUC del receptor | Resultado |
|---|---|
99999901-7 |
Rechazado por la DNIT, código 0160 |
99999902-4 |
Error de procesamiento de lote, código 0301 |
| cualquier otro | Aprobado |
Van con dígito verificador: "99999901-7", no "99999901".
Para cambiar el estado de un documento ya emitido:
Las dos vías disparan los mismos eventos y webhooks que el flujo real.
Si no estás en una cuenta demo¶
Todo lo que emitas se envía a la DNIT y tiene validez fiscal. Antes de correr los ejemplos, cambiá el receptor y los ítems por datos reales.
Para confirmar en qué tipo de cuenta estás:
Y ahora¶
Lo de arriba sirve para probar. Para integrar de verdad:
- Cómo integrar — las tres piezas que hay que implementar y el código de cada operación. Empezá por acá.
- Adaptar tu sistema — cómo traducir tu modelo de datos y qué revisar antes de producción.
- Los catálogos listan los valores válidos de cada campo.