Skip to navigation

Emitir factura

Tres operaciones, mismo payload (MinimalInvoiceRequest):

OperaciónEfectoRespuesta
previewValida sin crear nada (no toca SIAT)200 vista previa
createGuarda borrador201 + Location: /v1/invoices/{id}
emitCrea y emite en el mismo request (ruta estrella, síncrona)200 + Location
emit por IDEmite un borrador existente200 (u OFFLINE)

Estados y ciclo post-emisión: Quickstart.

En esta página aprenderás: preview, create y emit con el mismo payload, descargas y errores del caso · Prerrequisitos: POS con CUIS/CUFD (Onboarding) · Tiempo: ~10 min · ¿Términos nuevos? Glosario.

Payload (MinimalInvoiceRequest)

CampoTipoObligatorioDescripción
point_of_sale_iduuidSíPOS activo de tu tenant, con CUIS/CUFD vigente
customerobjetoSíSnapshot del receptor (ver tabla)
itemsarraySí, ≥ 1Líneas (ver tabla; excepción: ajustes con reference_invoice_id copian líneas)
invoice_typestringNo, default salesale, education, credit_note, debit_note (+ aliases)
sectorstringNo, default auto (= 1)Código ("1", "11"…) o alias (sale, education)
dataobjetoNo, default {}Campos sectoriales de cabecera (Sectores)
layoutstringSolo sector 24nota_credito_debito o nota_fiscal_credito_debito
reference_invoice_iduuidSolo ajustes (24/29/47/48)Factura original del mismo tenant
paymentobjetoNo, default 1,1,1Si se envía, los 3 campos >0
totalnumberSolo sectores sin detalleTotal directo

customer

CampoTipoObligatorioDescripción
document_numberstringSíNIT/CI sin guiones
namestringSíRazón social / nombre
document_typestringNo, default CICI, CEX, PAS, NIT, OD (o 1–5)
complementstringNoComplemento del documento
emailstringNoPara notificaciones

customer.id está prohibido → 400 "customer.id no está permitido; envíe el snapshot completo del receptor". El cliente se resuelve/crea desde el payload.

items[]

CampoTipoObligatorioDescripción
skustringSíCódigo interno (no vacío)
descriptionstringSíDescripción fiscal (no vacía)
codigo_producto_sinintSí, >0Del catálogo sincronizado
unidad_medidaintSí, >0Código SIAT de unidad
quantitynumberSí, >0Cantidad
pricenumberSí, ≥0Precio unitario en Bs
discountnumberNo, default 0Debe ser ≤ quantity × price
codigo_actividadstringSe hereda del companySi ni empresa ni ítem lo tienen → 400
dataobjetoNoCampos sectoriales de detalle

payment

CampoTipoObligatorioDescripción
method_codeintSí (si envías payment)Método SIAT
currency_codeintSíMoneda (2 + exchange_rate para USD)
exchange_ratenumberSí, >0Monto moneda = total / tipo_cambio

Cualquier campo no declarado o typo → 400 "json: unknown field ..." (DisallowUnknownFields). Programa contra error.code, no contra message.

// Un solo payload para preview, create y emit
const payload = {
point_of_sale_id: pos.id,
// Receptor: snapshot completo
customer: {
document_type: "ci",
document_number: "1234567",
name: "Ada Lovelace",
email: "ada@example.com",
},
// Líneas: sku + snapshot fiscal por línea
items: [
{
sku: "PLAN-PRO",
description: "Plan profesional",
codigo_producto_sin: 5113100,
unidad_medida: 58,
quantity: 1,
price: 150,
discount: 0,
},
],
// Operación: venta local, sector autoresuelto
sector: "auto",
};
const vista = await supay.invoices.preview(payload); // no persiste
const borrador = await supay.invoices.create(payload); // 201 + Location
const factura = await supay.invoices.emit(payload); // ruta estrella
// Emitir un borrador ya creado
await supay.invoices.emitById({ id: borrador.id });
// Listar por punto de venta y estado
const lista = await supay.invoices.list({
point_of_sale_id: pos.id,
status: "ACCEPTED",
});

Descargas y estado

RecursoDetalle
GET /{id}?include=xml,company,point_of_sale,cufd,archivo,all
/{id}/xmlapplication/xml + Content-Disposition: attachment
/{id}/pdfGenera on-demand si hay CUF; sin archivo → 404 plano (sin envelope)
/{id}/siat-statusRe-verifica contra el SIAT

Errores de este caso

SituaciónRespuesta
sector:"30"400 "requiere emisión masiva" (Paquetes)
POS de otro tenant / factura ajena404 (enmascarado por seguridad)
SIAT caído en emit200 OFFLINE o 503 — no duplicar, conciliar por ID

Siguiente: Sectores · Anulación.