Integrating 1C-Bitrix with Metacommerce (Price Monitoring)
Metacommerce is a competitor price monitoring service specializing in retail. It parses prices from competitor websites and marketplaces (Wildberries, Ozon, Yandex.Market) and aggregates them into a unified report. Integration with 1C-Bitrix allows pricing position data to be visible directly on the product card, enabling data-driven pricing decisions.
Metacommerce API
Metacommerce provides a REST API. The base URL depends on the subscription plan; authentication uses Authorization: Token {api_token}. Primary methods:
-
GET /api/v3/products/— list of products in the Metacommerce project -
GET /api/v3/products/{id}/prices/— competitor prices for a specific product -
GET /api/v3/reports/price-position/— price position report -
POST /api/v3/products/— add products for monitoring
Product Matching
Metacommerce stores products with its own IDs that must be mapped to products in 1C-Bitrix. The mapping is stored in bl_metacommerce_product_map:
CREATE TABLE bl_metacommerce_product_map (
bitrix_product_id INT NOT NULL PRIMARY KEY,
metacommerce_id VARCHAR(64) NOT NULL,
last_position SMALLINT, -- rank among competitors by price
last_check TIMESTAMP,
min_competitor_price NUMERIC(12,2),
max_competitor_price NUMERIC(12,2),
avg_competitor_price NUMERIC(12,2),
UNIQUE (metacommerce_id)
);
Initial matching is performed by EAN/SKU via POST /api/v3/products/match. Unmatched products require manual mapping.
Price Position Synchronization
An agent retrieves fresh data for all products once per hour:
function SyncMetacommercePositions(): string
{
$mappedProducts = MetacommerceMapTable::getList(['select' => ['BITRIX_PRODUCT_ID', 'METACOMMERCE_ID']]);
$ids = array_column($mappedProducts->fetchAll(), 'METACOMMERCE_ID');
// Batch position request
$positions = $metacommerceClient->get('/api/v3/reports/price-position/', [
'product_ids' => implode(',', $ids),
'date' => date('Y-m-d'),
]);
foreach ($positions['results'] as $pos) {
$bitrixId = MetacommerceMapTable::getByMetacommerceId($pos['product_id'])['BITRIX_PRODUCT_ID'] ?? null;
if (!$bitrixId) continue;
MetacommerceMapTable::update($bitrixId, [
'LAST_POSITION' => $pos['rank'],
'LAST_CHECK' => new \Bitrix\Main\Type\DateTime(),
'MIN_COMPETITOR_PRICE' => $pos['min_price'],
'MAX_COMPETITOR_PRICE' => $pos['max_price'],
'AVG_COMPETITOR_PRICE' => $pos['avg_price'],
]);
// Update UF fields on the info block element for display in the product card
\CIBlockElement::SetPropertyValuesEx($bitrixId, CATALOG_IBLOCK_ID, [
'COMPETITOR_MIN_PRICE' => $pos['min_price'],
'PRICE_RANK' => $pos['rank'],
]);
}
return __FUNCTION__ . '();';
}
Displaying Price Position in the Product Card (Catalogue)
A "Price Monitoring" tab is added to the product editor in the admin panel. Data is pulled from bl_metacommerce_product_map and bl_metacommerce_price_history.
On the public side — a widget for the category manager (visible only to authenticated users with the required permissions): "You are ranked #X. Lowest competitor price: Y."
Competitor Price History
Historical data is saved to bl_metacommerce_price_history for analytics purposes:
CREATE TABLE bl_metacommerce_price_history (
id SERIAL PRIMARY KEY,
bitrix_product_id INT NOT NULL,
check_date DATE NOT NULL,
our_price NUMERIC(12,2),
min_competitor NUMERIC(12,2),
avg_competitor NUMERIC(12,2),
rank SMALLINT,
UNIQUE (bitrix_product_id, check_date)
);
This enables ranking trend charts over a period to be built in the dashboard.
Timeline
| Phase | Duration |
|---|---|
| API client + product matching | 2 days |
| Position synchronization (agent) | 2 days |
| Display in product card | 1–2 days |
| History + dashboard | 2 days |
| Testing | 1 day |
| Total | 8–9 days |







