Синхронізація з інтернет-магазином
Усе налаштовується у Складі, Довідники → Інтернет-магазини. Конфігурація зберігається в базі даних, поруч з іншими блоками конфігурації.
Загальна схема роботи
flowchart TD
SK["Склад<br/>(адміністрування)"]
subgraph DBG["БД"]
PL["Майданчики (платформи)<br/>R_INET_PLATFORMS"] --> SF["Магазини (вітрини)<br/>R_INET_STOREFRONTS"]
SF --> CFG["Конектор<br/>S_BLOCKYAML"]
D[("Товари, замовлення")]
end
subgraph ABG["abasyn"]
ABS["Завдання синхронізації<br/>(одне на магазин), сповіщення<br/> (email, telegram)"]
end
ABR["abrest<br/>пошук або створення товарів, нормалізація і аналіз даних"]
M["Інтернет-магазин"]
D ~~~ ABR
ABR ~~~ M
SK ==>|редагує майданчик,<br/>вітрину, конектор| PL
SK ==>|шаблон конфігурації, стан завдань, ручний запуск, де/активація синхронізації| ABS
CFG -.->|один блок =<br/>одне завдання| ABS
ABS --> ABR
ABR -.-> ABS
ABR --> D
D -.-> ABR
M -->|товари, категорії,<br/>характеристики, зображення,<br/>замовлення| ABS
ABS -.->|ціна, залишок, назви,<br/>ключові слова, розміщення,<br/>зображення| M
Суцільні стрілки — потік даних з магазину у базу даних; пунктирні — потік БД → магазин; товсті стрілки — дії адміністратора. Склад редагує майданчик, вітрину й конектор прямо в БД та керує завданнями abasyn через HTTP REST API. Внутрішню бізнес-логіку синхронізації — пошук або створення товару, співставлення, словник статусів — виконує abrest; abasyn лишається транспортом між магазином і abrest.
Один майданчик може мати кілька вітрин; кожна вітрина має лише один блок налаштувань конектора, і саме він стає завданням синхронізації в abasyn (ключ завдання — ІД інтернет-магазину).
Очікуваний робочий цикл: 1. Підготовка даних і тестування - послідовно, у режимах probe, readonly, rehearse. 2. Введення в експлуатацію — одне повне завантаження каталогу створює товари, дерево категорій і співставлення з магазином. 3. Робочий режим, вхід — замовлення, їхні рядки та відправлення надходять безперервно; завантаження каталогу й далі підхоплює товари, що з'явилися в магазині іншим шляхом. 4. Робочий режим, вихід — зміна ціни, назви, опису, ключових слів чи фото або нове розміщення, зроблені у Складі, передаються наступним запуском.
Хто чим володіє
В робочому режимі mode: live по замовчуванню синхронізуються всі дані. За потреби їх можна вимикати
| Дані | Джерело істини | Напрямок | Вимикається |
|---|---|---|---|
| Назва товару, короткий і детальний опис, ключові слова | "Рахівниця" | назовні | skip_push: [names] |
| Ціна | перемагає останній запис | обидва | skip_push: [products] |
Залишок (SUM(M_TOVAR_AGG.TOVAR_AMOUNT)) |
"Рахівниця" | назовні | skip_push: [stock] |
| Розміщення та зняття з продажу | "Рахівниця" (IS_LISTED) |
назовні | skip_push: [listing] |
| Статус замовлення | два господарі, перемагає свіжіша позначка | обидва | skip_push: [order_status] |
| Зображення | "Рахівниця" | назовні (лише WooCommerce) | skip_push: [images] |
| Створення товару | магазин, а на WooCommerce ще й "Рахівниця" | обидва | skip_push: [listing] |
| Замовлення, рядки, відправлення | магазин | усередину | skip_pull: [orders] |
| Фотографії товарів | магазин | усередину | skip_pull: [images] |
| Характеристики товарів | магазин | усередину, додаванням | skip_pull: [characteristics] |
| Неопубліковані товари | магазин | усередину | skip_pull: [drafts] |
| Дерево категорій | магазин | усередину | не вимикається |
Що потрібно перед початком
- Служби abrest і abasyn запущені на сервері
- У вашому робочому профілі є секція
abasyn:
- Токен доступу до abasyn для користувача-оператора. Токени створює кнопка активації служб у редакторі конфігурації.
- Облікові дані магазину:
- Prom.ua — один токен API з кабінету продавця.
- WooCommerce — логін користувача WordPress і його пароль
застосунку, створений у Users → Profile → Application Passwords. Надайте
цьому користувачеві роль Shop Manager: вона має права
manage_woocommerce,edit_productsіupload_files- це те, що потрібно синхронізації.
1. Майданчик
Верхня ліва таблиця — майданчики, або ж платформи (Пром, Розетка, Allegro, Ebay) що можуть мати багато окремих магазинів.
| Колонка | Значення |
|---|---|
| Майданчик | Довільна назва. |
| Адреса сайту | Сайт самого майданчика. Лише довідково. |
| Тип конектора | prom, woocommerce або stub. Порожнє поле означає, що жоден магазин цього майданчика не синхронізується. |
stub — вбудоване штучне джерело для перевірки конвеєра без створення справжнього інтернет-магазину.
2. Інтернет-магазин
Верхня права таблиця — магазини на обраному майданчику. Окремі записи є різними магазинами, їхні товари, ціни та замовлення не змішуються.
| Колонка | Значення |
|---|---|
| Назва інтернет-магазину | Довільна назва. Лише для інформації, можна перейменовувати в будь-який момент. |
| Головний URL | R_INET_STOREFRONTS.URL_MAIN. Робоче поле: для WooCommerce це хост API (abasyn сам додає /wp-json/wc/v3 — не дописуйте), для Prom — вітрина, з якої будуються посилання на товари й читаються сторінки. |
| URL адмінки | Адреса адмінки/API, якщо відрізняється від головного URL. |
| Активний | IS_ACTIVE. Головний вимикач синхронізації цього магазину. |
3. Облікові дані
Виберіть магазин, натисніть Токен доступу до API. Для Prom запитується один
токен API. Для майданчика woocommerce запитуються два значення: логін
користувача WordPress, а потім його пароль застосунку. Обидва зберігаються
спільними рядками (S_TOKENS, user_id = -1, service_name = 'storefront' /
'storefront_secret') і доступні всім робочим профілям.
Паролем для WooCommerce має бути саме пароль застосунку, створений у Users → Profile → Application Passwords у WordPress. Пароль облікового запису не приймається: на цьому шляху WordPress перевіряє лише паролі застосунків, і будь-що інше повертає
invalid_username. WordPress друкує значення групами по чотири символи; пробіли декоративні, їх можна лишити або прибрати.Один пароль застосунку покриває всю інтеграцію: API WooCommerce для каталогу, замовлень, цін і розміщення та медіатеку WordPress для зображень товарів. Відкликання його у WordPress повністю відрізає інтеграцію, не зачіпаючи нічого іншого.
4. Налаштування синхронізації
Виберіть магазин, натисніть Налаштування синхронізації. Якщо блока ще немає,
Склад бере типовий із GET /api/connectors/template/<conntype> — тому
створення першого блока потребує доступного abasyn. Ctrl+J на значенні
показує допустимі варіанти.
Відсутній блок налаштувань означає «не налаштовано», а не «типові значення»: інтернет-магазин, для якого немає налаштувань залишається несинхронізованим навіть якщо користувач його активує. Створення блока ініціює синхронізацію.
interval: 600
mode: probe
skip_push: []
skip_pull: []
lang: uk
remote_url: ''
landing_group_id: 0
tag_group_id: 0
push_miss_limit: 3
scrape_delay_ms: 500
order_backfill_days: 30
order_status_default: ''
retry_interval_minutes: 60
max_retries: 24
max_age_hours: 24
Усе увімкнено за замовчуванням. Активний інтернет-магазин із заповненим блоком і mode: live повністю синхронізується в обидва боки (з сайту в рахівницю і з рахівниці на сайт).
| Ключ | Дія |
|---|---|
interval |
Секунд між запусками, відлік починаєтсья від завершення попереднього. 0 — лише на вимогу. |
mode |
Етап введення в експлуатацію. Див. нижче. |
skip_push |
Що не записувати до магазину: order_status, products (ціна), stock (залишок), names, listing, images. Порожньо — магазин отримує все. |
skip_pull |
Що не читати з магазину: images, characteristics (лише Prom), drafts, orders. Порожньо — читається все, що магазин віддає. |
lang |
Бажана мова для багатомовних джерел (name/description у Prom). Ключові слова її не дотримуються — Prom не має keywords_multilang. |
remote_url |
Перевизначає базу API — https://my.prom.ua/api/v1 для Prom, URL магазину + /wp-json/wc/v3 для Woo. Порожнє значення визначає її автоматично; змінювати можна лише якщо ви точно розумієте що робите. |
landing_group_id |
ІД групи, куди потрапляють щойно створені товари. |
tag_group_id |
ІД групи, що обмежує область дії характеристик товарів без групи. 0 означає «взяти landing_group_id»; лише якщо і той дорівнює 0, характеристики діють в усіх групах. Задавайте явно, коли теги мають діяти не в тій групі, куди потрапляють нові товари. |
push_miss_limit |
Скільки разів поспіль намагатись співставити товар з інтернет-магазину з товарим з бази даних якщо інтернет-магазин відповідає "товар не знайдено". Лічильник — CR_TOVAR_STOREFRONTS.PUSH_MISS_COUNT, обнуляється будь-яким успішним записом. Рахується лише відповідь «невідомий ІД»; відмова валідації ніколи не виводить живе співставлення з обігу. |
scrape_delay_ms |
Лише Prom. Мілісекунд між читаннями сторінок товарів під час ручного завантаження характеристик. |
order_backfill_days |
За скільки днів стягнути замовлення з інтернет-магазину при першій синхронізації. 0 — уся історія. |
order_status_default |
Типовий стан замовлення якщо він не визначений інтернет-магазином. |
retry_interval_minutes, max_retries, max_age_hours |
Періодичність повторних спроб для замовлень, які не вдалося зберегти. |
Неправильне значення всередині skip_push / skip_pull логується та ігнорується, нічого не вимикаючи.
Збереження конфігурації зі складу надсилає api/connectors/reload, і abasyn перечитує конфігурацію без перезапуску. При цьому оновлюється
лише сама конфігурація — LastRun, позначки прогресу та статистика зберігаються,
тож збереження не спричиняє повторне завантаження каталогу. Якщо abasyn
недосяжний, налаштування все одно збережуться, а зміни наберуть чинності при
наступному старті служби.
Склад відмовляється зберігати некоректний YAML.
mode — етапи введення в експлуатацію
| mode | обсяг | запис в інтернет-магазин |
|---|---|---|
probe |
10 товарів, 10 замовлень | ніколи |
readonly |
повний | ніколи |
rehearse |
повний | обчислює й журналює, нічого не надсилає |
live |
повний | надсилає все, чого немає в skip_push |
probe обмежує обсяг звантажених даних, але у цих межах виконується весь конвеєр синхронізації (зображення, характеристики, завантаження замовлень). При цьому abasyn не зберігає внутрішню позначку прогресу, тому активована синхронізація в режимі probe буде постійно намагатись стягнути одні й ті ж товари й документи.
Куди потрапляють нові товари
Категорії магазину і групи "Рахівниці" — незалежні одна від одної. Віддалена категорія стає
вузлом TAG_NODES під тег-деревом, прив'язаним до майданчика, і зв'язується через
CR_TOVAR_NODES. Без landing_group_id створений товар не має групи й невидимий у кожному дереві груп
Складу та Каси.
- Діє лише на створені товари — зіставлений товар лежить там, куди його поклав оператор, і ніколи не переміщується.
- Пропускається для товару, який уже має групу.
- Неіснуючий ІД журналюється; товари все одно створюються, просто без групи.
0— це ІД кореня дерева груп, тому він не може означати справжню групу.
Панель відомостей про магазин показує поточну кількість як «Без групи: N» червоним.
Характеристики зі сторінок товарів (лише Prom)
API продавця Prom не має ендпойнта характеристик, тому завантаження додатково
читає публічну сторінку кожного зміненого товару й розбирає її — спершу
ld+json, потім блок data-qaid="attributes". Ціна питання — один додатковий
GET на змінений товар, тож у робочому режимі це не створює додатковго навантаження, але при першому повному
проході, якщо це тисячі сторінок, процес може затягнутись. Ставтеся до цього першого проходу як до першого
завантаження зображень: виконайте один раз і свідомо, або поставте
skip_pull: [characteristics], доки не будете готові. Сторінка, яку не вдалося
отримати, утримує позначку прогресу каталогу, замість того щоб лишити товар
недотегованим.
5. Увімкнення запису до магазину
Спершу репетиція:
rehearse обчислює кожен запис, який надіслав би, і журналює його в повному
робочому масштабі. Простежте would_push на кількох справжніх змінах, потім
підвищіть до live і перевірте результат у маркетплейсі.
При першому увімкненні позначка прогресу ініціалізується поточним моментом, і запуск не робить нічого: зміни, зроблені до увімкнення, вважаються вже узгодженими. Без цього підвищення конектора спричинило б прохід по всій історії — кожен колись видалений у "Рахівниці" товар було б знято з продажу за один раз.
Особливості каналів:
- Перелік статусів Prom сталий:
received,delivered,canceled,paidі кредитні стани. Решта пропускається із записом у журнал, але помилкою не є. WooCommerce приймає будь-який статус, зареєстрований на сайті. - Статус замовлення передається зі звіркою: перед записом читається поточний статус у магазині, тож повтор після збою транспорту не дублює записів, а «луна» між завантаженням і передаванням не може зациклитися.
- Товари передаються без звірки — запис ціни й залишку ідемпотентний і
містить наше власне значення, тому надсилається обмеженими пакетами по 100
(Prom
products/edit, Wooproducts/batch). - Для ціни діє правило останнього запису, реалізоване в коді. Завантаження
записує віддалену ціну, лише якщо віддалена позначка
modifiedсвіжіша заCR_TOVAR_STOREFRONTS.SYNC_TIMESTAMPі значення справді відрізняється; локально переоцінений товар переживає завантаження й натомість передається до магазину. - Залишок — це
SUM(TOVAR_AMOUNT)поM_TOVAR_AGGдля всіх складів; те саме число видно в колонці Залишок таблиці товарів вітрини. Від'ємний підсумок передається як 0; порожня ціна не передається ніколи. Якщо залишок 0, товар в інтернет-магазині позначається як відсутній і це ще одна причина ретельно тестувати початок синхронізації. - Зображення вивантажуються до медіатеки магазину по одному, після чого вся
галерея прив'язується до товару одним упорядкованим списком (за
SORT_ORDER, найменше значення першим). Товар обробляється, лише якщо хоч одне його зображення нове або змінене.
6. Розміщення товарів "Рахівниці" в магазині
CR_TOVAR_STOREFRONTS.IS_LISTED (колонка У продажу в таблиці товарів) — це
бажаний стан. Фактичний стан — це REMOTE_TOVAR_ID: порожнє значення означає,
що в магазині товару немає. Перелік на розміщення звіряє одне з одним:
REMOTE_TOVAR_ID |
IS_LISTED |
TTYPE товару |
дія |
|---|---|---|---|
| порожній | 1 | не 3 | розмістити — створити в магазині |
| заповнений | 0 | не 3 | зняти з продажу — товар просто ховається від покупців |
| заповнений | будь-який | 3 | архівувати — товар вилучено чи об'єднано з іншим |
| заповнений | 1 | не 3 | нічого |
| порожній | 0 | будь-який | нічого |
Отже, послідовність виставлення товару "Рахівниці" на продаж така: додати його до
вітрини кнопкою Додати товар, проставити ціну в таблиці товарів, поставити
позначку У продажу — і дати запуску в режимі live з увімкненим listing
створити його в магазині. Колонка ІД у магазині заповниться після успіху.
Різниця між двома жестами важлива. Зняття з продажу оборотне: товар зникає з вітрини, але залишається в кабінеті магазину, і позначка У продажу повертає його назад. Архівування — однобічне: копія товару потрапляє до кошика магазину, звідки його видалять за правилами самого магазину. Саме це відбувається з товаром-дублікатом після об'єднання товарів.
Видалення рядка співставлення (Прибрати товар з вітрини) — це інший жест, він означає припинити синхронізувати цей товар тут. До магазину нічого не надсилається, а віддалений ІД втрачається. Якщо товар має справді зникнути з продажу, спершу зніміть позначку У продажу.
7. Сумнівні та конфліктні прив'язки
Товар "Рахівниці" можна випадково зв'язати не з тим товаром магазину — наприклад, коли збіглись артикули різних товарів. Колонка Стан синхронізації в таблиці товарів вітрини показує, чи варто перевірити прив'язку:
| Стан | Значення |
|---|---|
| (порожньо) | перевірено автоматично — назва товару й назва в магазині достатньо схожі |
| підтверджено | оператор підтвердив зв'язок кнопкою «Підтвердити прив'язку»; синхронізація більше його не чіпає |
| сумнівний | назви розійшлися — рядок підсвічено червоним, перевірте вручну |
| конфлікт | інший запис магазину претендує на цей самий товар |
Кількість сумнівних і конфліктних рядків видно в колонці «Сумнівних прив'язок» таблиці магазинів і в панелі відомостей про вітрину; сам рядок товару підсвічується червоним (крім архівних товарів). Колонка Назва у магазині показує, як товар називається на майданчику, — порівняйте з локальною назвою, щоб зрозуміти причину розбіжності.
Синхронізація ніколи не перестворює прив'язку сама. Якщо надходить запис магазину, що претендує на вже зайнятий товар "Рахівниці", наявний зв'язок лишається недоторканим, суперник запам'ятовується окремо, а рядок позначається конфліктом. Жодне замовлення при цьому не втрачається — рядки, що не знайшли товар, повторно зіставляються після кожного проходу каталогу.
Виправляють це кнопками під таблицею товарів:
- Підтвердити прив'язку позначає поточний зв'язок правильним; синхронізація більше не чіпатиме його, навіть якщо назви й далі розходяться.
- Переприв'язати товар пропонує на вибір: перенести прив'язку на інший товар "Рахівниці", або — коли є суперник — віддати цей товар суперникові чи прив'язати суперника до іншого товару. Якщо в замовленнях чи відвантаженнях є рядки з цим товаром, буде запитано, чи перенести їх разом з прив'язкою. Кожна така дія — одна операція в базі: зв'язок, документи й журнал завжди змінюються разом.
8. Завантаження замовлень
Якщо skip_pull не містить orders, abasyn оновлює "Онлайн замовлення" та
"Онлайн доставки" після кожного проходу каталогу, у межах того самого завдання.
Каталог синхронізується першим, бо рядки співставляються за
CR_TOVAR_STOREFRONTS.REMOTE_TOVAR_ID, а потім за артикулом.
- Неспівставлений рядок зберігається з порожнім
TOVAR_IDі перезіставляється проходом після каталогу (POST /api/documents/orders/reresolve-lines, показникlines_reresolved). Вручну перезавантажувати замовлення не потрібно. - Покупець згортається в одного контрагента «онлайн-покупець» на вітрину;
справжні ім'я, телефон і адреса лишаються текстом у
CLIENT_INFO/SHIPPING_INFO. - Валюта визначається через
R_CURRENCIES.EXT_CODE; заповніть код ISO один раз для кожної валюти, у якій продаєте, інакшеCURRENCY_IDлишиться порожнім. - Замовлення, яке відкинула база, не втрачається: заголовок повторюється один раз
у спрощеному вигляді, позначається в
ONL_ORDER.NOTEі рахується як попередження. - Замовлення, яке остаточно не вдалося зберегти, повністю зберігається в
abasyn_state.jsonі повторно надсилається до abrest при наступному запуску синхронізації, без звертання до маркетплейсу. Закладка, скасована заmax_retriesчиmax_age_hours, записується в окремий JSON-файл поруч із файлом стану й супроводжується помилкою в журналі. Стан завдання показуєN awaiting retryі у разі успіху самостійно повертається до OK.
Словник статусів
R_ORDER_STATUS.EXT_CODE з областю дії за PLATFORM_ID, і він наповнюється
сам: невідомий віддалений код створюється автоматично для цього майданчика з
читабельною назвою (checkout-draft → «Checkout draft»). Перейменовуйте вільно —
ключем лишається EXT_CODE.
- Словники Prom і WooCommerce різні (
receivedпротиprocessing); рядок із порожнімPLATFORM_IDє спільним запасним варіантом, а точний збіг за майданчиком має пріоритет. - Видалений статус вважається свідомим видаленням і не відновлюється.
- При оновленні статус має двох господарів: віддалене значення застосовується,
лише якщо воно свіжіше за
ONL_ORDER.STATUS_SYNC_TS, тож замовлення, просунуте локально, не відкочується запізнілим завантаженням.
9. Розклад
Перший запуск синхронізації припадає приблизно на 10 с після старту, щоб не перевантажувати запуск служби.
- Завдання ніколи не накладаються: якщо ви вказали інтервал запуску 600 секунд але поточне завдання не встигло закінчитись за 10 хвилин, нове завдання пропускається.
- Інтервал відраховується від завершення попереднього запуску.
- Запуски виконуються послідовно для всіх конекторів — одне довге перше завантаження змушує решту чекати. Дайте йому завершитися, перш ніж додавати наступні магазини.
interval: 1 безпечний і формально легітимний, але позбавлений сенсу: кожне завдання
спершу перевіряє магазин і перечитує дерево категорій, яке завжди забирається повністю,
а маркетплейси обмежують частоту наполегливого опитування, в тому числі відправкою
помилки 429 / Too many requests. abasyn при такій відповіді автоматично сповільнюється.
Для звичайної роботи беріть 180–600, для масивних магазинів з частими оновленнями 60.
Якщо справді важать секунди, опитування — хибний механізм: магазин має сповіщати
"Рахівницю" через webhook. Це запит на нову можливість, а не значення в конфігурації.
interval: 0 разом із кнопкою Запустити синхронізацію зараз — цілком робоча
схема, синхронізація відбувається лише на вимогу.
10. Обидва напрямки інкрементальні
Кожне завдання тримає свої позначки прогресу (watermark) у abasyn_state.json
(шлях визначається за стандартним розташуванням конфігурації — /opt/abacus/etc/,
~/.config/abacus/, інакше каталог бінарника), ключем є ІД вітрини:
| Ключ | Що покриває |
|---|---|
catalog_since |
товари |
order_since |
замовлення |
push_since |
передавання статусів замовлень |
product_push_since |
передавання цін, залишків, назв |
listing_since |
розміщення та зняття з продажу |
image_push_since |
вивантаження зображень |
Позначка просувається лише після повного проходу. Обмеження режиму probe,
невдале чи часткове отримання даних або скасування при зупинці служби утримують
її, і наступний запуск перезапитує пропущені дані. При цьому завантаження ідемпотентне, тож
повторний запуск ніколи не створює дублікатів.
- Prom округлює
date_modifiedдо години для товарів і до секунди для замовлень, а його фільтр включний. Тобто всі товари створені у проміжку від наприклад 15:00:00 до 15:59:59 будуть мати однаковий час модифікації. Конектор утримує відкритий інтервал і перезабирає його, доки той не закриється в UTC, щоб пізніша правка з тією ж округленою позначкою не була пропущена. - WooCommerce використовує
modified_afterізdates_are_gmt=true, виключний із точністю до секунди, тож позначка одразу переходить на найсвіжішийdate_modified_gmt. - Категорії завжди забираються повністю — це одна невелика сторінка без дати зміни, за якою можна було б фільтрувати.
- Зображення лишаються завантаженням «один раз»; товар із уже завантаженим зображенням повторно не читається.
Повне перезавантаження — це видалення позначки: зупиніть abasyn, видаліть
потрібний ключ (або весь abasyn_state.json), запустіть службу знову. Це потрібно
після переспрямування магазину на нову базу. Це безпечно, але для великого
магазину не швидко: перша синхронізація може тривати багато годин, плануйте її заздалегідь.
11. Зображення товарів
"Рахівниця" забирає фото один раз і лише для товару, який їх ще не має.
Зображення вивантажується, якщо його ще жодного разу не надсилали на цю вітрину або якщо його вміст, тип чи порядок показу змінилися з моменту останнього надсилання. Тому заміна фото в "Рахівниці" замінює його і в магазині наступним запуском. Кожне вивантаження записується окремо для вітрини, тож товар, виставлений у двох магазинах, тримає окремий ІД медіафайлу для кожного і ніколи не вивантажується двічі в один і той самий.
Як і для решти передавань, перший запуск після увімкнення лише ініціалізує позначку прогресу й нічого не надсилає: зображення, які вже є в каталозі, вважаються такими, що збігаються з магазинними.
Видалення зображення — єдиний випадок, який не поширюється далі. Коли ви прибираєте фото в "Рахівниці", локальний запис зникає, але до магазину нічого не надсилається: галерея вирівняється наступного разу, коли зміниться будь-яке інше зображення цього товару. Зміна порядку, навпаки, застосовується одразу.
12. Ключові слова товарів
Список ключових слів продавця забирається разом із товаром у вбудований
блоб-тег −104 «Ключові слова» (видно у властивостях товару на вкладці
«Користувацькі параметри» одним рядком-передпоказом; кнопка «…» відкриває повний
список). Prom дає власне поле keywords; WooCommerce — tags[], об'єднані з
фокусними ключовими словами Rank Math / Yoast, якщо додаток встановлено, із
дедуплікацією без урахування регістру.
Відсутній або порожній список означає, що поле не надсилається, а ненадіслане
поле лишає збережений тег недоторканим — магазин, який перестав повідомляти
ключові слова, ніколи не стирає те, що є в "Рахівниці". Якщо skip_push не
містить products, тег передається назад до магазину.
Якщо щось не працює
| Симптом | Причина |
|---|---|
| «Службу Abasyn не налаштовано для цього робочого місця» | У профілі немає секції abasyn: або стоїть enabled: false. |
| «У вас немає токена авторизації» | Для профілю не активовано служби. |
| «Спершу вкажіть тип конектора для майданчика» | Порожній CONNTYPE майданчика. |
| Нічого не синхронізується | Не збережено блок налаштувань (неналаштоване завдання лишається вимкненим); або знято Активний; або interval: 0 і ніхто не запускав завдання. |
| 401 від маркетплейсу | Хибний токен або secret. З URL це не пов'язано — токени ключуються за ІД вітрини. Якщо вітрину видаляли й створювали заново, токен належить старому ІД. |
| 401 від abrest | Застарілий кешований ключ abrest. POST /api/connectors/reload очищає кеш; якщо самого токена немає — переактивуйте служби у Складі. |
| Прийшло лише 10 товарів і 10 замовлень | mode: probe. Підвищіть до readonly. |
| Товари є, замовлень немає | orders вказано в skip_pull, або з моменту позначки нічого не змінилося. |
| Зміна в магазині не надійшла | Запуски інкрементальні. Щоб узгодити все, очистіть catalog_since. |
| Зміна в "Рахівниці" не пішла | mode нижче за live, або сутність указано в skip_push, або пропущено products (що забирає із собою й names, але вже не stock). Це також очікувано на першому запуску після підвищення до live: позначка прогресу запису встановлюється на «зараз», тож змініть запис ще раз. |
| Замовлення потрапляють не на той товар | співставлення переплутане — перевірте колонку «Стан синхронізації» товару вітрини і виправте кнопкою «Переприв'язати товар» (розділ 7). |
| Нових товарів немає в дереві груп | landing_group_id: 0. |
| «Без групи: N» червоним | Ті самі товари: їхні характеристики діють в усіх групах. Вкажіть landing_group_id, а якщо теги мають діяти в іншій групі — ще й tag_group_id. |
| Товар перестав передаватися | PUSH_MISS_COUNT досяг push_miss_limit — у магазині такого товару вже немає. Приберіть співставлення або розмістіть товар заново. |
| Новий товар так і не з'явився на Prom | Так і має бути. Prom приймає створення товарів лише імпортними файлами. |
| Фото, додане в "Рахівниці", не з'явилося у WooCommerce | images вказано в skip_push, або mode нижчий за live. Стан завдання показує Job-<ІД>-images із причиною. |
| Фото не з'явилося на Prom | Так і має бути: в API Prom немає поля для зображень. |
| Фото видалено в "Рахівниці", але воно лишилося в магазині | Відоме обмеження; зникне, коли зміниться інше зображення цього товару. |
WooCommerce відхиляє все з invalid_username |
Збережено пароль облікового запису. Створіть пароль застосунку (Users → Profile → Application Passwords) і введіть його заново, крок 3. |
| WooCommerce віддає 401/403 лише на вивантаженні зображень | Користувачеві WordPress бракує права upload_files. Надайте йому роль Shop Manager. |
| Запуск завершився з «order fetch incomplete; watermark held» | Неповний прохід сторінок. Отримане збережено, наступний запуск перезапитає пропуск. |
| Після оновлення служби ендпойнт віддає 404/401 | abrest реєструє маршрути під час старту — перезапустіть abrest -r. |
Діагностика
$KEY — ключ API abasyn.
Один запис на конектор: ІД вітрини, поля label, mode, enabled,
last_run, last_stats, last_error. Результати передавання видно як
pushed / would_push / skipped_same / skipped_unsupported / not_found / errors,
для зображень — candidates / goods / uploaded / would_upload / attached / errors;
статистика каталогу містить goods_unscoped, статистика замовлень —
lines_reresolved.
# Негайний запуск (цифра = ІД вітрини)
curl -H "X-API-KEY: $KEY" -X POST http://localhost:4602/api/jobs/7/run
# Стан служби; кожне завдання видно як виконавця Job-<ІД>, а для напрямку
# запису - ще й Job-<ІД>-push, Job-<ІД>-products, Job-<ІД>-listing, Job-<ІД>-images
curl -H "X-API-KEY: $KEY" http://localhost:4602/api/status
# Чи бачить abrest базу даних
curl -H "X-API-KEY: $ABREST_KEY" http://localhost:4603/api/status
# -> {... "workers":[{"workerName":"DBWorker","status":"OK", ...}]}
fetched N products, fetched N
orders, job … ok: …). Повний контракт abrest доступний за
GET /api/openapi.json.