Skip to main content
Permiso requerido: sales La venta v2 es la misma de v1 (mismos campos, punto de venta, centros de costo y tipos de documento) con tres diferencias: acepta moneda (currency_code, exchange_rate), exige tax_ids por línea y valida los impuestos en modo estricto. Sus errores llevan code; ver API v2: qué cambia.
Los campos que no se describen aquí (observation, is_credit, credit_days, point_of_sale_id, cost_center_id, project_id, etc.) son los de Crear venta en v1. El listado GET /sales sigue únicamente en v1.

Crear venta

Ejemplo: venta (CCF) de un negocio con base USD, en quetzales (GTQ), con IVA 13 % y FOVIAL. La tasa vigente de GTQ es 0.128 (1 GTQ = 0.128 USD).
Todos los montos del documento van en la moneda de currency_code: precios, subtotales, impuestos, pagos y totales. No los conviertas tú. El servidor aplica la tasa, convierte cada monto a la moneda base y emite el DTE en la moneda legal del país.
En el ejemplo, 750.00 GTQ gravados equivalen a 96.00 USD; el IVA de 97.50 GTQ, a 12.48 USD; y el FOVIAL de 15.63 GTQ, a 2.00 USD. El total a pagar es 863.13 GTQ = 110.48 USD.

Campos nuevos o distintos de v1

Respuesta 200

El resto de campos de la respuesta (sale_id, generation_code, control_number, etc.) son los de v1. Un documento en moneda base responde igual, con la moneda base como currency_code, tasa "1.00000000" y foreign_total null:

Impuestos por id

En v2 cada línea declara los impuestos que le aplican con tax_ids, y el documento los totaliza en totals.taxes y totals.withholdings. Antes de transmitir el DTE, el servidor valida y recalcula los impuestos:
  • Cada id debe existir, estar activo, corresponder al país de la sucursal y tener el efecto correcto (los de tax_ids y taxes suman; los de withholdings retienen).
  • La suma de los montos declarados debe coincidir con totalTax, totalRetein y totalRent.
  • En modo estricto (siempre en v2), si totalTax, totalRetein o totalRent difieren de lo que calcula el servidor en más de 0.02, la venta se rechaza y no se transmite nada. Esto incluye la retención de IVA 1 % y la renta cuando las reglas del cliente las exigen (por ejemplo, un cliente grande con gravado de 100 o más).
Ejemplo de retención del 1 % para un cliente grande en USD (gravado 200.00, IVA 26.00, retención 2.00, total a pagar 224.00):
La renta retenida se envía igual: totalRent con su monto y una fila en withholdings con el tax_id de la renta. Un gravado de 300.00 con IVA 39.00 y renta del 10 % (30.00) paga 309.00.

Error tax_invalid

En tax_invalid, errors es una lista; cada elemento trae field, message, un code de detalle y, cuando aplica, tax_id. Los nombres de field son los internos del documento (invoiceResumenDetail.*, invoiceProductsDetail.tax_ids). Si un valor de tax_ids no es un UUID, la respuesta es validation_error (no tax_invalid).
Alcance de la validación: el servidor no compara el monto declarado de los impuestos fijos por unidad (por ejemplo FOVIAL y COTRANS) con cantidad × valor del catálogo; valida los porcentuales (IVA), las retenciones y la renta. Además, una venta sin ningún valor en tax_ids, totals.taxes ni totals.withholdings se trata como legada y no se valida. En moneda extranjera, los montos de los impuestos fijos se envían en la moneda del documento.

Errores de moneda

Se validan antes de emitir; ningún error guarda ni transmite el documento.

Consultar venta

Devuelve lo mismo que v1 más la referencia de moneda. Los montos de totals y de products están en moneda base; el total en la moneda del documento está en foreign_total.
Una venta de otro negocio o inexistente responde 404 con { "status": false, "message": "..." }.
GET /receivables (v1) también expone la referencia de moneda de cada documento por cobrar. Ver Cuentas por cobrar.