requestId, datos persistidos, efectos y warnings.
lapymeVersion: "2026-08-20" activa el contrato fechado y estricto. En ese
contrato, total es el total final esperado y es obligatorio. Para
comprobantes A (voucherType 1, 2 y 3), unitPrice es neto sin IVA. Para
comprobantes a consumidor final, como B (voucherType 6, 7 y 8) y presupuesto
(voucherType 90), unitPrice es final con IVA incluido.
Cuando enviás productId, La Pyme resuelve el producto y usa el mismo renglón
canónico para stock, contabilidad, fiscalización y respuesta. No necesitás leer
el producto de nuevo para calcular importes derivados. Si el total no
coincide, el SDK recibe un error 422 BUSINESS_REQUIREMENT_UNMET con un detalle
TOTAL_MISMATCH; no se crea la venta ni sus efectos.
El contrato fechado rechaza campos desconocidos y campos monetarios derivados,
como subtotal, taxAmount, discountAmount, taxIncludedOverride y
roundingAdjustment. Omitir lapymeVersion conserva el contrato histórico,
pero ese modo está deprecado.
Descargar el comprobante
La respuesta de creación incluyesale.invoicePdf cuando el comprobante ya
puede tener un PDF. El valor es una ruta estable de la API, por ejemplo
/api/v1/sales/{sale_id}/document. El detalle de la venta también conserva
document.file para mantener compatibilidad con las integraciones existentes.
La ruta requiere la misma API key con sales:read y responde con un redirect
302 hacia una URL firmada de cinco minutos.
409 PRECONDITION_FAILED, retryable: true y Retry-After: 5. Si la
generación falló, responde 409 con retryable: false. Descargar el documento
no inicia una regeneración.
La ruta autenticada
sale.invoicePdf es para integraciones. El Location
firmado existe solo para transferir el archivo y no debe persistirse. Los links
públicos opacos /comprobantes/d/{token} usados en emails son credenciales de
portador distintas; la ruta pública histórica usada por WhatsApp tampoco forma
parte del contrato de la API.Facturar una venta ya importada
Si Tiendanube, Mercado Libre u otra integración ya importó el pedido como una venta, no llamessales.create y no lo conviertas en un order. Facturá el
saleId existente con una key estable:
idempotentReplay: true. No uses la misma
key para otro saleId. Después de corregir un rechazo final o la configuración
fiscal, enviá una key nueva.
Reintentos seguros
Si tu worker, backend o job reintenta la misma venta, reenviá el mismoidempotencyKey. No generes una key nueva para cada intento del mismo pedido.
La clave de idempotencia no se guarda como referencia externa de la venta; si
necesitás ver o buscar el ID de tu sistema, envialo también en
integrationSource e integrationId.

