Integration of 1C-Bitrix with MoySklad (WMS)
MoySklad is one of the most popular choices for small and mid-sized e-commerce: a friendly interface, a well-documented API, and a native mobile app for warehouse staff. Integration with 1C-Bitrix looks straightforward on paper, but in practice it breaks in three places: product variant synchronisation, handling of partial shipments, and order status mapping.
MoySklad API and integration points
MoySklad provides a REST API based on JSON-API (JSON:API standard). Base URL: https://api.moysklad.ru/api/remap/1.2/. Authentication: Bearer token or Basic Auth.
The main entities the integration works with:
-
entity/product— products (without variants) -
entity/variant— product variants (trade offers in Bitrix terminology) -
entity/customerorder— customer orders -
entity/demand— shipments -
entity/stock— stock levels (read-only via report)
Retrieving stock across all warehouses: GET /report/stock/all?groupBy=variant — returns JSON with fields stock (available stock), reserve (reservation), inTransit (in transit).
The hardest part: variant synchronisation
In 1C-Bitrix, product offers (variants) are stored in b_catalog_sku and linked to the parent product via the IBLOCK_ID of the trade offers infoblock. In MoySklad, this is a variant with a reference to a product.
The problem arises during the initial load: the variant.id from MoySklad must be correctly associated with the trade offer ID in Bitrix. Without a mapping table, every synchronisation run will attempt to create duplicates. Store the correspondence in a dedicated table custom_moysklad_mapping (or in the infoblock property MOYSKLAD_ID).
When updating variant stock, the sequence is: retrieve variant.id → look up the corresponding trade offer ID in the mapping table → update b_catalog_product for that offer.
// Update trade offer stock
\Bitrix\Catalog\ProductTable::update($offerBitrixId, [
'QUANTITY' => $stockData['stock'],
'QUANTITY_RESERVED' => $stockData['reserve'],
]);
\Bitrix\Catalog\Catalog::clearProductCache($offerBitrixId);
Forwarding orders to MoySklad
New order in Bitrix → create a customerorder in MoySklad. Minimum required fields:
-
organization— reference to the seller's organisation (required) -
agent— the buyer (counterparty in MoySklad), created automatically or mapped by email -
positions— order items with references tovariantorproductand quantities -
vatEnabled,vatIncluded— VAT settings must match the organisation's configuration
Partial shipment is a scenario that breaks simple integrations. An order for 5 items, 3 are shipped. In MoySklad, a demand with 3 items is created, linked to the customerorder. The Bitrix order status must transition to "Partially Shipped", not "Completed". This is handled via a MoySklad webhook on the demand creation event — compare demand.positions with customerorder.positions and select the appropriate Bitrix status.
MoySklad webhooks
MoySklad supports webhooks for events: CREATE, UPDATE, DELETE on any entity. Subscription:
POST /notification/webhook
{
"entityType": "customerorder",
"action": "UPDATE",
"url": "https://your-bitrix-site.ru/api/moysklad/webhook/"
}
On the Bitrix side, create a controller (a subclass of \Bitrix\Main\Engine\Controller) or a plain init.php handler. It is critical to return HTTP 200 within 3 seconds — MoySklad considers the webhook failed if no response arrives in time, and retries it.
Common pitfalls
API rate limits. MoySklad limits requests: 45 per second on the free plan, 100 on paid plans. When performing bulk stock updates (1,000+ positions), add usleep(100000) between batches.
Time zone difference. MoySklad stores dates in UTC+3. Bitrix operates in the server time zone. When comparing synchronisation timestamps ("what changed since the last run"), account for the offset.
Deleted products. If a product is deleted from MoySklad, it will not appear in the /entity/product response. Bitrix will not learn of the deletion. A periodic full reconciliation is needed, or check via archived: true.
Estimated timelines
| Scenario | Timeline |
|---|---|
| One-way stock synchronisation | 1–2 weeks |
| Two-way order and stock exchange | 3–6 weeks |
| Full synchronisation with webhooks and partial shipments | 6–10 weeks |
Pricing is calculated individually after analysing the product catalogue structure, warehouse layout, and order processing workflows.







