// blog

Integrar SAP Business One: por qué nunca escribo directo en la base de datos

Escribir en las tablas de SAP B1 parece el atajo obvio y es la forma más rápida de corromper tu contabilidad. La diferencia entre Service Layer, DI API y SQL, explicada con casos.

4 min de lectura
SAP Business OneIntegraciónArquitectura

Cada vez que alguien me pide integrar SAP Business One con otro sistema, aparece la misma pregunta en la primera reunión técnica: "¿y no es más fácil escribir directo en la base de datos?"

Es más fácil. También es la forma más rápida y silenciosa de romper la contabilidad de una empresa.

Qué pasa realmente cuando insertas una fila a mano

Un documento de SAP Business One no es una fila en una tabla. Una factura de venta toca, como mínimo:

  • OINV — la cabecera del documento
  • INV1 — las líneas
  • OJDT y JDT1 — el asiento contable que se genera automáticamente
  • OITW / OITM — el stock por almacén y sus costos
  • OCRD — el saldo del socio de negocio
  • Las tablas de numeración de series, que asignan el folio de forma correlativa

Si insertas la cabecera y las líneas por SQL, obtienes algo que se ve como una factura en la lista de documentos. No tiene asiento contable, no descontó stock, no movió el saldo del cliente y probablemente rompió el correlativo de la serie.

El problema es que nada falla en el momento. Falla semanas después, cuando el contador cierra el mes y los números no cuadran, y nadie relaciona el descuadre con la integración que se instaló en marzo.

SAP no soporta instalaciones con escrituras directas a la base de datos. Si algo se corrompe y el soporte oficial detecta escrituras externas, el caso se cierra ahí.

Las dos vías soportadas

Service Layer

Es una API REST sobre OData. Es la vía que uso por defecto en integraciones nuevas.

POST /b1s/v1/Orders
Content-Type: application/json
Cookie: B1SESSION=...
 
{
  "CardCode": "C20000",
  "DocDate": "2026-07-22",
  "DocumentLines": [
    { "ItemCode": "A00001", "Quantity": 5, "WarehouseCode": "01" }
  ]
}

Ese POST dispara exactamente la misma lógica de negocio que si un usuario hubiera creado la orden desde el cliente de SAP: validaciones, asiento, stock, correlativo. Si algo no cumple una regla, responde con un error y no escribe nada.

Ventajas prácticas: es HTTP, funciona desde cualquier lenguaje, corre en Linux y no necesita instalar el cliente de SAP en el servidor de integración.

DI API

Es la librería COM de .NET. Más antigua, atada a Windows y requiere el cliente de SAP instalado en la máquina.

Sigue siendo necesaria para operaciones que Service Layer no expone —cierta manipulación de objetos de usuario, algunos procesos de aprobación— y suele ser más rápida en cargas masivas porque mantiene la sesión abierta sin el costo de HTTP por operación.

Mi regla: Service Layer por defecto, DI API cuando Service Layer no llega.

Las tres cosas que rompen una integración en producción

Elegir la vía correcta es la parte fácil. Lo que realmente decide si una integración sobrevive son estas tres.

1. Idempotencia o pagarás dos veces

La red se cae justo después de que SAP creó el documento y antes de que tu sistema recibiera la respuesta. Tu código reintenta. Ahora hay dos facturas idénticas.

La solución no es "reintentar con cuidado": es guardar en un campo de usuario del documento —U_ExtId, por ejemplo— el identificador del pedido en el sistema origen, y consultar antes de crear:

SELECT DocEntry FROM OINV WHERE U_ExtId = @externalId

Si ya existe, el reintento devuelve el documento existente en vez de crear otro. Esta consulta de lectura contra la base de datos sí es perfectamente válida: leer nunca fue el problema.

2. La sesión de Service Layer expira

B1SESSION tiene un tiempo de vida (30 minutos por defecto) y el error que devuelve al expirar no siempre es obvio. Un cliente HTTP que renueva la sesión al recibir un 401 y reintenta una sola vez te ahorra la mitad de las incidencias del primer mes.

3. Los errores de SAP hay que traducirlos

Un mensaje como [OINV.TaxDate][line: 0] , 'Date deviates from permissible range' es incomprensible para quien opera el sistema todos los días. Mapea los códigos más frecuentes a mensajes en español que digan qué hacer: "El período contable de esa fecha está cerrado".

Ese mapeo es media hora de trabajo y es la diferencia entre que el equipo resuelva solo el 80% de las incidencias o que te escriba cada vez.

Lo que sí conviene hacer por SQL

Leer. Todo lo que sea consulta va directo contra la base de datos: es más rápido, no consume sesiones y no tiene efectos secundarios.

Para dashboards y reportes, lo que hago es crear vistas propias con prefijo —ZV_VentasPorVendedor— en lugar de consultar las tablas del sistema desde la aplicación. Si mañana cambia la estructura, se ajusta la vista y no hay que tocar el código.

La línea es simple: leer por SQL, escribir por la API. Siempre.

Si esto te resultó útil o tienes un caso parecido en tu empresa, escríbeme: me gusta conversar sobre estos problemas aunque no termine en un proyecto.