Saltar al contenido principal

Ventas BETA

Endpoints para crear ventas y facturar desde un sistema externo.

Endpoints en beta

Estos endpoints están disponibles para uso anticipado pero pueden cambiar de contrato, comportamiento o ser retirados antes de su release definitivo. No los comprometas en producción sin confirmar disponibilidad.

Sucursal del comprobante

El comprobante se emite en la sucursal del punto de venta de tu integración, y esa sucursal tiene que estar dentro de las habilitadas para el canal. Si el administrador del ERP configuró una lista de sucursales habilitadas que no la incluye, la operación responde 403.

A diferencia de las exportaciones, acá no hace falta tener sucursales cargadas: si no hay lista, se toma la sucursal de los depósitos o del punto de venta ya configurados en el canal. Una integración que hoy funciona sigue funcionando.

Venta directa

Permite crear una FACTURA_VENTA en forma directa, sin pasar antes por preventa.

POSTBETA/integraciones/terceros/venta

Request

export interface VentaTerceros extends PedidoTerceros {
medioPago: MedioPagoTerceros;
}
export interface PedidoTerceros {
ordenId: number;
numero: number;
detalle?: string;
listaPrecioId?: number; // si no viene o es 0, usa la configurada en el canal
direccionEnvio?: DireccionTerceros;
direccionFacturacion?: DireccionTerceros;
usuario?: UsuarioTerceros; // requerido salvo que mandes entidadId
productos: ArticuloExterno[];
subtotal: number;
descuento: number;
recargo: number;
envio: number;
total: number;
empleadoId?: number; // vendedor del comprobante; pisa al configurado en el canal
entidadId?: number; // cliente explícito; si viene, ignora usuario y no crea cliente
}
export interface MedioPagoTerceros {
tipo: TipoMedio;
cuentaBancariaId?: number; // requerido si tipo = DEPOSITO_BANCO
tarjetaId?: number; // requerido si tipo = TARJETA
externalId?: string; // requerido si tipo = VIRTUAL
}

Tipos de medio de pago

export enum TipoMedio {
EFECTIVO = 1,
TARJETA = 5,
CUENTA_CORRIENTE = 6,
DEPOSITO_BANCO = 9,
VIRTUAL = 11,
}
Soporte real en venta

Aunque el DTO admite varios tipos, hoy POST /venta aplica el medio con el helper interno de integraciones, que solo soporta EFECTIVO, DEPOSITO_BANCO y VIRTUAL. Si se envía otro tipo, la operación puede fallar con "El medio de pago no es compatible".

Respuesta

ajFacturaResult

Validaciones

ReglaError
Body inválido o sin productos"Los datos de venta son invalidos"
medioPago ausente"El medio de pago es requerido"
Request duplicada dentro de 30 segundos para el mismo ordenId"La solicitud ya se esta procesando"
Medio de pago no soportado por el helper"El medio de pago no es compatible"
Punto de venta en una sucursal no habilitada403 con "El punto de venta N pertenece a una sucursal no habilitada para esta integracion..."
empleadoId que no es un empleado activo de una sucursal habilitada403 con "El empleadoId N no es un empleado valido..."
entidadId que no es un cliente activo403 con "El entidadId N no es un cliente valido"
Sin entidadId válido y sin usuario con dni/cuit/email400 con "Debe indicar entidadId o los datos del cliente..."

Notas operativas

  • el punto de venta lo toma siempre de la configuración de la integración
  • si listaPrecioId no viene o es 0, toma la configurada en la app/canal
  • usa una ventana anti-duplicados de 30 segundos por ordenId
  • internamente asigna numero = ordenId
  • el vendedor sale de empleadoId si lo mandás; si no, del configurado en la integración
  • el cliente sale de entidadId si lo mandás; si no, se resuelve/crea a partir de usuario
Vendedor: orden de precedencia

El vendedor del comprobante se resuelve en este orden: empleadoId del body, después el vendedor por defecto de tu integración, y por último el vendedor asignado al cliente (este último solo si tu integración está configurada para priorizarlo). Los ids válidos salen de GET /empleados. Aplica igual a pedido, venta y notacredito.

Cliente: entidadId o usuario

Si mandás entidadId, se usa ese cliente directo — no se busca por documento/CUIT/email ni se crea uno nuevo. Sin entidadId, usuario sigue siendo obligatorio (con al menos dni, cuit o email) para identificar o dar de alta al cliente. Un entidadId inválido responde 403; la falta total de datos de cliente responde 400. Aplica igual a pedido, venta y notacredito. Los ids válidos salen de GET /entidades.

Ejemplo

curl --request POST \
--url https://api.test-ninox.com.ar/integraciones/terceros/venta \
--header 'X-NX-TOKEN: {TU_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"ordenId": 12345,
"numero": 12345,
"detalle": "Venta directa desde sistema externo",
"listaPrecioId": 3,
"usuario": {
"nombre": "Juan Perez",
"email": "juan@example.com",
"dni": "12345678",
"telefono": "1122334455",
"condicion": 1
},
"productos": [
{ "articuloId": 100, "precio": 1500.5, "cantidad": 2 }
],
"subtotal": 3001,
"descuento": 0,
"recargo": 0,
"envio": 500,
"total": 3501,
"medioPago": { "tipo": 1 }
}'

Nota de crédito

Crea una NOTACREDITO_VENTA directa. Espeja el flujo de venta: mismo payload de cliente, productos, totales y medioPago (el medio con el que se reintegra), más un campo opcional facturaRefId para vincular la nota de crédito a la venta original. El punto de venta lo toma de la configuración de la integración.

POSTBETA/integraciones/terceros/notacredito

Request

export interface NotaCreditoTerceros extends PedidoTerceros {
medioPago: MedioPagoTerceros;
facturaRefId?: number; // FacturaId de la venta original a acreditar (opcional)
}

Reutiliza las interfaces PedidoTerceros y MedioPagoTerceros definidas en Venta directa.

Respuesta

ajFacturaResult

Validaciones

ReglaError
Body inválido o sin productos"Los datos de la nota de credito son invalidos"
medioPago ausente"El medio de pago es requerido"
Request duplicada dentro de 30 segundos para el mismo ordenId"La solicitud ya se esta procesando"
facturaRefId no corresponde a ninguna factura"No se encontro la venta original {id} a acreditar"
Medio de pago no soportado por el helper"El medio de pago no es compatible"
entidadId que no es un cliente activo403 con "El entidadId N no es un cliente valido"
Sin entidadId válido y sin usuario con dni/cuit/email400 con "Debe indicar entidadId o los datos del cliente..."

Notas operativas

  • el punto de venta lo toma siempre de la configuración de la integración
  • si listaPrecioId no viene o es 0, toma la configurada en la app/canal
  • facturaRefId es opcional pero recomendado: vincula la nota de crédito a la venta original, lo que habilita el saldado en cuenta corriente (en cascada) y la trazabilidad NC↔Venta
  • genera un ingreso de stock por los productos devueltos (no reserva stock)
  • usa una ventana anti-duplicados de 30 segundos por ordenId, independiente de la de venta
  • al igual que venta, el medio se aplica con el helper interno que hoy soporta EFECTIVO, DEPOSITO_BANCO y VIRTUAL
  • acepta empleadoId con la misma precedencia que venta (ver más arriba)
  • acepta entidadId con la misma semántica que venta (ver más arriba)

Ejemplo

curl --request POST \
--url https://api.test-ninox.com.ar/integraciones/terceros/notacredito \
--header 'X-NX-TOKEN: {TU_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"ordenId": 12345,
"numero": 12345,
"detalle": "Nota de credito por devolucion",
"listaPrecioId": 3,
"facturaRefId": 456,
"usuario": {
"nombre": "Juan Perez",
"email": "juan@example.com",
"dni": "12345678",
"telefono": "1122334455",
"condicion": 1
},
"productos": [
{ "articuloId": 100, "precio": 1500.5, "cantidad": 2 }
],
"subtotal": 3001,
"descuento": 0,
"recargo": 0,
"envio": 500,
"total": 3501,
"medioPago": { "tipo": 1 }
}'

Facturar preventa

Convierte una preventa existente en FACTURA_VENTA.

POSTBETA/integraciones/terceros/facturar

Request

export interface FacturarTerceros {
facturaId: number; // id de la preventa existente
puntoVentaId: number;
electronica: boolean;
medioPago: MedioPagoTerceros;
}

Respuesta

ajFacturaResult

Validaciones

ReglaError
Body inválido o facturaId <= 0"El facturaId es requerido"
medioPago ausente"El medio de pago es requerido"
puntoVentaId <= 0"El puntoVentaId es requerido"
puntoVentaId inexistente403 con "El punto de venta N no existe"
puntoVentaId en una sucursal no habilitada403 con "El punto de venta N pertenece a una sucursal no habilitada para esta integracion..."
Request duplicada dentro de 30 segundos para la misma facturaId"La solicitud ya se esta procesando"

Notas operativas

  • requiere que la preventa exista y esté en estado PENDIENTE
  • si electronica = true, intenta generar factura electrónica AFIP
  • usa una ventana anti-duplicados de 30 segundos por facturaId
  • a diferencia de venta, la facturación de preventa soporta el flujo completo de medios (EFECTIVO, TARJETA, CUENTA_CORRIENTE, DEPOSITO_BANCO, VIRTUAL)
  • no acepta empleadoId: la preventa que estás facturando ya trae su vendedor
  • los puntoVentaId válidos los devuelve GET /puntos-venta

Ejemplo

curl --request POST \
--url https://api.test-ninox.com.ar/integraciones/terceros/facturar \
--header 'X-NX-TOKEN: {TU_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"facturaId": 456,
"puntoVentaId": 1,
"electronica": false,
"medioPago": { "tipo": 9, "cuentaBancariaId": 12 }
}'

Medios de pago

Devuelve la configuración de medios habilitados y los catálogos necesarios para obtener ids válidos antes de llamar a venta o facturar.

GETBETA/integraciones/terceros/medios-pago

Respuesta

export interface MediosPagoConfigDTO {
medios: WMedios;
tarjetas: TarjetaDTO[];
tarjetasReglas: TarjetaReglaDTO[];
cuentasBancarias: CuentaBancariaDTO[];
bancos: BancoDTO[];
tarjetaCreditoReglas: boolean;
botonesRapidos: BotonRapidoConfig[];
recargoDigitalHabilitado: boolean;
facturaElectronicaAutomatica: boolean;
recargosTipoMedio: RecargoTipoMedioConfig[];
}
export interface WMedios {
efectivo: boolean;
cuentaCorriente: boolean;
tarjeta: boolean;
cheque: boolean;
tarjetaPropia: boolean;
chequePropio: boolean;
chequeCartera: boolean;
deposito: boolean;
extraccion: boolean;
transferencia: boolean;
virtual: boolean;
}
export interface CuentaBancariaDTO {
cuentaBancariaId: number;
descripcion: string;
bancoId?: number;
alias?: string;
cbu?: string;
}

Uso recomendado

  • consultar este endpoint antes de operar con DEPOSITO_BANCO o TARJETA
  • tomar tarjetas[].tarjetaId para pagos con tarjeta
  • tomar cuentasBancarias[].cuentaBancariaId para pagos por depósito o transferencia
  • usar medios como capacidad disponible del tenant antes de construir el payload

Ejemplo

curl --request GET \
--url https://api.test-ninox.com.ar/integraciones/terceros/medios-pago \
--header 'X-NX-TOKEN: {TU_TOKEN}' \
--header 'Content-Type: application/json'

Flujos recomendados

Venta directa

  1. Consultar /medios-pago para validar el tipo disponible y obtener ids de tarjetas o cuentas bancarias si hacen falta.
  2. Construir el payload de venta con cliente, productos, totales y medioPago.
  3. Enviar a /venta.
  4. Verificar ajFacturaResult y registrar facturaId, numero, pvNumero y errores.

Facturación de preventa

  1. Tomar el facturaId de la preventa existente.
  2. Consultar /medios-pago si el medio requiere ids auxiliares.
  3. Enviar a /facturar.
  4. Verificar ajFacturaResult y el estado final de la factura.

Nota de crédito

  1. Tomar el facturaId de la venta original a acreditar (para facturaRefId).
  2. Consultar /medios-pago si el medio de reintegro requiere ids auxiliares.
  3. Construir el payload con cliente, productos a devolver, totales y medioPago.
  4. Enviar a /notacredito.
  5. Verificar ajFacturaResult y registrar facturaId, numero, pvNumero y errores.