Tutorial: Generar nota de crédito libre (devolución)
¡Hola! Te voy a explicar paso a paso cómo generar una nota de crédito electrónica libre por devolución usando nuestra API. Este flujo es ideal cuando querés emitir una nota de crédito por devolución, porque el endpoint final arma todo en una sola solicitud.
La idea es que primero prepares todos los datos y luego hagas una única llamada a la API.
Entorno
Sección titulada «Entorno»URL base: https://api.guarani.app
Necesitás un token válido en el encabezado x-api-key: Bearer <access_token> para todas las llamadas.
¿Qué vamos a hacer?
Sección titulada «¿Qué vamos a hacer?»- Consultar el timbrado (autorización de la SET).
- Preparar los datos del cliente.
- Preparar las mercaderías y/o servicios con sus precios vigentes.
- Definir los campos de la nota de crédito.
- Emitir la nota con la API.
- Consultar el estado del documento electrónico.
Requisitos previos
Sección titulada «Requisitos previos»- Timbrado vigente y asociado al establecimiento/punto de expedición.
- Identificadores de ciudad, unidades de medida, marcas y clasificaciones listos.
- Motivo entre 6 y 30 caracteres (
motivo_descripcion).
Paso 1: Consultar el timbrado
Sección titulada «Paso 1: Consultar el timbrado»¿Por qué necesitás consultar el timbrado?
Sección titulada «¿Por qué necesitás consultar el timbrado?»El timbrado es la autorización que te da la SET (Secretaría de Estado de Tributación) para emitir documentos electrónicos. Contiene información importante que necesitás incluir en cada nota de crédito:
- numero_timbrado: El número de autorización de la SET
- numero_establecimiento: El código de tu local o sucursal
- punto_expedicion: El punto desde donde emitís los documentos
¿Cómo consultar el timbrado?
Sección titulada «¿Cómo consultar el timbrado?»Hacé una consulta al endpoint de timbrados:
curl -X GET "https://api.guarani.app/timbrados?page=1&limit=100" \ -H "x-api-key: Bearer <access_token>" \ -H "Accept: application/json" | jqNota: Reemplazá
<access_token>con un token JWT válido proporcionado por el equipo Guarani.
Para más información sobre timbrados, consultá la documentación completa en Obtener lista de timbrados.
Paso 2: Preparar los datos del cliente
Sección titulada «Paso 2: Preparar los datos del cliente»Aunque la API arma todo en una sola solicitud, es buena práctica validar los datos del cliente previamente (o crearlo en el sistema para reutilizarlo).
Obtener ciudad y validar documento
Sección titulada «Obtener ciudad y validar documento»- Ver como obtener la lista de ciudades para encontrar el
ciudad_id. - Ver como validar un RUC para validar RUC o cédula.
Estructura de cliente que vas a enviar dentro de la nota
Sección titulada «Estructura de cliente que vas a enviar dentro de la nota»| Campo | Requerido | Descripción |
|---|---|---|
tipo_persona | Sí | Tipo de persona. Ver tabla de tipos de personas |
tipo_documento | Sí | Tipo de documento de identidad. Ver tabla de tipos de documentos |
documento | Sí | Número de CI o RUC. |
nombre | Sí | Nombre completo o razón social. |
nombre_fantasia | No | Nombre comercial (si aplica). |
nacionalidad | Sí | Código ISO 3166-1 alfa-3 (ej: PRY). |
fecha_nacimiento | Sí | Formato DD/MM/YYYY. |
whatsapp | Sí | Número en formato internacional. |
email | Sí | Correo del cliente. |
direccion | Sí | Dirección física. |
numero_casa | No | Número de casa. |
barrio | No | Barrio/zona. |
ciudad_id | Sí | UUID de la ciudad. Ver como obtener la lista de ciudades |
Paso 3: Preparar mercaderías y servicios
Sección titulada «Paso 3: Preparar mercaderías y servicios»La API admite arrays de mercaderias y servicios. Podés enviar solo uno de los dos o ambos combinados.
Identificadores necesarios
Sección titulada «Identificadores necesarios»unidad_medida_venta_id: Ver como obtener la lista de unidades de medidaestablecimiento_id: para asignar precios (el mismo del timbrado). Ver como obtener la lista de establecimientos
Campos para mercaderías
Sección titulada «Campos para mercaderías»| Campo | Requerido | Descripción |
|---|---|---|
codigo_interno | Sí | Código interno de la mercadería. Ver tabla de código interno. |
codigo_original | No | Código original de la mercadería. |
codigo_barra | No | Código de barras de la mercadería. |
codigo_fabricante | No | Código del fabricante de la mercadería. |
descripcion | Sí | Descripción de la mercadería. |
descripcion_larga | No | Descripción extendida de la mercadería. |
observacion | No | Observaciones de la mercadería. |
unidad_medida_venta_id | Sí | UUID de la unidad de medida de venta. |
marca | No | Marca de la mercadería. |
clasificacion | Sí | Objeto { codigo, nombre } con la clasificación SIFEN. |
cantidad | Sí | Cantidad devuelta. |
precio_unitario_original | Sí | Precio original facturado. |
precio_unitario | Sí | Objeto con montos por IVA (0, 5, 10). |
Campos para servicios
Sección titulada «Campos para servicios»| Campo | Requerido | Descripción |
|---|---|---|
codigo_interno | Sí | Código interno del servicio. Ver tabla de código interno. |
descripcion | No | Descripción del servicio. |
descripcion_larga | No | Descripción extendida del servicio. |
observacion | No | Observaciones del servicio. |
unidad_medida_venta_id | Sí | UUID de la unidad de medida de venta. |
clasificacion | Sí | Objeto { codigo, nombre } con la clasificación SIFEN. |
cantidad | Sí | Cantidad devuelta. |
precio_unitario_original | Sí | Precio original facturado. |
precio_unitario | Sí | Objeto IVA (0, 5, 10). |
Ejemplo de objetos preparados
Sección titulada «Ejemplo de objetos preparados»- Mercaderías
{ "mercaderias": [ { "codigo_interno": "01-1234567", "codigo_original": "672", "codigo_barra": "1234567890", "codigo_fabricante": "1234567890", "descripcion": "Mercadería de ejemplo", "descripcion_larga": "Descripción larga de la mercadería", "observacion": "Observación de la mercadería", "unidad_medida_venta_id": "5f49c6c1-d622-4f5b-9d8b-2d1636b584ab", "marca": "Marca de ejemplo", "clasificacion": { "codigo": "99", "nombre": "Sin Definir" }, "cantidad": 1, "precio_unitario_original": 100000, "precio_unitario": { "0": 0, "5": 0, "10": 100000 } } ]}- Servicios
{ "servicios": [ { "codigo_interno": "02-1234567", "descripcion": "Servicio de ejemplo", "unidad_medida_venta_id": "5f49c6c1-d622-4f5b-9d8b-2d1636b584ab", "clasificacion": { "codigo": "99", "nombre": "Sin Definir" }, "cantidad": 1, "precio_unitario_original": 150000, "precio_unitario": { "0": 0, "5": 0, "10": 150000 } } ]}Paso 4: Definir los campos de la nota de crédito electronica completa
Sección titulada «Paso 4: Definir los campos de la nota de crédito electronica completa»Campos de la nota de crédito electronica completa
Sección titulada «Campos de la nota de crédito electronica completa»nota_credito (objeto)
Sección titulada «nota_credito (objeto)»| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
moneda | string | Sí | Código ISO de la moneda (PYG, USD, etc.). Debe coincidir con la moneda del documento original. |
cotizacion | number | Sí | Cotización respecto al guaraní. Para operaciones en PYG, enviá 1. |
cliente | object | Sí | Datos completos del receptor (ver Paso 2). |
motivo_descripcion | string | Sí | Motivo comercial entre 6 y 30 caracteres. Se imprime en la nota y lo valida la SET. |
numero_timbrado | string | Sí | Timbrado electrónico activo de tu empresa. |
numero_establecimiento | string | Sí | Establecimiento (3 dígitos) asociado al timbrado. |
punto_expedicion | string | Sí | Punto de expedición (3 dígitos) desde el cual emitís la nota. |
total | number | Sí | Total Debe ser igual a la suma de los ítems de la suma de todos los precios unitarios por su cantidad. |
Tip: mantené
monedaycotizacioniguales a los de la factura original y asegurate de quetotalcoincida con el desglose de ítems para evitar rechazos.
documentos_asociados (objeto)
Sección titulada «documentos_asociados (objeto)»| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
tipo_documento_asociado | number | Sí | Tipo de documento asociado. Ver tabla de tipos de documentos asociados. |
impreso | object | Condicional | Se envía cuando tipo = 2. Contiene la información del comprobante físico. |
electronico | object | Condicional | Se envía cuando tipo = 1. Incluye el CDC y datos del documento electrónico original. Ver como obtener el CDC. |
impreso (requerido si tipo_documento_asociado = 2)
Sección titulada «impreso (requerido si tipo_documento_asociado = 2)»| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
numero_timbrado_documento_asociado | string | Sí | Timbrado del documento impreso original. |
numero_establecimiento_documento_asociado | string | Sí | Establecimiento del documento impreso original (3 dígitos). |
punto_expedicion_documento_asociado | string | Sí | Punto de expedición del documento impreso original (3 dígitos). |
fecha_emision_documento_asociado | string | Sí | Fecha de emisión en formato DD/MM/YYYY. |
numero_documento_asociado | string | Sí | Número del documento (ej.: 0000001). |
tipo_documento_impreso | number | Sí | Código SIFEN del tipo de documento. Ver tabla de tipos de documentos |
electronico (requerido si tipo_documento_asociado = 1)
Sección titulada «electronico (requerido si tipo_documento_asociado = 1)»| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
cdc | string | Sí | CDC del documento electrónico original. Ver como obtener el CDC. |
items (objeto)
Sección titulada «items (objeto)»| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
mercaderias | array | Opcional | Lista de mercaderías acreditadas. Cada elemento sigue la estructura explicada en el Paso 3. |
servicios | array | Opcional | Lista de servicios acreditados. Usa también la estructura del Paso 3. |
- Podés enviar solo mercaderías, solo servicios o ambos.
- Las cantidades no pueden exceder lo facturado originalmente.
- No mezcles ítems de distintos carritos/facturas porque la API lo rechaza.
Bandera jsonDE
Sección titulada «Bandera jsonDE»| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
jsonDE | boolean | No | Bandera opcional en la raíz del payload. Si la enviás en true, la respuesta incluye el XML transformado a JSON. |
Si omitís este campo se asume false.
⚠️ Importante: El campo
totaldebe coincidir EXACTAMENTE con la suma de todos los ítems de la suma de todos los precios unitarios por su cantidad o la emisión será rechazada.
Paso 5: Enviar todo completo a la API
Sección titulada «Paso 5: Enviar todo completo a la API»A continuación tenés un ejemplo completo que crea la nota con cliente, mercaderías, servicios, motivo en un solo paso.
Ejemplo completo con documento físico asociado:
curl -X POST 'https://api.guarani.app/simplificado/notas/credito/devolucion/libre' \ -H 'Content-Type: application/json' \ -H 'x-api-key: Bearer <access_token>' \ -d '{ "jsonDE": false, "nota_credito": { "moneda": "PYG", "cotizacion": 1, "cliente": { "tipo_persona": 1, "tipo_documento": 1, "documento": "1234567", "nombre": "Cliente de ejemplo", "nombre_fantasia": "", "nacionalidad": "PRY", "fecha_nacimiento": "01/01/1990", "whatsapp": "", "email": "[email protected]", "direccion": "Dirección de ejemplo", "numero_casa": "", "barrio": "Barrio de ejemplo", "ciudad_id": "67ef2e9f-0fa7-43e7-ad5e-87a694e56341" }, "motivo_descripcion": "Devolución", "numero_timbrado": "80158040", "numero_establecimiento": "001", "punto_expedicion": "002", "total": 250000 }, "documentos_asociados": { "tipo_documento_asociado": 2, "impreso": { "numero_timbrado_documento_asociado": "12345678", "numero_establecimiento_documento_asociado": "001", "punto_expedicion_documento_asociado": "001", "fecha_emision_documento_asociado": "22/03/2025", "numero_documento_asociado": "0000001", "tipo_documento_impreso": 1 } }, "items": { "mercaderias": [ { "codigo_interno": "01-1234567", "codigo_original": "123", "codigo_barra": "", "codigo_fabricante": "", "descripcion": "Mercadería de ejemplo", "descripcion_larga": "", "observacion": "", "unidad_medida_venta_id": "5f49c6c1-d622-4f5b-9d8b-2d1636b584ab", "marca": "Marca de ejemplo", "clasificacion": { "codigo": "01", "nombre": "Clasificación de ejemplo" }, "cantidad": 1, "precio_unitario_original": 100000, "precio_unitario": { "0": 0, "5": 0, "10": 100000 } } ], "servicios": [ { "codigo_interno": "02-1234567", "descripcion": "Servicio de ejemplo", "unidad_medida_venta_id": "5f49c6c1-d622-4f5b-9d8b-2d1636b584ab", "clasificacion": { "codigo": "01", "nombre": "Clasificación de ejemplo" }, "cantidad": 1, "precio_unitario_original": 150000, "precio_unitario": { "0": 0, "5": 0, "10": 150000 } } ] } }' | jqEjemplo de respuesta (documento impreso)
Sección titulada «Ejemplo de respuesta (documento impreso)»{ "success": true, "codigo": "200", "message": "Operación realizada correctamente.", "data": { "numero_timbrado": "80158040", "numero_documento": "001-002-0000105", "serie": "AA", "cdc": "05801580404001002000010512025111211819934403", "estado_sifen": { "estado": "Aprobado", "mensaje": "Autorización del DE satisfactoria" }, "xml": "https://api.guarani.app/sifen/xml/05801580404001002000010512025111211819934403", "qr": "https://ekuatia.set.gov.py/consultas/qr?nVersion=150&Id=05801580404001002000010512025111211819934403&dFeEmiDE=323032352d31312d31325431303a32383a3338&dNumIDRec=5839704&dTotGralOpe=250000.00000000&dTotIVA=22727.27272727&cItems=2&DigestValue=4563624b7237443345517171417a525659455453552b526674694c48503065555652326c76702f674f74413d&IdCSC=0001&cHashQR=51682d1c7b7125e8bab601dd6a77d70ba0dca530c4a21bce773f652d5eb3ddaf" }}Ejemplo completo con documento electrónico asociado:
curl -X POST 'https://api.guarani.app/simplificado/notas/credito/devolucion/libre' \ -H 'Content-Type: application/json' \ -H 'x-api-key: Bearer <access_token>' \ -d '{ "jsonDE": false, "nota_credito": { "moneda": "PYG", "cotizacion": 1, "cliente": { "tipo_persona": 1, "tipo_documento": 1, "documento": "1234567", "nombre": "Cliente de ejemplo", "nombre_fantasia": "", "nacionalidad": "PRY", "fecha_nacimiento": "01/01/1990", "whatsapp": "", "email": "[email protected]", "direccion": "Dirección de ejemplo", "numero_casa": "", "barrio": "Barrio de ejemplo", "ciudad_id": "67ef2e9f-0fa7-43e7-ad5e-87a694e56341" }, "motivo_descripcion": "Devolución", "numero_timbrado": "80158040", "numero_establecimiento": "001", "punto_expedicion": "002", "total": 250000 }, "documentos_asociados": { "tipo_documento_asociado": 1, "electronico": { "cdc": "05801580404001002000009212025111112609055674" } }, "items": { "mercaderias": [ { "codigo_interno": "01-1234567", "codigo_original": "123", "codigo_barra": "", "codigo_fabricante": "", "descripcion": "Mercadería de ejemplo", "descripcion_larga": "", "observacion": "", "unidad_medida_venta_id": "5f49c6c1-d622-4f5b-9d8b-2d1636b584ab", "marca": "Marca de ejemplo", "clasificacion": { "codigo": "01", "nombre": "Clasificación de ejemplo" }, "cantidad": 1, "precio_unitario_original": 100000, "precio_unitario": { "0": 0, "5": 0, "10": 100000 } } ], "servicios": [ { "codigo_interno": "02-1234567", "descripcion": "Servicio de ejemplo", "unidad_medida_venta_id": "5f49c6c1-d622-4f5b-9d8b-2d1636b584ab", "clasificacion": { "codigo": "01", "nombre": "Clasificación de ejemplo" }, "cantidad": 1, "precio_unitario_original": 150000, "precio_unitario": { "0": 0, "5": 0, "10": 150000 } } ] } }' | jqEjemplo de respuesta (documento electrónico)
Sección titulada «Ejemplo de respuesta (documento electrónico)»{ "success": true, "codigo": "200", "message": "Operación realizada correctamente.", "data": { "numero_timbrado": "80158040", "numero_documento": "001-002-0000109", "serie": "AA", "cdc": "05801580404001002000010912025111213769126114", "estado_sifen": { "estado": "Aprobado", "mensaje": "Autorización del DE satisfactoria" }, "xml": "https://api.guarani.app/sifen/xml/05801580404001002000010912025111213769126114", "qr": "https://ekuatia.set.gov.py/consultas/qr?nVersion=150&Id=05801580404001002000010912025111213769126114&dFeEmiDE=323032352d31312d31325431313a32313a3136&dNumIDRec=5839704&dTotGralOpe=250000.00000000&dTotIVA=22727.27272727&cItems=2&DigestValue=4f7266346672626241487933597a62756c2f564c564869582f394369684644426f4c49534b6a75754437673d&IdCSC=0001&cHashQR=0ff17fd2025cd7e4ced8b037f60cd45d51c9195e0a179e336ef445477e11727c" }}Paso 6: Consultar el estado del documento electrónico
Sección titulada «Paso 6: Consultar el estado del documento electrónico»Esperá unos 10 minutos y consultá:
GET /sifen/consultas/estado/cdc/{cdc}curl -X GET "https://api.guarani.app/sifen/consultas/estado/cdc/05801580404001002000009212025111112609055674" \ -H "x-api-key: Bearer <access_token>" \ -H "Accept: application/json" | jqestado: "Aprobado" confirma que SIFEN aceptó el documento. Si ves Rechazado, revisá el mensaje devuelto para corregirlo y emitir nuevamente.
Resumen del flujo
Sección titulada «Resumen del flujo»- Consultás el timbrado para obtener
numero_timbrado,numero_establecimientoypunto_expedicion. - Preparás cliente, mercaderías/servicios, motivo y documento asociado (si es necesario).
- Enviás todo completo a la API en un solo paso con
POST /simplificado/notas/credito/devolucion/libre. - Verificás el estado del documento electrónico con
GET /sifen/consultas/estado/cdc/{cdc}.