Connectez vos systèmes ERP, outils d’inventaire, flux d’achats et plateformes financières à APIBASE avec des coordonnées déterministes. Les systèmes externes n’ont pas besoin d’accès direct à la base de données. Ils envoient seulement des requêtes API ou Hive autorisées.
Connect ERP systems, inventory tools, purchasing workflows and finance platforms to APIBASE using deterministic coordinates. External systems do not need direct database access. They only send authorized API or Hive requests.
Une intégration ERP relie les systèmes opérationnels à APIBASE : produits, fournisseurs, niveaux de stock, bons d’achat, expéditions et factures.
An ERP integration connects operational systems to APIBASE: products, suppliers, stock levels, purchase orders, shipments and invoices.
L’ERP externe ou le backend communique avec APIBASE uniquement par requêtes HTTP. Il n’appelle pas les modèles, classes ou méthodes PHP internes d’APIBASE.
The external ERP or backend communicates with APIBASE through HTTP requests only. It does not call internal APIBASE models, classes or PHP methods.
// Recommended architecture
ERP system
↓
external backend / proxy
↓ HTTP requests
APIBASE API / Hive
↓
user BASE
Les données ERP sont fortement relationnelles. La discipline de nommage est donc importante.
Les tables doivent être au pluriel. Les clés primaires utilisent id_*. Les clés étrangères utilisent *_id.
Les champs métier normaux n’utilisent pas de soulignés.
ERP data is highly relational. That makes naming discipline important.
Tables must be plural. Primary keys use id_*. Foreign keys use *_id.
Normal business fields do not use underscores.
// Valid APIBASE ERP table structure
products
C1 = id_product
C2 = product
C3 = sku
C4 = unit.price
C5 = erp.id
C6 = synced.at
C7 = erp.status
suppliers
C1 = id_supplier
C2 = supplier
C3 = email
C4 = phone
C5 = erp.id
stocks
C1 = id_stock
C2 = stock
C3 = product_id
C4 = stock.quantity
C5 = stock.minimum
C6 = stock.location
purchases
C1 = id_purchase
C2 = purchase
C3 = supplier_id
C4 = product_id
C5 = purchase.quantity
C6 = purchase.status
C7 = purchase.date
products, suppliers, stocks, purchases, invoices.
id_product, product_id, id_supplier, supplier_id.
unit_price, stockQuantity, erp.synced.at, purchase_status.
unit.price, stock.quantity, purchase.status et synced.at. N’empilez pas plusieurs points.
Use one-level dot notation for composed business fields such as unit.price, stock.quantity, purchase.status and synced.at. Do not stack multiple dots.
Ne codez pas les identifiants de tables et de colonnes à l’aveugle. Appelez /schema une fois pendant la configuration, puis stockez les T et C retournés dans votre configuration.
Do not hardcode table and column ids blindly. Call /schema once during setup, then store the returned T and C ids in your configuration.
Dans cet exemple, l’intégration cible les tables products, stocks et purchases dans la base publique d’exemple acme.
In this example, the integration targets products, stocks and purchases in the public example base acme.
// ── PHASE 1 : setup — run once, store results in config ──────
$api = "https://apibase.work";
$base = "acme";
$token = "TOKEN_ERP";
$productsSchema = api_get("$api/hive/schema/$base/products", $token);
$stocksSchema = api_get("$api/hive/schema/$base/stocks", $token);
$purchasesSchema = api_get("$api/hive/schema/$base/purchases", $token);
$T_products = $productsSchema['T']; // 4
$T_stocks = $stocksSchema['T']; // 9
$T_purchases = $purchasesSchema['T']; // 12
$productCols = array_flip($productsSchema['columns']);
$stockCols = array_flip($stocksSchema['columns']);
$purchaseCols = array_flip($purchasesSchema['columns']);
$C_product_id = $stockCols['product_id']; // 3
$C_stock_quantity = $stockCols['stock.quantity']; // 4
$C_stock_minimum = $stockCols['stock.minimum']; // 5
$C_supplier_id = $purchaseCols['supplier_id']; // 3
$C_purchase_product_id= $purchaseCols['product_id']; // 4
$C_purchase_quantity = $purchaseCols['purchase.quantity']; // 5
$C_purchase_status = $purchaseCols['purchase.status']; // 6
Le backend ERP peut lire une ligne de stock précise avec la coordonnée de table et l’identifiant logique de ligne. En Hive, la base key apparaît dans l’URL.
The ERP backend can read a precise stock line using the table coordinate and logical line identifier. In Hive, the base key appears in the URL.
// ── PHASE 2 : read stock from Hive ───────────────────────────
$line = 21;
$stock = api_get(
"$api/hive/get/$base/T{$T_stocks}/L{$line}?format=assoc",
$token
)['data'];
// Example returned data
$stock = [
'id_stock' => 21,
'stock' => 'Main warehouse stock',
'product_id' => 8,
'stock.quantity' => 42,
'stock.minimum' => 10,
'stock.location' => 'warehousea',
];
read sur la table stocks pour la base Hive acme.The token must have the read right on the stocks table for the acme Hive base.Dans un PUT Hive, l’URL identifie la coordonnée cible exacte. La nouvelle valeur est envoyée dans le corps JSON.
In Hive PUT, the URL identifies the exact target coordinate. The new value is sent in the JSON body.
Cet exemple met seulement à jour stock.quantity. L’ERP n’a pas besoin d’accès à toute la base de données.
This example updates only stock.quantity. The ERP does not need access to the full database.
// ── PHASE 3 : update one stock cell through Hive ─────────────
$stockLine = 21;
api_put(
"$api/hive/put/$base/T{$T_stocks}/L{$stockLine}/C{$C_stock_quantity}",
$token,
['value' => 37]
);
// Example response
[
'status' => 'success',
'mode' => 'cell',
'message' => 'Cell updated.',
'hive_base' => 'acme',
]
{"value":37}.Do not append values to the URL query string. The coordinate identifies the cell. The body carries the value: {"value":37}.Pour créer un bon d’achat via Hive, envoyez une requête POST vers la table purchases. Le corps de la requête doit contenir un objet record.
To create a purchase order through Hive, send a POST request to the purchases table. The request body must contain a record object.
// ── PHASE 4 : create purchase through Hive ───────────────────
$created = api_post(
"$api/hive/post/$base/T{$T_purchases}",
$token,
[
'record' => [
'purchase' => 'Purchase for product 8',
'supplier_id' => 3,
'product_id' => 8,
'purchase.quantity' => 50,
'purchase.status' => 'pending',
'purchase.date' => date('Y-m-d'),
]
]
);
$line = $created['line']; // 34
$purchaseId = $created['id_purchase']; // 34
// Example response from APIBASE
[
'status' => 'success',
'message' => 'Record added.',
'line' => 34,
'hive_base' => 'acme',
'id_purchase' => 34,
]
add sur la table purchases. Sans la bonne ACL Hive, APIBASE retourne 403.The token must have the add right on the purchases table. Without the correct Hive ACL, APIBASE returns 403.Les flux ERP doivent souvent mettre à jour un seul état opérationnel : pending, approved, received, cancelled ou closed.
ERP workflows often need to update only one operational state: pending, approved, received, cancelled or closed.
// ── PHASE 5 : update purchase status through Hive ────────────
$purchaseLine = 34;
api_put(
"$api/hive/put/$base/T{$T_purchases}/L{$purchaseLine}/C{$C_purchase_status}",
$token,
['value' => 'received']
);
L’appel au fournisseur ERP se fait à l’extérieur d’APIBASE. APIBASE n’a pas besoin de savoir comment le fournisseur ERP fonctionne. Votre backend lit depuis APIBASE, envoie le payload à l’ERP, puis écrit le résultat dans APIBASE.
The ERP provider call happens outside APIBASE. APIBASE does not need to know how the ERP provider works. Your backend reads from APIBASE, sends the payload to the ERP, then writes the result back to APIBASE.
// ── PHASE 6 : send product data to an external ERP ───────────
$productLine = 8;
$product = api_get(
"$api/hive/get/$base/T{$T_products}/L{$productLine}?format=assoc",
$token
)['data'];
$erpResponse = erp_post(
"https://erp.example.com/api/products",
[
'name' => $product['product'],
'sku' => $product['sku'],
'price' => $product['unit.price'],
]
);
$erpId = $erpResponse['id'];
Après le retour de l’identifiant ERP externe, écrivez le résultat dans APIBASE avec des coordonnées exactes.
After the external ERP returns its identifier, write the result back to APIBASE through exact coordinates.
// ── PHASE 7 : write ERP result back to APIBASE ───────────────
$C_erp_id = $productCols['erp.id']; // 5
$C_synced_at = $productCols['synced.at']; // 6
$C_erp_status = $productCols['erp.status']; // 7
api_put(
"$api/hive/put/$base/T{$T_products}/L{$productLine}/C{$C_erp_id}",
$token,
['value' => $erpId]
);
api_put(
"$api/hive/put/$base/T{$T_products}/L{$productLine}/C{$C_synced_at}",
$token,
['value' => date('Y-m-d\TH:i')]
);
api_put(
"$api/hive/put/$base/T{$T_products}/L{$productLine}/C{$C_erp_status}",
$token,
['value' => 'synced']
);
erp.id, synced.at et erp.status. Elle n’a pas besoin d’un accès large en écriture à des données non liées.The integration updates only erp.id, synced.at and erp.status. It does not need broad write access to unrelated data.
Pour mettre à jour un enregistrement complet via Hive, omettez la colonne dans l’URL
et envoyez un objet record. Cela déclenche le mode ligne.
To update a full record through Hive, omit the column from the URL
and send a record object. This triggers line mode.
À utiliser avec prudence. Pour les métadonnées opérationnelles, les mises à jour cellule par cellule sont généralement plus sûres.
Use this carefully. For operational metadata, cell updates are usually safer.
// ── Alternative : full product line update through Hive ──────
$updated = api_put(
"$api/hive/put/$base/T{$T_products}/L{$productLine}",
$token,
[
'record' => [
'id_product' => $productLine,
'product' => 'Industrial pump',
'sku' => 'PMP100',
'unit.price' => '1200.00',
'erp.id' => 'erp7890',
'synced.at' => date('Y-m-d\TH:i'),
'erp.status' => 'synced',
]
]
);
// Example response for a line update
[
'status' => 'success',
'mode' => 'line',
'message' => 'Line updated.',
'hive_base' => 'acme',
]
/hive/put/acme/T4/L8/C5 avec {"value":"..."}.
Mode ligne : /hive/put/acme/T4/L8 avec {"record":{...}}.
Cell mode: /hive/put/acme/T4/L8/C5 with {"value":"..."}.
Line mode: /hive/put/acme/T4/L8 with {"record":{...}}.
Utilisez /api/* quand le token cible la propre base du propriétaire. Utilisez /hive/* quand le token accède à une base partagée contrôlée par ACL Hive.
Use /api/* when the token targets the owner’s own base. Use /hive/* when the token accesses a shared base controlled by Hive ACLs.
// ── Personal API version — owner’s own base ──────────────────
$stock = api_get(
"$api/api/get/T{$T_stocks}/L{$stockLine}?format=assoc",
$token
)['data'];
api_put(
"$api/api/put/T{$T_stocks}/L{$stockLine}/C{$C_stock_quantity}",
$token,
['value' => 37]
);
/hive/get/acme/....Personal API does not use a base key in the URL. Hive does: /hive/get/acme/....Un connecteur ERP a besoin d’une couche de mapping. Le côté gauche représente les noms de champs APIBASE. Le côté droit représente les noms de champs ERP externes.
An ERP connector needs a mapping layer. The left side represents APIBASE field names. The right side represents external ERP field names.
// left side = APIBASE field names
// right side = external ERP field names
// underscores are valid only for APIBASE keys such as id_product and product_id
// dots are used for composed business fields with one structural level
$erpMap = [
'products' => [
'product' => 'name',
'sku' => 'sku',
'unit.price' => 'price',
'erp.id' => 'id',
'synced.at' => 'synced.at',
'erp.status' => 'status',
],
'stocks' => [
'stock' => 'name',
'product_id' => 'product.id',
'stock.quantity' => 'quantity',
'stock.minimum' => 'minimum',
'stock.location' => 'location',
],
'purchases' => [
'purchase' => 'name',
'supplier_id' => 'supplier.id',
'product_id' => 'product.id',
'purchase.quantity' => 'quantity',
'purchase.status' => 'status',
'purchase.date' => 'date',
],
];
product_id et supplier_id sont valides parce que ce sont des clés étrangères. unit_price ou purchase_status ne seraient pas des champs métier APIBASE valides.product_id and supplier_id are valid because they are foreign keys. unit_price or purchase_status would not be valid APIBASE business fields.C’est la première version la plus propre lorsque APIBASE reste la source de vérité et que le fournisseur ERP conserve des données opérationnelles miroirs.
This is the cleanest first version when APIBASE remains the source of truth and the ERP provider stores mirrored operational data.
// ── COMPLETE FLOW : APIBASE master → ERP mirror ──────────────
// 1. Discover schema once
$productsSchema = api_get("$api/hive/schema/$base/products", $token);
$T_products = $productsSchema['T'];
$productCols = array_flip($productsSchema['columns']);
$C_erp_id = $productCols['erp.id'];
$C_synced_at = $productCols['synced.at'];
$C_erp_status = $productCols['erp.status'];
// 2. Read the product from APIBASE
$product = api_get(
"$api/hive/get/$base/T{$T_products}/L{$productLine}?format=assoc",
$token
)['data'];
// 3. Send the product to the ERP provider
$erpResponse = erp_post(
"https://erp.example.com/api/products",
[
'name' => $product['product'],
'sku' => $product['sku'],
'price' => $product['unit.price'],
]
);
$erpId = $erpResponse['id'];
// 4. Write synchronization metadata back to APIBASE
api_put(
"$api/hive/put/$base/T{$T_products}/L{$productLine}/C{$C_erp_id}",
$token,
['value' => $erpId]
);
api_put(
"$api/hive/put/$base/T{$T_products}/L{$productLine}/C{$C_synced_at}",
$token,
['value' => date('Y-m-d\TH:i')]
);
api_put(
"$api/hive/put/$base/T{$T_products}/L{$productLine}/C{$C_erp_status}",
$token,
['value' => 'synced']
);
Si le fournisseur ERP supporte les webhooks, il devrait notifier votre backend externe. Le backend vérifie l’événement, puis écrit les changements autorisés dans APIBASE par requêtes API ou Hive.
If the ERP provider supports webhooks, it should notify your external backend. The backend verifies the event, then writes authorized changes to APIBASE through API or Hive requests.
// Webhook architecture
ERP provider
↓ webhook
external backend / proxy
↓ verified HTTP request
APIBASE API / Hive
// Example webhook handling logic
$event = verify_erp_webhook();
if ($event['type'] === 'stock.updated') {
api_put(
"$api/hive/put/$base/T{$T_stocks}/L{$stockLine}/C{$C_stock_quantity}",
$token,
['value' => $event['quantity']]
);
}
Un token ERP devrait recevoir seulement les droits nécessaires à l’intégration. Pour Hive, les droits sont accordés par token, par base et par table.
An ERP token should only receive the rights needed for the integration. For Hive, rights are granted per token, per base and per table.
// Example ERP token rights for the acme base
token: erp-sync
scope: hive
products:
read: yes
add: no
edit: yes
delete: no
stocks:
read: yes
add: no
edit: yes
delete: no
purchases:
read: yes
add: yes
edit: yes
delete: no
403.Registering a base in Hive does not grant access by itself. Permissions must be added explicitly in Hive ACLs. Until an ACL rule exists for a token and table combination, the request returns 403.Ne commencez pas avec une synchronisation bidirectionnelle sauf si c’est absolument nécessaire. Elle ajoute trop tôt la gestion des conflits, des doublons, des comparaisons de timestamps et des règles de suppression.
Do not start with bidirectional synchronization unless it is absolutely required. It adds conflict handling, duplicate handling, timestamp comparisons and deletion rules too early.
// Best first version
APIBASE master → ERP mirror
// Later, if truly required
ERP ↔ APIBASE
Une seule direction. Moins de cas limites. Plus facile à auditer et à déboguer.
One direction. Fewer edge cases. Easier to audit and debug.
L’ERP reçoit seulement les coordonnées et permissions nécessaires pour les produits, stocks, achats ou factures.
The ERP receives only the coordinates and permissions required for products, stock, purchases or invoices.