Every day, managers spend hours switching between personal accounts on Ozon, Wildberries, and Yandex.Market—orders get mixed up, stock goes negative, and customers complain about delays. Manual entry errors reach 5% of orders, leading to over-reservation and dissatisfaction. We solve this with a single integration: orders from all channels flow into your site's unified order management system. Our experience—over 5 years in the market, 50+ marketplace integration projects. We know how to normalize raw data from each API, build a reliable queue, and never lose a single order.
Manual order processing costs tens of thousands of rubles monthly just in manager salaries, not counting losses from errors and delays. Our integration pays for itself in two to three months—managers stop copying data and focus on customers.
How Order Synchronization Works
The architecture is built on the queue-adapter-normalizer pattern. Each marketplace (Ozon, WB, YM, etc.) has its own adapter that transforms the raw API response into a unified UnifiedOrder structure. After normalization, orders enter a common database where a state machine processes them.
We use a queue on Redis or RabbitMQ for guaranteed delivery. If one marketplace is temporarily unavailable, orders are not lost—they wait in the queue and are processed after reconnection. Idempotency is ensured by a unique sourceOrderId; a repeated request won't create a duplicate.
Ozon Order ─────┐
WB Order ──────┼──→ Order Normalizer ──→ Unified Orders DB ──→ Processing
YM Order ─────┘ ↓
Site Order ─────────────────────────────→ WMS / ERP / 1С
Normalized Order Structure
class UnifiedOrder
{
public string $id;
public string $source; // 'site', 'ozon', 'wb', 'yandex_market'
public string $sourceOrderId; // Order ID in the source system
public string $status; // mapped to unified statuses
public Customer $customer;
public array $items; // [{product_id, sku, quantity, price}]
public Shipping $shipping;
public float $total;
public string $createdAt;
}
Adapters for Each Marketplace
interface MarketplaceAdapter
{
public function getNewOrders(): array;
public function toUnifiedOrder(array $raw): UnifiedOrder;
public function updateStatus(string $orderId, string $status): void;
}
class OzonAdapter implements MarketplaceAdapter
{
public function toUnifiedOrder(array $raw): UnifiedOrder
{
return new UnifiedOrder(
source: 'ozon',
sourceOrderId: $raw['posting_number'],
status: $this->mapStatus($raw['status']),
customer: new Customer(
name: $raw['customer']['name'],
phone: $raw['customer']['phone'] ?? null,
),
items: array_map(fn($item) => [
'sku' => $item['offer_id'],
'quantity' => $item['quantity'],
'price' => $item['price'],
'name' => $item['name'],
], $raw['products']),
shipping: new Shipping(
address: $raw['delivery_method']['warehouse'] ?? null,
method: $raw['delivery_method']['name'],
),
total: $raw['financial_data']['total_amount'],
createdAt: $raw['created_at'],
);
}
public function updateStatus(string $orderId, string $unifiedStatus): void
{
$ozonStatus = $this->reverseMapStatus($unifiedStatus);
$this->ozon->updatePostingStatus($orderId, $ozonStatus);
}
}
Why a Unified State Machine Matters
Without a state machine, each marketplace lives its own life: "formed," "awaiting shipment," "transferred to delivery." A manager manually tracks changes and copies statuses. We automate this with mapping (see finite state machine theory). Additionally, the state machine avoids N+1 queries—instead of periodic API polling, we use webhooks or background checks with intervals, reducing load on marketplace servers and your network channel.
class OrderStatusMachine
{
private array $statusMap = [
'confirmed' => [
'ozon' => 'awaiting_deliver',
'wb' => 'confirm',
'ym' => 'PROCESSING',
],
'shipped' => [
'ozon' => 'delivering',
'wb' => 'complete',
'ym' => 'DELIVERY',
],
];
public function syncStatus(Order $order, string $newStatus): void
{
$order->update(['status' => $newStatus]);
if ($order->source !== 'site') {
$adapter = $this->getAdapter($order->source);
$adapter->updateStatus($order->source_order_id, $newStatus);
}
}
}
How Are Returns Handled?
Returns are a common headache. A customer sends back an item on Ozon, and the manager finds out a week later. Our ReturnProcessor instantly creates a return in the system and restores stock. It supports both full and partial returns, automatically recalculating commissions and notifying responsible parties.
class ReturnProcessor
{
public function processMarketplaceReturn(array $returnData, string $source): void
{
$order = Order::where('source', $source)
->where('source_order_id', $returnData['order_id'])
->firstOrFail();
Return::create([
'order_id' => $order->id,
'items' => $returnData['items'],
'reason' => $returnData['reason'],
'source' => $source,
]);
// Restore stock
foreach ($returnData['items'] as $item) {
Product::find($item['product_id'])?->increment('stock', $item['quantity']);
}
// Notify manager
app(TelegramNotifier::class)->notifyReturn($order);
}
}
Monitoring and Alerts
The system includes a dashboard with key metrics: number of orders in queue, processing time, number of errors per marketplace. Alerts can be configured in Telegram or Slack when thresholds are exceeded. This enables quick response to failures without affecting customers.
What's Included in the Work
We provide a turnkey integration:
| Stage | What We Do | Result |
|---|---|---|
| Analytics | Audit current processes, collect API credentials for marketplaces, document business logic | Technical specification |
| Design | Develop database schema, state machine, queues | Architectural document |
| Development | Implement adapters, normalizer, webhooks, return handler | Ready code |
| Testing | Mock tests on test orders, integration testing with real APIs | Test protocol |
| Deployment & training | Deploy to production, train managers on the unified panel | Connected system + documentation |
Timelines
Order synchronization for 2–3 marketplaces with a unified control panel: 16–24 working days. Cost is calculated individually based on the number of marketplaces and complexity of custom requirements. Get a consultation for an accurate estimate of your project.
Manual Work vs. Automation: A Comparison
| Criterion | Manual Work (average) | Our Integration |
|---|---|---|
| Time to sync statuses | 1–2 hours per day | Automatic, <1 minute |
| Data entry errors | ~5% of orders | 0% |
| Return processing time | 2–3 days | 10 minutes |
| Manager costs | Substantial (thousands of rubles monthly) | Pays back in 2–3 months |
Automation reduces time costs by 120 times—instead of 2 hours of manual work, the system does it in a minute. Manual return handling costs a noticeable amount in manager salary; our integration eliminates those expenses.
Typical Mistakes in Self-Integration
- Different product naming schemes. On your site, SKU is "ABC-001"; on Ozon, "ABC001." Result: stock mismatches. Solution: use a unified SKU across all systems.
- Lack of idempotency. Duplicate orders are created on repeated requests. Solution: check for
sourceOrderIdbefore insertion. - Missed returns. The marketplace doesn't always send a notification. Solution: regular background checks via API.
Already have an integration, but something is unstable? We'll evaluate your current implementation and suggest improvements—contact us. Order integration and free your managers from routine.







