Integration of 1C-Bitrix and Akeneo: Product Catalog Sync

A catalog of 50,000 products. Each has 20 attributes, 5 languages, hundreds of images. Filling one product takes 15 minutes. That's 1250 person-hours for the entire assortment. Editors spend days, data errors pile up. Returns multiply. Without a PIM system — chaos. With integration of [Akeneo](https

Our competencies:

Frequently Asked Questions

A catalog of 50,000 products. Each has 20 attributes, 5 languages, hundreds of images. Filling one product takes 15 minutes. That's 1250 person-hours for the entire assortment. Editors spend days, data errors pile up. Returns multiply. Without a PIM system — chaos. With integration of Akeneo and 1C-Bitrix, we bring order: automatic enrichment, a single master data source, synchronization.

One client with 80,000 SKUs cut content preparation time by a factor of three. Annual savings of around $18k–26k. But that's not the limit. With a well-architected Akeneo-1C-Bitrix integration, even greater efficiency is achievable. Manual labor savings can reach $14k–20k per year for a 30,000-product catalog.

Typical Problems of a Catalog Without PIM

No single source of truth. Products are scattered across Excel, Google Sheets, 1C. Cards duplicate, attributes diverge. Managers work with different versions. Conflicts are inevitable.

Localization is a headache. Manually translating names, descriptions, SEO texts for 10+ languages is a nightmare. Each language requires separate edits. Translation errors multiply.

Media assets. Hundreds of images are linked by hand, broken links, confusion with alt texts. No CDN synchronization.

How Akeneo Solves These Problems

The typical scheme: 1C (nomenclature, prices, stock) → Akeneo (descriptions, attributes, media, translations) → Bitrix (catalog, cart, orders). Akeneo is the master of product content. 1C is the source of SKUs and prices. Bitrix is the sales channel. Sync direction: Akeneo → Bitrix. Reverse flow (orders, statistics) is rarely set up — only for analytics.

What Data Do We Synchronize?

The set is flexible. Basic configuration: name, full and short description, attributes (brand, weight, color, material, country of origin), images, prices, stock. For multilingual catalogs — localized versions (ru_RU → ru, en_US → en, de_DE → de). Attribute mapping is stored in a config file or HL-block.

Akeneo Attribute Bitrix Property
description DETAIL_TEXT
short_description PREVIEW_TEXT
brand BRAND
weight WEIGHT
color COLOR
material MATERIAL
care_instructions CARE
country_of_origin COUNTRY_ORIGIN

Comparison: Akeneo vs. Extending Infoblocks

Bitrix infoblocks are a sales engine, but not for managing large content. Akeneo takes over enrichment, localization, and validation. Result: catalog updates 3x faster.

Criterion Without Akeneo With Akeneo
Enrichment speed Manual, up to 2 days per 1,000 products Automatic, hours
Single source Infoblock with duplicates PIM — master data
Localization Difficult, up to 2 languages Up to 10+ languages out of the box

How We Write Sync Code

Akeneo provides REST API with OAuth 2.0. We use Bitrix\Main\Web\HttpClient. Request limits (100/hour) are bypassed with a queue of deferred tasks. According to Akeneo REST API Reference, the limit is 100 requests per hour. Example client:

class AkeneoClient { private string $baseUrl; private string $token; public function __construct( string $baseUrl, string $clientId, string $secret, string $username, string $password ) { $this->baseUrl = rtrim($baseUrl, '/'); $this->token = $this->authenticate($clientId, $secret, $username, $password); } private function authenticate( string $clientId, string $secret, string $username, string $password ): string { $http = new \Bitrix\Main\Web\HttpClient(); $http->setHeader('Authorization', 'Basic ' . base64_encode($clientId . ':' . $secret)); $http->setHeader('Content-Type', 'application/json'); $response = $http->post( $this->baseUrl . '/api/oauth/v1/token', json_encode([ 'grant_type' => 'password', 'username' => $username, 'password' => $password, ]) ); $data = json_decode($response, true); return $data['access_token'] ?? throw new \RuntimeException('Akeneo auth failed'); } public function getProducts(int $page = 1, int $limit = 100): array { $http = new \Bitrix\Main\Web\HttpClient(); $http->setHeader('Authorization', 'Bearer ' . $this->token); $response = $http->get( $this->baseUrl . '/api/rest/v1/products' . '?page=' . $page . '&limit=' . $limit . '&with_attribute_options=true' ); return json_decode($response, true)['_embedded']['items'] ?? []; } public function getMediaFile(string $code): string { $http = new \Bitrix\Main\Web\HttpClient(); $http->setHeader('Authorization', 'Bearer ' . $this->token); return $http->get($this->baseUrl . '/api/rest/v1/media-files/' . $code . '/download'); } } 
Example mapping configuration

Mapping stored in a PHP file:

<?php return [ 'description' => 'DETAIL_TEXT', 'short_description' => 'PREVIEW_TEXT', 'brand' => 'BRAND', 'weight' => 'WEIGHT', 'color' => 'COLOR', 'material' => 'MATERIAL', 'care_instructions' => 'CARE', 'country_of_origin' => 'COUNTRY_ORIGIN', ]; 

Step-by-Step Integration: From Audit to Deployment

  1. Audit the current catalog: list products, attributes, sections. Mapping recommendations.
  2. Set up Akeneo REST API: create client, obtain token, test request.
  3. Develop sync module: agent, mapping, update logic (including media).
  4. Implement incremental mode: record last sync time.
  5. Test on a sample of products: check data correctness, errors, performance.
  6. Documentation and training: agent description, manual trigger commands, admin instructions.

Incremental Mode: The Efficient Approach

For 50,000+ SKUs, full sync every time is a performance killer. Incremental mode pulls only changes since last sync. This reduces load on Akeneo and Bitrix. Agent runs on schedule:

function syncAkeneoProductsAgent(): string { $lastSync = \Bitrix\Main\Config\Option::get('akeneo_sync', 'last_sync', ''); $client = new AkeneoClient( AKENEO_URL, AKENEO_CLIENT_ID, AKENEO_SECRET, AKENEO_USER, AKENEO_PASSWORD ); $mapping = include '/local/config/akeneo-mapping.php'; $syncTime = date('c'); $page = 1; do { $products = $client->getProducts($page, 100); foreach ($products as $akeneoProduct) { syncSingleProduct($akeneoProduct, $mapping, $client); } $page++; } while (count($products) === 100); \Bitrix\Main\Config\Option::set('akeneo_sync', 'last_sync', $syncTime); return __FUNCTION__ . '();'; } function syncSingleProduct(array $product, array $mapping, AkeneoClient $client): void { $sku = $product['identifier']; $enabled = $product['enabled']; $existing = CIBlockElement::GetList( [], ['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'PROPERTY_CML2_ARTICLE' => $sku] )->Fetch(); $el = new CIBlockElement(); $fields = [ 'IBLOCK_ID' => CATALOG_IBLOCK_ID, 'ACTIVE' => $enabled ? 'Y' : 'N', 'NAME' => getAkeneoValue($product['values']['name'] ?? [], 'ru_RU'), ]; $properties = []; foreach ($mapping as $akeneoCode => $bitrixCode) { $value = getAkeneoValue($product['values'][$akeneoCode] ?? [], 'ru_RU'); if ($value !== null) { if (in_array($bitrixCode, ['DETAIL_TEXT', 'PREVIEW_TEXT', 'NAME'])) { $fields[$bitrixCode] = $value; } else { $properties[$bitrixCode] = $value; } } } if ($existing) { $el->Update($existing['ID'], $fields); CIBlockElement::SetPropertyValuesEx($existing['ID'], CATALOG_IBLOCK_ID, $properties); } else { $fields['IBLOCK_SECTION_ID'] = resolveCategoryId($product['categories'][0] ?? null); $newId = $el->Add($fields); if ($newId) { CIBlockElement::SetPropertyValuesEx($newId, CATALOG_IBLOCK_ID, $properties); } } } function getAkeneoValue(array $values, string $locale): mixed { foreach ($values as $entry) { if (($entry['locale'] === $locale || $entry['locale'] === null) && $entry['scope'] === null) { return $entry['data']; } } return null; } 

Images are downloaded and saved as MORE_PHOTO via CFile::MakeFileArray. We use tagged caching — don't re-download already downloaded files.

How to Avoid Data Duplication?

Duplication can occur if the agent runs again while a product was partially synced. To avoid this, we check by unique identifier (CML2_ARTICLE) and block re-syncing the same product within one run. We also log all operations and deduplicate by Akeneo identifier.

What to Do on Sync Errors?

All errors are logged to the Bitrix event log. We set up monitoring and admin notifications. If needed, a re-sync for specific products is available from the admin panel. The client can always check the last sync status.

Category Synchronization: Recursive Algorithm

Akeneo category hierarchy is synchronized into infoblock sections. We recursively create sections via CIBlockSection::Add. Correspondence akeneo_code ↔ IBLOCK_SECTION_ID is stored in an HL-block. We account for ACTIVE and SORT logic.

Timeline and Cost

Volume Scope of Work Time
1,000–5,000 SKUs, basic attributes Client + mapping + agent 1–2 weeks
10,000–50,000 SKUs + media + i18n Incremental sync + queue 3–4 weeks
Two-way sync + product models Full exchange + Webhook 5–7 weeks

Cost is calculated individually after an audit. Contact us — we'll assess the project within two business days.

What's Included

Stage Result
Audit of current catalog List of products, attributes, sections. Mapping recommendations
Set up Akeneo REST API Client creation, token acquisition, test request
Develop sync module Agent, mapping, update logic (including media)
Testing on product sample Data correctness, error checks, performance
Documentation and training Agent description, manual trigger commands, admin instructions

Why Choose Us

We are a team with 10+ years of experience in 1C-Bitrix and Bitrix24 development. Certified specialists. We have completed over 50 PIM integration projects. We guarantee stable sync operation and prompt support. Order a turnkey integration — get a reliable solution for your catalog. Contact us for an audit of your assortment.

Unlike standard CommerceML integration, which is limited to nomenclature and prices, Akeneo integration via REST API allows transferring rich attributes, media, and translations.