⚡ SIFEN · Factura electrónica · Paraguay

Facturación electrónica por API

Su sistema sigue gestionando ventas, stock y cobros. CDEpos numera, firma, envía al SET y devuelve CDC, QR, KuDE y XML — con una sola llamada.

Facturación electrónica (SIFEN) por API — guía para sistemas externos

Para empresas que ya tienen su propio sistema (ERP, facturador, e-commerce, software a medida) y solo necesitan emitir factura electrónica en Paraguay. Su sistema sigue gestionando ventas, stock y cobros; CDEpos se encarga de la parte fiscal: numera con el timbrado electrónico, firma con el certificado del contribuyente, envía al SET (SIFEN), devuelve el CDC + QR + KuDE (PDF) + XML, consulta la aprobación, anula, emite notas de crédito y envía el comprobante al cliente por email.

Base URL: https://app.micdepos.com/connector/api · Formato: JSON · Auth: OAuth2 (Bearer). Documentación general de la API: https://app.micdepos.com/doc.


1. Cómo funciona (resumen)

Su sistema                                CDEpos                                  SET / SIFEN
──────────                                ──────                                  ───────────
POST /sell  {cliente, ítems, pago,        crea la venta, numera (timbrado
            sifen_emit: true}      ───►   electrónico), arma el XML del DE,
                                          lo firma y lo envía por lote    ───►    recibe el lote (0300)
            ◄─── 200 {id, invoice_no,
                     sifen: {cdc, qr}}
                                          cron cada 10 min consulta el lote ───►  aprobado / rechazado
◄── webhook sifen.aprobado (POST firmado a su URL)   o   GET /sell/{id}/sifen/status
GET /sell/{id}/pdf           ───►         KuDE (PDF) / XML / email al cliente

2. Requisitos previos (una sola vez)

Lo configura CDEpos junto con el contribuyente:

  1. Negocio en CDEpos con el módulo de factura electrónica activo (sifen_active en el negocio y en la sucursal emisora).
  2. Certificado digital (.p12 del contribuyente, emitido por una PSC habilitada) cargado en la sucursal, con su contraseña.
  3. Timbrado electrónico vigente (esquema de numeración electrónico con timbrado, fecha de inicio/fin, establecimiento y punto de expedición) asignado a la sucursal.
  4. Ambiente: test para homologar, produccion cuando el SET habilita al contribuyente. (En demo el XML se firma localmente y no se envía.)
  5. Tasas de IVA del negocio: IVA 10%, IVA 5% y Exenta (vienen por defecto).
  6. Usuario API con permisos: sell.create, customer.view, customer.create (alta de clientes), product.create (alta automática de ítems por SKU), invoice.view_pdf (emitir / KuDE / XML), sell.view.
  7. Credenciales OAuth (Client ID, Client Secret, usuario y contraseña API): las genera el administrador del negocio en CDEpos → Conector / Clientes API. El secret se muestra una sola vez.

3. Autenticación

curl -X POST https://app.micdepos.com/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "password",
    "client_id": "<CLIENT_ID>",
    "client_secret": "<CLIENT_SECRET>",
    "username": "<USUARIO_API>",
    "password": "<PASSWORD_API>",
    "scope": "*"
  }'

Respuesta: {"token_type":"Bearer","expires_in":...,"access_token":"...","refresh_token":"..."}. Enviar en cada llamada Authorization: Bearer <access_token> y Accept: application/json. Renovar con grant_type: refresh_token antes de que venza.


4. Emitir una factura electrónica (una llamada)

POST /connector/api/sell — el cuerpo es un arreglo sells (normalmente con una venta).

{
  "sells": [
    {
      "location_id": 1,
      "status": "final",
      "idempotency_key": "ERP-FAC-2026-000123",
      "sifen_emit": true,
      "transaction_date": "2026-08-19 10:30:00",
      "contact": {
        "ruc": "80012345-6",
        "name": "Distribuidora Ejemplo SA",
        "email": "[email protected]",
        "mobile": "0981123456",
        "address": "Av. Monseñor Rodríguez 123, Ciudad del Este"
      },
      "products": [
        { "sku": "SRV-MANT-01", "name": "Servicio de mantenimiento", "quantity": 1,
          "unit_price_inc_tax": 550000, "tax_rate": 10 },
        { "sku": "LIB-0001", "name": "Libro técnico", "quantity": 2,
          "unit_price_inc_tax": 120000, "tax_rate": 5 },
        { "sku": "EXE-0001", "name": "Ítem exento", "quantity": 1,
          "unit_price_inc_tax": 30000, "tax_rate": 0 }
      ],
      "payments": [
        { "method": "cash", "amount": 820000 }
      ],
      "sale_note": "Pedido ERP #98765"
    }
  ]
}

Campos clave

Campo Obligatorio Descripción
location_id sí Sucursal emisora (la que tiene certificado y timbrado). GET /business-location lista las sucursales.
status sí final.
idempotency_key recomendado Id único de la factura en su sistema (≤ 64). Si reintenta con la misma key, CDEpos devuelve la misma venta (duplicate: true) en vez de crear otra. La key es de cada comercio: la misma key en otro comercio es otra venta.
sifen_emit sí (FE) true → emite la factura electrónica en la misma llamada. Implica document_type: "factura_electronica".
document_type opcional factura_electronica (se asume con sifen_emit) / comprobante (interno, sin SIFEN).
transaction_date opcional Y-m-d H:i:s; por defecto ahora.
contact sí* Cliente por documento — ver abajo. Alternativa: contact_id de un cliente ya cargado.
products[] sí Ítems — ver abajo.
payments[] opcional Pagos. Si cubren el total → factura contado; si no hay pagos o son parciales → crédito (la condición de pago del DE sale de acá). method: cash, card, bank_transfer, cheque, other.
sale_note opcional Observación (aparece en el KuDE).
discount_type / discount_amount opcional Descuento global (fixed o percentage).

Cabecera Idempotency-Key. Desde el 15/10/2026, si el cuerpo no trae idempotency_key y el pedido trae una sola venta, la cabecera Idempotency-Key también se guarda con la venta como su clave. Deduplica de forma persistente, por comercio, y no vence. Antes la cabecera sólo deduplicaba 24 h y se perdía en cada actualización del servidor. Si manda las dos, manda la del cuerpo.

contact — cliente por documento

Campo Descripción
ruc (o doc) RUC con DV (80012345-6) o CI (4671379). Si ya existe un cliente con ese documento se reutiliza; si no, se crea con los datos enviados.
name Nombre / razón social. Obligatorio solo si el documento es nuevo.
email, mobile, address, city Opcionales; si el cliente existe y no los tenía, se completan.
sin_nombre: true Consumidor final "Sin nombre" (cliente por defecto del negocio).
id Alternativa: id de un contacto existente.

Para validar un RUC contra el SET antes de facturar: GET /connector/api/contactapi-lookup?doc=80012345-6.

products[] — ítems

Campo Descripción
sku Código del ítem en su sistema. Si existe en el catálogo de CDEpos se usa; si no, se crea automáticamente (ítem sin control de stock) con name, el IVA y el precio enviados.
name Descripción del ítem (sale en el DE y en el KuDE). Obligatoria la primera vez que aparece un sku.
quantity Cantidad (decimal permitido).
unit_price_inc_tax Precio unitario con IVA (el habitual en Paraguay). CDEpos calcula el neto.
unit_price Alternativa: precio unitario sin IVA.
tax_rate 10, 5 o 0 (exento). Alternativa: tax_rate_id (ids en GET /tax). Sin tax_rate ni tax_rate_id la línea va exenta.
discount_amount / discount_type Descuento por línea.
product_id + variation_id Alternativa clásica: ítem ya cargado en CDEpos (GET /product).

Respuesta (200)

[
  {
    "id": 614885,
    "invoice_no": "001-001-0000123",
    "transaction_date": "2026-08-19 10:30:00",
    "final_total": "820000.0000",
    "payment_status": "paid",
    "contact_id": 8415,
    "sifen_cdc": "01023665700001001000001212026081910119614641",
    "sifen_qr": "https://ekuatia.set.gov.py/consultas/qr?nVersion=150&Id=0102366570...",
    "sifen_process": "lote_recibido",
    "sifen": {
      "emitted": true,
      "cdc": "01023665700001001000001212026081910119614641",
      "qr": "https://ekuatia.set.gov.py/consultas/qr?...",
      "process": "lote_recibido",
      "links": {
        "status": "https://app.micdepos.com/connector/api/sell/614885/sifen/status",
        "pdf":    "https://app.micdepos.com/connector/api/sell/614885/pdf",
        "xml":    "https://app.micdepos.com/connector/api/sell/614885/sifen/xml"
      }
    },
    "invoice_url": "https://app.micdepos.com/invoice/…"
  }
]

5. Consultar el estado SIFEN

GET /connector/api/sell/{id}/sifen/status

{ "data": {
    "transaction_id": 614885,
    "invoice_no": "001-001-0000123",
    "sifen_cdc": "0102…",
    "sifen_process": "aprobado_set",
    "ambiente": "produccion",
    "ultimo_envio": { "estado": "APROBADO", "cod_res_envio": "0260",
                      "msg_res_envio": "Autorización del DE satisfactoria", "intentos": 1 },
    "qr_url_set": "https://ekuatia.set.gov.py/consultas/qr?nVersion=150&Id=0102…",
    "email": { "state": "sent" }
} }
sifen_process Significado Qué hacer
generado XML firmado (ambiente demo) —
lote_recibido El SET recibió el lote (cód. 0300); procesando Consultar de nuevo en 1–10 min
aprobado_set Aprobada por el SET Listo
rechazado_set Rechazada por el SET (msg_res_envio dice por qué) Corregir y emitir una nueva; la rechazada no es válida
error_envio No se pudo enviar (red/SET caído) POST /sell/{id}/sifen/retry

Sugerencia: consultar cada 1–2 minutos hasta estado final (el proceso interno revisa los lotes cada 10 minutos). Una factura con CDC ya puede imprimirse y entregarse; el SET la valida en ese lapso. Mejor aún: suscribir un webhook (§5.1) y no consultar.

5.1 Webhooks (recomendado): CDEpos le avisa a su sistema

En vez de consultar el estado, registre una URL y CDEpos le hace un POST cuando el documento cambia de estado:

Evento Cuándo
sifen.aprobado El SET aprobó la factura / nota de crédito
sifen.rechazado El SET la rechazó (ultimo_envio.msg_res_envio explica por qué)
sifen.error No se pudo enviar al SET (se reintenta; si persiste, POST /sell/{id}/sifen/retry)
sifen.anulado El evento de anulación fue aceptado por el SET
ping Prueba manual (POST /sifen/webhooks/{id}/test)

Registrar (usuario administrador del negocio o con business_settings.access):

curl -X POST https://app.micdepos.com/connector/api/sifen/webhooks \
  -H "Authorization: Bearer <TOKEN>" -H "Content-Type: application/json" \
  -d '{ "url": "https://mi-erp.com/webhooks/cdepos", "events": ["sifen.aprobado","sifen.rechazado","sifen.error","sifen.anulado"], "description": "ERP producción" }'

Respuesta: {"data": {"id": 1, "url": "...", "secret": "whsec_…"}} — guarde el secret: se muestra una sola vez (se puede rotar con PUT /sifen/webhooks/{id} { "rotate_secret": true }). Máximo 5 webhooks por negocio; la URL debe ser https pública.

Lo que recibe su endpoint (POST, Content-Type: application/json):

X-CDEpos-Event: sifen.aprobado
X-CDEpos-Delivery: 3f0c…-uuid            (id único de la entrega; úselo para no procesar dos veces)
X-CDEpos-Timestamp: 1755610000
X-CDEpos-Signature: sha256=<HMAC-SHA256 del cuerpo crudo con el secret>
User-Agent: CDEpos-Webhooks/1.0
{
  "id": "3f0c…", "event": "sifen.aprobado", "created_at": "2026-08-19T10:42:00-03:00",
  "business_id": 12,
  "data": {
    "transaction_id": 614885, "type": "sell",
    "invoice_no": "001-001-0000123", "idempotency_key": "ERP-FAC-2026-000123",
    "transaction_date": "2026-08-19 10:30:00", "final_total": 820000, "payment_status": "paid",
    "cdc": "0102366570…", "qr": "https://ekuatia.set.gov.py/consultas/qr?…", "sifen_process": "aprobado_set",
    "contact": { "id": 8415, "name": "Distribuidora Ejemplo SA", "tax_number": "80012345-6" },
    "ultimo_envio": { "tipo": "ASYNC", "estado": "APROBADO", "cod_res_envio": "0260", "msg_res_envio": "Autorización del DE satisfactoria" },
    "links": { "status": "…/sell/614885/sifen/status", "pdf": "…/sell/614885/pdf", "xml": "…/sell/614885/sifen/xml" }
  }
}

type = sell (factura) o sell_return (nota de crédito). idempotency_key es la clave que usted mandó al crear la venta: con eso enlaza el aviso con su registro sin guardar ids ajenos.

Verificar la firma (obligatorio): calcule HMAC-SHA256(secret, cuerpo crudo) y compárelo con X-CDEpos-Signature (sin sha256=). Ejemplo PHP:

$raw = file_get_contents('php://input');
$ok  = hash_equals('sha256='.hash_hmac('sha256', $raw, $SECRET), $_SERVER['HTTP_X_CDEPOS_SIGNATURE'] ?? '');

Responder 2xx rápido (< 8 s). Cualquier otra respuesta o timeout se reintenta con espera creciente: 1 min, 5 min, 30 min, 2 h, 6 h, 12 h (6 intentos). Un mismo evento de una misma factura se entrega una sola vez por webhook, pero diseñe su receptor idempotente por X-CDEpos-Delivery.

Gestión: GET /sifen/webhooks · PUT /sifen/webhooks/{id} (url, events, is_active, rotate_secret) · DELETE /sifen/webhooks/{id} · POST /sifen/webhooks/{id}/test (ping) · GET /sifen/webhooks/{id}/deliveries (historial con estado, intentos y último error) · POST /sifen/webhooks/{id}/deliveries/{deliveryId}/retry.

5.2 Reconciliación

Para cruzar su sistema con CDEpos (cierre del día, reproceso tras una caída):


6. Documentos

Acción Endpoint
KuDE (PDF) oficial GET /connector/api/sell/{id}/pdf → application/pdf
XML firmado GET /connector/api/sell/{id}/sifen/xml
Enviar por email al cliente (KuDE + XML adjuntos) POST /connector/api/sell/{id}/sifen/email { "to_email": "...", "subject": "..." }
Detalle de la venta (líneas, pagos, ids) GET /connector/api/sell/{id}
Listado GET /connector/api/sell?start_date=…&end_date=…

El negocio también puede activar el email automático al aprobarse el DE (sin llamadas de su parte).


7. Anulación y notas de crédito


8. Errores

HTTP Caso Detalle
401 Token vencido / inválido Renovar token
403 Permiso faltante El mensaje dice cuál (sell.create, invoice.view_pdf, …)
422 Validación message legible: products[0].sku 'X' no existe… y no vino "name", tax_rate: el negocio no tiene una tasa de IVA 7%, contact: el documento … no está registrado y no vino "name", idempotency_key: máximo 64 caracteres
422 CLAVE_YA_USADA La key ya está registrada: en otra operación del comercio (p. ej. una compra), en una venta fuera del alcance del usuario (otra sucursal, o de otro cajero con "ver sólo propias"), o, con la key de la cabecera, en una venta con otra sucursal, cliente o cantidad de productos La venta no se creó. Revisar en Ventas antes de cargarla de nuevo
503 OPERACION_EN_CURSO Otro pedido con la misma Idempotency-Key se está procesando todavía Trae Retry-After (segundos). Reintentar con la misma key después de ese tiempo: devuelve el resultado del primero, no crea otra venta. Vale para todo POST/PUT/DELETE con la cabecera
429 Límite de pedidos por minuto Trae Retry-After. Los reintentos con la misma key también cuentan
200 + sifen.error La venta se creó pero no se emitió Códigos: BUSINESS_NO_SIFEN, LOCATION_NO_SIFEN (sucursal sin FE), NO_CERT (sin certificado), TIMBRADO_VENCIDO, LAYOUT_NOT_KUDE (la venta no fue ruteada como FE: faltó sifen_emit/document_type o la config SIFEN de la sucursal está incompleta), XML_GEN_FAIL, EMIT_EXCEPTION
4xx/5xx en POST /sell La venta no se creó Reintentar con la misma idempotency_key es seguro

9. Buenas prácticas

  1. Usar siempre idempotency_key (el número interno de su factura/pedido) y reintentar con la misma ante timeouts.
  2. Guardar id, invoice_no, sifen_cdc y sifen_qr en su sistema; mostrar el QR / link qr_url_set en sus comprobantes.
  3. Enviar el RUC con dígito verificador y el nombre como figura en el SET (contactapi-lookup lo consulta); para consumidor final usar sin_nombre.
  4. Mandar precios con IVA (unit_price_inc_tax) y la tasa (tax_rate): así el DE refleja exactamente lo que cobró.
  5. Homologar primero en ambiente test (mismos endpoints, la sucursal en sifen_ambiente = test), luego pasar a producción.
  6. Suscribir un webhook (§5.1) para enterarse de aprobado_set / rechazado_set sin consultar; atender los rechazos el mismo día. Si no puede exponer una URL, consulte el estado hasta el final.
  7. No borrar facturas: si hubo error, anular (≤ 48 h) o nota de crédito.

10. Checklist de salida a producción


Referencia rápida de endpoints

Método Ruta Uso
POST /oauth/token Token OAuth
POST /connector/api/sell Crear + emitir factura (sifen_emit)
GET /connector/api/sell/{id} Detalle (líneas, pagos, CDC)
GET /connector/api/sell/{id}/sifen/status Estado SIFEN
POST /connector/api/sell/{id}/sifen/emit Emitir (si no se emitió en la creación)
POST /connector/api/sell/{id}/sifen/retry Reintentar envío con error
GET /connector/api/sell/{id}/pdf KuDE PDF
GET /connector/api/sell/{id}/sifen/xml XML firmado
POST /connector/api/sell/{id}/sifen/email Enviar al cliente
POST /connector/api/sell/{id}/sifen/cancel Anular (evento SET)
POST /connector/api/sell-return Nota de crédito electrónica
GET /connector/api/sell?idempotency_key= Reconciliación por su clave (también sifen_cdc, sifen_process, invoice_no)
GET/POST /connector/api/sifen/webhooks Listar / registrar webhook (secret una sola vez)
PUT/DELETE /connector/api/sifen/webhooks/{id} Editar (url, events, is_active, rotate_secret) / borrar
POST /connector/api/sifen/webhooks/{id}/test Ping de prueba
GET /connector/api/sifen/webhooks/{id}/deliveries Historial de entregas (+ /{deliveryId}/retry)
GET /connector/api/contactapi-lookup?doc= Consultar RUC/CI en el SET
GET /connector/api/tax Tasas de IVA (ids)
GET /connector/api/business-location Sucursales
GET /connector/api/sifen-catalogs Catálogos SIFEN (departamentos, ciudades, motivos NC…)

CDEpos — CDE Online · Ciudad del Este, Paraguay · soporte: [email protected]