Two-Way Catalog Synchronization with 1C
Imagine: a manager updated a price in 1C, but the old price lingers on the site for three days. Or a product is discontinued in the accounting system but remains orderable online. Two-way catalog sync with 1C is not just import and export. It's designing a rule system that resolves data conflicts when information changes in both systems simultaneously. Without a clear definition of the source of truth, synchronization turns into chaos: data gets overwritten, duplicates appear, orders are lost.
A typical scenario: price and stock are changed in 1C, while the description is edited on the site. If the exchange is set up as one-way import, the description may be overwritten. Our approach is two-way exchange with field-level master systems. We design the logic so that the site and 1C remain consistent without manual intervention.
Defining Sources of Truth
The first step is to document for each field which system is the master:
| Field | Master | Logic |
|---|---|---|
| Product name | 1C | 1C is the nomenclature system |
| SKU | 1C | SKU is set in the accounting system |
| Description | Site | Marketing texts are written by the editor |
| Price | 1C | Pricing in the accounting system |
| Stock | 1C | Real warehouse accounting |
| Images | Site | Photos are processed separately |
| SEO fields | Site | meta title/description on the site side |
| Activity status | Both | 1C can take it off sale, the site can too |
How Conflicts Are Resolved During Synchronization
Conflict: the active_site field was set to false by a site operator (unpublished), but the next export from 1C contains active = true. According to the table above, 1C is the master for active_1c, but active_site remains untouched. Result: active_1c = true, active_site = false → product is not displayed. The site operator retains control. For each field, we define a master system and merge rule. This ensures data integrity and prevents information loss.
Database Schema
CREATE TABLE products (
id BIGSERIAL PRIMARY KEY,
onec_guid UUID UNIQUE, -- 1C identifier
sku TEXT,
-- Fields from 1C (overwritten on each sync)
name_1c TEXT,
price_1c NUMERIC(12,2),
stock_1c INTEGER,
category_guid UUID,
active_1c BOOLEAN DEFAULT true,
-- Site fields (not overwritten by sync)
description TEXT,
meta_title TEXT,
meta_description TEXT,
images JSONB,
active_site BOOLEAN DEFAULT true,
-- Sync metadata
last_sync_1c TIMESTAMPTZ,
sync_hash_1c CHAR(64) -- hash of data from 1C for change detection
);
-- Final status: product is active only if active in both 1C and site
CREATE VIEW products_active AS
SELECT * FROM products WHERE active_1c = true AND active_site = true;
Synchronization Algorithm from 1C to Site
class OnecToSiteSyncService
{
public function sync(CommerceMLData $data): SyncResult
{
$result = new SyncResult();
foreach ($data->products as $onecProduct) {
$syncHash = $this->computeHash($onecProduct);
$product = Product::firstOrNew(['onec_guid' => $onecProduct->guid]);
// Skip if data hasn't changed
if ($product->exists && $product->sync_hash_1c === $syncHash) {
$result->skipped++;
continue;
}
// Update ONLY fields from 1C (do not touch description, images, etc.)
$product->fill([
'sku' => $onecProduct->sku,
'name_1c' => $onecProduct->name,
'price_1c' => $onecProduct->price,
'stock_1c' => $onecProduct->stock,
'category_guid'=> $onecProduct->categoryGuid,
'active_1c' => $onecProduct->active,
'last_sync_1c' => now(),
'sync_hash_1c' => $syncHash,
]);
$product->save();
$result->updated++;
}
// Products no longer exported by 1C are deactivated
$syncedGuids = $data->products->pluck('guid');
Product::whereNotIn('onec_guid', $syncedGuids)
->update(['active_1c' => false]);
return $result;
}
}
Synchronization Site to 1C
The site sends to 1C only what has changed on the site and matters to 1C: new orders, returns, payment notifications.
class SiteToOnecSyncService
{
public function getUnsyncedOrders(): Collection
{
return Order::where('sent_to_1c', false)
->where('status', '!=', 'draft')
->with(['items.product', 'customer'])
->get();
}
}
Why Choosing the Right Exchange Format Matters
CommerceML is the industry standard for integration with 1C, but REST API gives more control. Comparison:
| Criterion | CommerceML | REST API |
|---|---|---|
| Deployment speed | Fast (out of the box) | Requires development |
| Flexibility | Limited schema | Full control over fields |
| Versioning support | No | Yes (via headers) |
| Error granularity | Generic codes | HTTP statuses + response body |
| Performance | XML parsing | JSON, faster |
We choose the approach for the specific task. For small businesses, CommerceML is often sufficient; for large catalogs with high load, REST API is preferred.
Monitoring Synchronization
-- Last sync statuses
SELECT
source,
COUNT(*) FILTER (WHERE status = 'success') AS success,
COUNT(*) FILTER (WHERE status = 'error') AS errors,
MAX(finished_at) AS last_run,
AVG(EXTRACT(EPOCH FROM (finished_at - started_at))) AS avg_duration_sec
FROM sync_logs
WHERE started_at > NOW() - INTERVAL '7 days'
GROUP BY source;
How Often Should Synchronization Occur?
The interval depends on change intensity and load. For an online store with 10,000 products, it's optimal to update prices and stock every 15-30 minutes. For a large marketplace (100,000+ items) — every 5 minutes during peak hours and less frequently at night. We always set up an adjustable schedule with manual trigger capability.
Typical Mistakes When Setting Up Synchronization
- Lack of data hashing: each export overwrites all fields even if data hasn't changed. Solution: store the last sync hash and compare.
- Ignoring activity status: if a product is unavailable in either system, it still appears on the site. Use AND logic between
active_1candactive_site. - Incorrect processing order: import from 1C first, then export orders — otherwise collisions may occur. Maintain sequence.
What's Included in the Work
- Audit of current data schema — identify mismatches and growth points.
- Designing synchronization rules — define sources of truth and conflict resolution logic.
- Implementing the exchange — write sync code using CommerceML or REST API.
- Testing with real data — verify on live configuration, fix errors.
- Documentation and training — provide operation instructions.
- Post-launch support — guarantee stable operation, resolve incidents.
Timeline
Two-way catalog synchronization with 1C, including testing on a real configuration: 14–20 business days. Contact us for an audit of your current sync scheme. Get a consultation on data exchange setup — we will assess the scope of work and propose the optimal solution.







