Частина 3 — Вебхук при зміні статусу
На кожну зміну статусу замовлення — один POST на нашу адресу.
- Що
- POST з JSON при кожній зміні статусу, включно зі створенням
- Де
- catalog/model/checkout/order.php → addHistory()
- Готово, коли
- Ви надсилаєте — ми бачимо події у себе. Вам нічого тестувати
Адреса
POST https://prod-observix-integrations.orangeplant-bcc99803.eastus.azurecontainerapps.io/api/crm/hooks/hk_CmWlIqLfxRlJURPOK9x8ge85DyYwzqE8y9C-senpf-U
Content-Type: application/jsonОб'єкт
{
// ── Обов'язкові ──────────────────────────────────────────────────────────
"entity_id": "38018", // order_id
"status": "Підтверджено", // назва статусу як в OpenCart, дослівно
"occurred_at": "2026-09-22T14:19:00Z", // date_added з oc_order_history, UTC
// ── Рекомендовані — сума в звітах і впізнавання клієнта з іншого пристрою ──
"value": 5800.00, // total замовлення
"currency": "UAH",
"email": "olena@example.com",
"phone": "+380671234567",
"external_id": "CUST-100500", // customer_id; "" для гостя
"properties": {
"obx_visitor_id": "01a0c86c-5956-7801-a63d-e6d75e5520bb", // з частини 2 — обов'язково
// + будь-які поля замовлення, які маєте: товари, доставка, оплата, коментар…
"items": [ { "id": "112", "name": "Плитоноска U-WIN", "quantity": 1, "price": 4900.00 } ],
"shipping_method": "novaposhta_warehouse",
// + будь-які поля клієнта, які маєте
"first_name": "Олена",
"city": "Київ",
// + мітки, якщо utm.js уже пише їх у замовлення: gclid, gbraid, wbraid, fbclid, utm_*
"gclid": "Cj0KCQ…"
}
}Кроки
- 01
З addHistory(), після запису в oc_order_history
Таймаут 3 с, помилки — в лог. Аналітика не має ламати замовлення.
орієнтовна реалізація · на розгляд // catalog/model/checkout/order.php public function addHistory($order_id, $order_status_id, $comment = '', $notify = false, $override = false) { // ... усе як зараз: INSERT в oc_order_history, зміна статусу, листи ... // Why тут: через addHistory проходить і створення, і кожна зміна статусу з адмінки чи оплати $this->sendToObservix($order_id, $order_status_id); } private function sendToObservix($order_id, $order_status_id) { try { $order = $this->getOrder($order_id); $status = $this->db->query("SELECT name FROM `" . DB_PREFIX . "order_status` WHERE order_status_id = " . (int)$order_status_id . " AND language_id = " . (int)$this->config->get('config_language_id'))->row; $payload = [ 'entity_id' => (string)$order_id, 'status' => $status['name'] ?? (string)$order_status_id, 'occurred_at' => gmdate('Y-m-d\TH:i:s\Z'), 'value' => (float)$order['total'], 'currency' => $order['currency_code'], 'email' => $order['email'], 'phone' => $order['telephone'], 'external_id' => $order['customer_id'] ? (string)$order['customer_id'] : '', 'properties' => [ 'obx_visitor_id' => $order['obx_visitor_id'] ?? '', 'first_name' => $order['firstname'], 'items' => $this->getProducts($order_id), // + що ще маєте ], ]; $ch = curl_init('https://prod-observix-integrations.orangeplant-bcc99803.eastus.azurecontainerapps.io/api/crm/hooks/hk_CmWlIqLfxRlJURPOK9x8ge85DyYwzqE8y9C-senpf-U'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 3, // Why: аналітика не має тримати замовлення ]); curl_exec($ch); curl_close($ch); } catch (\Throwable $e) { $this->log->write('observix: ' . $e->getMessage()); // проковтнути, не ламати замовлення } } - 02
Без ретраїв і дедуплікації
Це на нашому боці. Один виклик.
Перевірка
- Створити тестове замовлення і змінити йому статус в адмінці двічі
- У лог нічого не впало; замовлення оформилось як звичайно
- Скажіть нам номер замовлення — ми підтвердимо, що бачимо три події зі своєї сторони