Skip to Content

Odoo 19 і маркетплейси: TikTok Shop із коробки, Tokopedia — через сторонні рішення

9 серпня Odoo опублікувала в блозі анонс: нативний конектор TikTok Shop і Tokopedia для Enterprise 19.0+. Переклав, звірив із технічною документацією 19.0 — і з'ясував, що з двох маркетплейсів у заголовку задокументований лише один.

Що каже блог

Ключова цитата з оригіналу — умова доступу:

«No third-party apps required. This feature is available to users with an active Odoo Enterprise subscription for version 19.0 or higher.»

Тобто це не community-конектор і не окремий платний додаток з Apps Store — фіча вшита в Enterprise-підписку і працює на всіх трьох варіантах хостингу: Odoo Online, Odoo.sh, on-premise. У блозі перелічено чотири напрямки: синхронізація каталогу, замовлень, залишків і доставки.

Розглянемо, що насправді описано в setup.html і manage.html

Технічна документація 19.0 підтверджує написане в блозі — але тільки для TikTok Shop. Підключення йде через TikTok Shop Partner Center, категорія «App developers (ISV)»:

Redirect URL:
https://<database url>.odoo.com/tiktok/return_from_authorization

Обов'язкові API-сервіси (Partner Center → App & Service):
Finance Information
Fulfillment Basic
Logistics Basic
Order Information
Product Basic
Product Modify
Shop Authorized Information
Global Shop Information

Після авторизації Odoo сама заводить крон-задачі з різним кроком: замовлення й вебхуки — кожні 5 хвилин, етикетки доставки — кожні 15, інвентар — кожні 30. Підтримується лише модель Fulfilled by Merchant (FBM): продавець сам організовує відправку і повертає номер відстеження в TikTok.

Важливо! Синхронізуються тільки замовлення в статусах AWAITING_SHIPMENT і AWAITING_COLLECTION — ті, що реально потребують дії. SHIPPED, CANCEL, UNPAID, COMPLETED в Odoo не тягнуться. І окремо в документації прямим текстом написано: скасування замовлення в Odoo на TikTok Shop не відображається. Синхронізація статусів — одностороння, з майданчика в Odoo.

А де Tokopedia?

Тут блог випереджає документацію. Окремої сторінки на кшталт tokopedia_connector/setup.html в 19.0 немає — у переліку конекторів (toctree сторінки sales.html) значаться тільки Amazon, Lazada, Shopee й TikTok Shop. Офіційного вбудованого конектора для Tokopedia в Odoo немає, і задокументований він теж ніде не був. Але це не означає, що на ринку порожньо: на Apps Store знайшлося кілька сторонніх рішень — izi_tokopedia (14.0-17.0), старіший yudha_tokopedia_connector (12.0-14.0) і, що важливіше, платний tokopedia_store_management (автор ECOSIRE, €430.43) саме під версію 19.0. Тому точніше формулювання таке: офіційного конектора для Tokopedia в 19.0 немає, документації на нього теж немає, а те, чого бракує в Enterprise-підписці, закривають сторонні розробники.

Український зріз: та сама задача, інша інфраструктура

У нас немає TikTok Shop чи Tokopedia, зате є та сама задача на інших майданчиках — модулі kw_marketplace_rozetka_api, kw_marketplace_promua_api, kw_marketplace_kasta_hub_api, kw_marketplace_horoshop_api. Архітектура своя: базовий фреймворк kw_marketplace (моделі kw.mp.merchant, kw.mp.offer, kw.mp.stage) і окремий платний модуль на кожен майданчик, а не одна вбудована Enterprise-фіча.

Крон у нас теж інтервальний, тільки без TikTok-івської диференціації 5/15/30 хвилин на різні сутності — усе на п'яти хвилинах:

<record id="kw_marketplace_kw_mp_merchant_load_orders" model="ir.cron">
    <field name="name">Marketplace: load_orders</field>
    <field name="model_id" ref="model_kw_mp_merchant"/>
    <field name="state">code</field>
    <field name="code">model.cron_load_orders()</field>
    <field name='interval_number'>5</field>
    <field name='interval_type'>minutes</field>
</record>

Залишки ми не тягнемо батчем раз на пів години — реагуємо на подію одразу. Запис у stock.quant кладе товар у чергу на перерахунок офера, а той самий п'ятихвилинний крон її розбирає:

class StockQuant(models.Model):
    _inherit = 'stock.quant'

    def write(self, vals):
        res = super().write(vals)
        self.env['kw.mp.offer'].action_reset_by_product_ids(
            self.sudo().mapped('product_id.id'))
        return res

Тепер про різницю, яка справді цінна для проєктування такої інтеграції. Неправильно закладати в архітектуру універсальне правило «статус завжди летить в обидва боки» — це неправда навіть для одного вендора. TikTok Shop, за офіційною документацією, синхронізує статуси лише в один бік: скасування в Odoo на майданчику не з'явиться. Правильно перевіряти це окремо для кожного маркетплейсу: у Rozetka, наприклад, зворотний зв'язок є — зміна стадії замовлення в Odoo реально йде назад через PUT /orders/{id}/:

def action_kw_mp_stage_change_rozetka(self):
    data = {'status': int(self.kw_mp_new_stage_id.ref)}
    res = self.kw_mp_merchant_id.request(
        method='PUT', url=f'/orders/{self.kw_mp_ref}/', data=data,
        silent=False, )
    if res:
        self.kw_mp_update_from_marketplace(
            merchant=self.kw_mp_merchant_id, res=res.get('content'), )
    return res

Модель доставки теж не переноситься один в один — і в самому Rozetka таких моделей насправді дві. TikTok Shop працює по FBM: продавець сам генерує ярлик і повертає tracking number. Прямий аналог у Rozetka — власна кур'єрська мережа Rozetka Delivery (rz-delivery-octopus.rozetka.ua): окрема модель тримає відправника й отримувача з типами door-door/door-dept/dept-door/dept-dept, і продавець сам через наш модуль замовляє забір і повертає track. Але коли покупець на Rozetka обирає доставку Новою поштою, у гру вступає інший ланцюжок модулів — kw_marketplace_rozetka_api_npkw_marketplace_npkw_novaposhta_delivery. Розпізнавання йде за delivery_service_id з відповіді маркетплейсу:

# kw_marketplace_np — загальний диспетчер для будь-якого маркетплейсу
def is_np_delivery(self, res):
    self.ensure_one()
    fname = f'is_np_delivery_{self.code}'
    return getattr(self, fname)(res) if hasattr(self, fname) else False


# kw_marketplace_rozetka_api_np — конкретна перевірка для Rozetka
def is_np_delivery_rozetka(self, res):
    return res.get('delivery') and \
        res.get('delivery').get('delivery_service_id') in (5, 43660)

Далі модуль-адаптер підбирає відділення чи адресу через kw.np.warehouse/kw.np.city і передає їх у kw_novaposhta_delivery, який уже й генерує накладну. Два перевізники в одному маркетплейсі — і два різні шматки коду під капотом. А от аналога TikTok-івського FBS — коли платформа сама зберігає і комплектує товар — у Rozetka чи Prom немає: склад завжди на боці продавця.

Ну ось і вся різниця між «нативний Enterprise-конектор для азійського ринку» і «набір окремих модулів для українського»: задача одна — товари, замовлення, залишки, доставка, — а хто відповідає за останню милю і чи їде статус в обидва боки, щоразу треба перевіряти окремо.

Переклад і адаптація статті https://www.odoo.com/blog/business-hacks-1/odoo-tiktok-shop-and-tokopedia-integration-2380. Код і поведінку перевірено на Odoo 19.

Odoo 19 і маркетплейси: TikTok Shop із коробки, Tokopedia — через сторонні рішення
KitWorks, Volodymyr Karabanov 6 серпня 2026 р.
Поділитися цією публікацією
Теги
Архів