Deux portes vers le même B1.
Tout programme qui lit ou enregistre quelque chose dans SAP Business One sans qu'une personne le saisisse passe par l'une de deux interfaces. Le Service Layer est un service web : il tourne sur le serveur, parle HTTPS et OData et répond en JSON. Vous pouvez l'appeler depuis n'importe quel langage capable d'envoyer une requête web, et le service mobile de B1 en dépend. La DI API (Data Interface API) est la voie plus ancienne : une bibliothèque COM (une DLL) pour Windows, conçue pour C/C++, Visual Basic et .NET, que le programme charge sur la machine où il s'exécute.
En dessous, c'est la même chose. Le guide Service Layer de SAP décrit le DI Core à l'intérieur du Service Layer comme « the same one that is used by SAP Business One DI API », et la logique métier (taxes, comptabilisation, stock) tourne dans le même composant que dans le client B1. C'est pourquoi une commande qui passe par l'une ou l'autre porte subit les mêmes contrôles qu'une commande saisie à l'écran : si B1 la refuserait dans la fenêtre, il la refuse aussi depuis votre programme. Les noms d'objets et de champs sont eux aussi en grande partie identiques : CardCode s'appelle CardCode dans les deux.
Laquelle utiliser, et quand.
- Service Layer pour tout ce qui est nouveau : une application de scan, un lien avec une boutique en ligne, un tableau de planification, une intégration avec un autre système. Il tourne sous SUSE Linux et sous Windows, le répartiteur de charge écoute généralement sur le port 50000, et votre programme n'a rien à installer à côté de B1. Il monte en charge avec plusieurs nœuds derrière le répartiteur.
- DI API quand vous maintenez un add-on existant construit dessus, ou quand le code tourne de toute façon dans le client B1 sous Windows, à côté de l'UI API. L'aide du SDK de SAP précise que la DI API ne prend pas en charge le multithreading, et elle doit être installée sur chaque machine qui exécute le programme.
- Ce que seule la DI API possède : le guide le dit sans détour. Le Service Layer n'a pas d'objet
Recordsetpour le SQL direct, pas d'import ni d'export en XML, et pas de transaction couvrant plusieurs requêtes : il n'y a pas deStartTransactionni deEndTransactioncomme dans la DI API. Chaque requête, y compris un lot, est sa propre transaction.
Dans la DI API, un programme crée un objet Company, renseigne Server, CompanyDB, UserName, Password et DbServerType, puis appelle Connect, qui renvoie 0 en cas de succès. Une commande est alors GetBusinessObject(BoObjectTypes.oOrders), remplie ligne par ligne et enregistrée avec Add ; si un appel échoue, GetLastError donne le code et le texte. La suite de ce guide porte sur le Service Layer, car c'est là que va le travail nouveau.
Se connecter, et combien de temps vit une session.
Le Service Layer se trouve à https://<server>:50000/b1s/v2/. /b1s/v2 parle OData version 4, /b1s/v1 l'ancienne version 3 ; choisissez v2 pour tout nouveau travail. Rien ne fonctionne avant la connexion :
POST /b1s/v2/Loginavec le corps{"CompanyDB": "SBODEMOUS", "UserName": "manager", "Password": "1234"}. UnLanguagefacultatif fixe la langue des messages.- La réponse est
200 OKavec unSessionIdet unSessionTimeout, et deux cookies :B1SESSIONetROUTEID. Chaque requête suivante doit envoyerB1SESSION;ROUTEIDest facultatif et vous maintient sur le même nœud derrière le répartiteur. Un navigateur envoie les deux tout seul ; un programme de bureau ou serveur doit les ajouter lui-même. - La session expire après une période sans requête : 30 minutes par défaut, réglées par
SessionTimeoutdansb1s.confsur le serveur. Ensuite, la réponse est401 Unauthorizedavec le code 301, « Invalid session or session already timeout. » Reconnectez-vous et répétez la requête. POST /b1s/v2/Logoutavec le cookie met fin à la session ; la réponse est204 No Content. Déconnectez-vous quand vous avez fini, et ne vous reconnectez pas pour chaque requête : la connexion est l'appel le plus lourd qui soit.
Lire, créer et modifier des données.
Lire, c'est un GET sur une entité, avec des options de requête OData pour garder la réponse petite. GET /b1s/v2/BusinessPartners?$select=CardCode,CardName&$filter=CardType eq 'cCustomer'&$top=5 renvoie cinq clients avec seulement leur code et leur nom. $filter connaît eq, ne, gt, ge, lt, le, and, or, not, et des fonctions comme startswith et contains ; $orderby trie et $skip pagine. Un enregistrement se lit par sa clé : GET /b1s/v2/BusinessPartners('C20000'), avec des guillemets car la clé est du texte, et GET /b1s/v2/Orders(22) sans, car DocEntry est un nombre. Les lignes d'une commande viennent avec la commande, dans DocumentLines.
Une liste n'arrive jamais d'un coup. Par défaut, le Service Layer renvoie 20 enregistrements par page et ajoute un @odata.nextLink vers la page suivante ; l'en-tête Prefer: odata.maxpagesize=50 demande des pages plus grandes. Un code qui lit seulement la première page puis s'arrête est l'erreur la plus fréquente d'une première intégration.
Créer, c'est un POST avec du JSON. POST /b1s/v2/Orders avec {"CardCode": "C20000", "DocDueDate": "2026-11-15", "DocumentLines": [{"ItemCode": "A00001", "Quantity": 10}]} ajoute une commande client et répond 201 Created avec le document entier, y compris le nouveau DocEntry et le DocNum. Modifier, c'est un PATCH sur la clé avec seulement les champs qui changent, par exemple PATCH /b1s/v2/BusinessPartners('C20000') avec {"Phone1": "0201234567"} ; la réponse est 204 No Content. Utilisez PATCH, pas PUT : PUT remet à zéro chaque champ omis. Les étapes qui ne sont pas une simple modification sont des actions, comme POST /b1s/v2/Orders(22)/Close. Un DELETE sur une commande est refusé, de même que vous ne pouvez pas en supprimer une dans le client B1.
Les entités ne sont pas des tables.
Le Service Layer parle en objets métier, la base de données en tables. BusinessPartners est stocké dans OCRD ; Orders est la commande client, avec l'en-tête dans ORDR et les lignes dans RDR1. De nombreux documents commerciaux partagent un même type d'entité, Document, si bien que Orders, Invoices et PurchaseOrders ont les mêmes champs. La liste complète des entités, champs et actions se trouve dans GET /b1s/v2/$metadata, y compris vos propres champs utilisateur ; les métadonnées d'une base de société peuvent donc différer de celles d'une autre. Un piège : un nouveau champ ou une nouvelle table utilisateur n'est visible qu'après un redémarrage du Service Layer.
Lire une table en SQL, c'est très bien. Y écrire, non. Les règles du SDK de SAP n'autorisent aucune modification des objets standard, et un INSERT ou un UPDATE directement dans ORDR saute tout ce que B1 fait quand un document est ajouté : numérotation, stock, l'écriture comptable, autorisations, approbation, le journal des modifications. Vous vous retrouvez avec des données que B1 n'a jamais vérifiées. Tout ce qui modifie des données passe par le Service Layer ou la DI API, sans exception.
Erreurs, lots et requêtes enregistrées.
- Les erreurs reviennent sous forme de statut HTTP (par exemple 400 pour une requête refusée, 401 sans session valide, 403 sans autorisation) et d'un corps JSON avec un objet
errorcontenant uncodeet unmessage: le même texte qu'un utilisateur verrait dans le client B1, par exemple un code de partenaire déjà attribué. Journalisez ce texte ; il dit presque toujours ce qui ne va pas. - Les requêtes par lot partent vers
POST /b1s/v2/$batchen un seul message multipart. Les requêtes d'un change set réussissent ou échouent ensemble : si l'une échoue, tout le change set est annulé. C'est la réponse du Service Layer à une transaction sur plusieurs documents, tant qu'ils tiennent dans un lot. - Requêtes SQL enregistrées (depuis 10.0 FP 2011) : vous enregistrez un
SELECTcomme entrée dansSQLQueries, avecSqlCode,SqlNameetSqlText, et vous l'exécutez avecGET /b1s/v2/SQLQueries('sql01')/List. Seule la lecture est permise ;UPDATE,INSERTetDELETEsont refusés, et seules les tables et colonnes autorisées peuvent être interrogées. Un utilisateur normal a besoin d'une autorisation pour chaque requête dans General Authorizations. Les détails sont dans notre guide sur les requêtes SQL.
Avant de commencer : une liste de contrôle.
- Le Service Layer est installé et tourne sur votre serveur B1, et votre programme peut atteindre le port 50000 en HTTPS. Il est prévu pour des appels internes ; il n'a pas besoin d'être exposé à internet.
- Une société de test pour essayer les requêtes, jamais la base de production.
- Un utilisateur B1 dédié au programme, avec seulement les autorisations dont il a besoin, et une licence pour cet utilisateur. Indirect Access est le type prévu pour les programmes ; voir notre guide sur les licences B1, et confirmez-le avec votre partenaire.
- Une session réutilisée d'une requête à l'autre, une nouvelle connexion sur un 401, et une déconnexion à la fin.
- Pagination gérée : suivez
@odata.nextLinkjusqu'à ce qu'il disparaisse. - Des noms de champs pris dans le
$metadatade votre propre base de société, ni devinés ni copiés d'un autre système. - Le texte d'erreur de chaque requête refusée écrit dans un journal, et rien d'écrit directement dans les tables SAP.
Comment KoonLearn l'aborde.
KoonLearn, notre simulation de formation pour SAP Business One, propose un module d'approfondissement Service Layer et DI API : des sections sur l'architecture et la connexion, la lecture, l'écriture, les cas avancés, DI API et le dépannage. Vous travaillez dans une console de requêtes dans le navigateur : méthode, URL, en-têtes et corps, un bouton Send, et une réponse avec statut et JSON tirée des données de la société de formation. Vous vous connectez et voyez votre session expirer, vous filtrez et paginez partenaires et commandes d'achat, vous créez et modifiez des documents par POST et PATCH, vous exécutez Close et Cancel, vous envoyez un change set dans un lot et vous réparez des requêtes qui reviennent en 400, 401 ou 404. La partie DI API consiste à lire du code et à trouver l'erreur : une connexion non vérifiée, une transaction sans sa gestion d'erreurs, une boucle sur un Recordset. La console répond comme le Service Layer ; elle n'en est pas un, et rien n'est installé ni connecté à un vrai B1.
Les prix et les options sont dans le portail client. L'approfondissement se termine par un quiz et un examen de module. Il va au-delà de l'examen : ce n'est pas une préparation à C_TB120 et il ne donne aucun certificat. Si vous voulez d'abord voir comment fonctionne KoonLearn, le chapitre 03 Achats est gratuit sans compte : commencez le chapitre gratuit sur learn.koonsystems.com. KoonLearn n'est pas affilié à SAP SE.
Sources : SAP, Working with SAP Business One Service Layer (version 1.29, 27-07-2026 : connexion et session, CRUD, options de requête, pagination, lots, SQL Query, limites par rapport à la DI API) ; la référence de l'API du Service Layer (Login, Logout, BusinessPartners, Orders) ; SAP Business One SDK Help 10.0 (DI API, connexion, gestion des erreurs, modifications du standard) ; référence de la DI API 10.0 (Company, Documents) ; Database Tables Reference 10.0 (OCRD, ORDR, RDR1) ; l'aperçu des modules KoonLearn. SAP et SAP Business One sont des marques de SAP SE.

