Для українського інтернет-магазину чи дистриб'ютора дві інтеграції визначають, чи економить Odoo час, чи створює ручну роботу: доставка і оплати. Більшість замовлень їде Новою Поштою, а дедалі більша частка оплачується онлайн через банківський еквайринг, як-от monobank. Без інтеграції менеджери копіюють адреси в кабінет перевізника, вставляють номери ТТН назад в Odoo і звіряють оплати вручну. У статті показуємо, як ми підключаємо Odoo до обох сервісів: архітектура, реальні виклики API, безпека вебхуків і підводні камені, що забирають час на реальних проєктах.

Що має робити інтеграція

Хороша інтеграція прибирає кожен ручний крок між «замовлення підтверджено» і «гроші звірено»:

  1. Введення адреси з валідацією. Клієнт або менеджер обирає місто і відділення (чи поштомат) з довідника Нової Пошти замість вільного тексту.
  2. Розрахунок вартості доставки в комерційній пропозиції чи на checkout сайту.
  3. Створення ТТН (експрес-накладної) під час валідації складського переміщення з номером, збереженим у документі.
  4. Відстеження статусу з автоматичним оновленням в Odoo: у дорозі, прибула у відділення, отримано, повернення.
  5. Звірка накладеного платежу, щоб суми післяплати зіставлялися з рахунками.
  6. Онлайн-оплата через рахунок еквайрингу з посиланням, а позначка «оплачено» — лише за перевіреним вебхуком.

Архітектура: де живе логіка

Обидві інтеграції ми реалізуємо як кастомні модулі Odoo, що розширюють стандартні моделі, а не як окремий middleware:

Модель Odoo Розширення
delivery.carrier Новий тип доставки «Нова Пошта» з ключем API і методом розрахунку ціни
stock.picking Номер ТТН, статус, друк етикетки, посилання для відстеження
res.partner Посилання на місто і відділення Нової Пошти для отримувачів
payment.provider Новий провайдер «monobank» з токеном мерчанта і ендпоінтом вебхука
payment.transaction ID рахунку в банку, мапінг статусів, посилання на фіскальний чек

Фреймворки доставки й оплат в Odoo вже ведуть потік замовлення, тож кастомний перевізник і платіжний провайдер вбудовуються в checkout сайту, замовлення продажу та бухгалтерію без змін у ядрі. Це важливо при кожному оновленні — про це у статті Odoo 17 vs Odoo 18.

Нова Пошта: як працює API

Нова Пошта надає JSON API за адресою https://api.novaposhta.ua/v2.0/json/. Кожен виклик — POST з однаковим «конвертом»: ваш ключ API, назва моделі, назва методу і властивості методу. Ключ генерується в бізнес-кабінеті.

Пошук відділень у місті виглядає так:

import requests

NP_URL = "https://api.novaposhta.ua/v2.0/json/"

def np_call(api_key, model, method, props):
    r = requests.post(NP_URL, json={
        "apiKey": api_key,
        "modelName": model,
        "calledMethod": method,
        "methodProperties": props,
    }, timeout=15)
    r.raise_for_status()
    data = r.json()
    if not data.get("success"):
        raise UserError("Nova Poshta: " + "; ".join(data.get("errors", [])))
    return data["data"]

branches = np_call(key, "Address", "getWarehouses",
                   {"CityRef": city_ref, "FindByString": "15", "Limit": "20"})

Той самий конверт використовується для створення ТТН: модель InternetDocument, метод save, з посиланнями на відправника й отримувача, типом вантажу, вагою, оголошеною вартістю, платником і способом оплати, а також, за потреби, зворотною доставкою для накладеного платежу. Відстеження — модель TrackingDocument, метод getStatusDocuments, до 100 номерів ТТН за виклик.

Практичні правила, яких ми дотримуємося:

  • Кешуйте довідники локально. Міста й відділення змінюються рідко; синхронізуйте їх щоночі в таблиці Odoo замість виклику API на кожне натискання клавіші на checkout.
  • Зберігайте посилання, а не назви. Нова Пошта ідентифікує міста, відділення і контрагентів через UUID у полі Ref. Назви змінюються й дублюються, посилання — ні.
  • Оновлюйте статуси пакетно. Запланована дія опитує статуси відкритих ТТН пакетами, а не одним запитом на кожне переміщення.
  • Мапте статуси явно. Перекладіть коди статусів перевізника в невеликий набір станів Odoo і вирішіть, які з них запускають дії — створення повернення чи сповіщення клієнта.

Еквайринг monobank: рахунки і вебхуки

API мерчанта monobank (документація еквайрингу monobank) побудований на моделі рахунків:

  1. Ваш сервер створює рахунок через POST /api/merchant/invoice/create з токеном мерчанта в заголовку X-Token. Сума передається в мінімальних одиницях (копійках) разом із кодом валюти, посиланням на ваше замовлення, redirectUrl для клієнта і webHookUrl для сповіщень про статус.
  2. Відповідь містить ID рахунку і URL сторінки оплати. Odoo перенаправляє туди клієнта.
  3. Коли статус оплати змінюється, monobank надсилає POST на ваш вебхук, підписаний ECDSA-підписом у заголовку X-Sign.
  4. Ваш сервер перевіряє підпис публічним ключем з /api/merchant/pubkey і лише потім оновлює транзакцію. Odoo підтверджує замовлення і, залежно від налаштувань, створює та звіряє платіж.
import base64, hashlib
from ecdsa import VerifyingKey, BadSignatureError
from ecdsa.util import sigdecode_der

def verify_mono_webhook(raw_body: bytes, x_sign: str, pubkey_b64: str) -> bool:
    # /api/merchant/pubkey повертає PEM-ключ, закодований у base64
    vk = VerifyingKey.from_pem(base64.b64decode(pubkey_b64))
    try:
        return vk.verify(base64.b64decode(x_sign), raw_body,
                         hashfunc=hashlib.sha256, sigdecode=sigdecode_der)
    except BadSignatureError:
        return False

Ніколи не позначайте замовлення оплаченим лише тому, що клієнт повернувся на redirectUrl, — це можна підробити. Доказом оплати є тільки перевірений вебхук або серверний запит статусу до /api/merchant/invoice/status.

Фіскалізація і бухгалтерія

Роздрібні продажі в Україні, як правило, потребують фіскального чека з РРО або програмного РРО (ПРРО). API еквайрингу має ендпоінти, пов'язані з фіскальними чеками, але чи використовувати фіскалізацію банку чи окремого провайдера ПРРО — залежить від вашої схеми і бухгалтера. Вирішіть це на старті: від цього залежить, яка система є джерелом правди для чеків. Пам'ятайте, що стандартна українська локалізація Odoo покриває лише план рахунків, як ми писали у статті Міграція з 1С на Odoo.

У бухгалтерії явно прив'яжіть кожен потік до журналів:

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

Підводні камені з реальних проєктів

  • Якість адрес. Вільні адреси зі старих систем рідко збігаються з довідниками перевізника. Заплануйте одноразову чистку і далі вимагайте вибір із довідника.
  • Ліміти й таймаути. Зовнішні API сповільнюються в пікові години. Використовуйте таймаути, повтори з backoff і черги завдань, щоб повільний перевізник не блокував воркери Odoo, — це часта причина гальмувань, описаних у статті Оптимізація продуктивності Odoo.
  • Ідемпотентність. Вебхуки можуть прийти двічі або не в тому порядку. Обробляйте їх ідемпотентно за ID рахунку і статусом.
  • Тестові середовища. Використовуйте окремі ключі API і токени мерчанта для staging і не дозволяйте staging-базі створювати реальні ТТН чи списувати гроші з реальних карток.
  • Повернення. Моделюйте зворотні відправлення і повернення коштів одразу; додавати їх потім болісно.

Строки і бюджет

Для типового магазину на Odoo з одним складом модуль Нової Пошти (довідники, ТТН, відстеження, післяплата) і платіжний провайдер monobank (рахунки, вебхуки, повернення) разом займають три-п'ять тижнів, включно з тестуванням на реальних акаунтах. Зазвичай це невелика частина ширшого проєкту, загальну економіку якого ми розбираємо у статті Скільки коштує впровадження Odoo.

Чек-лист тестування перед запуском

  • Синхронізація довідника міст і відділень виконується щоночі й обробляє перейменовані чи закриті відділення
  • ТТН створюються з правильною вагою, оголошеною вартістю і платником для кожного способу доставки
  • Суми накладеного платежу збігаються з рахунками, включно з частковими оплатами
  • Оновлення статусів переводять переміщення в очікувані стани, включно з поверненнями
  • Вебхуки оплат перевіряються, обробляються ідемпотентно і протестовані на дублях і зміні порядку
  • Повернення коштів працюють від початку до кінця і відображаються в бухгалтерії
  • Staging використовує окремі ключі API і не може створювати реальні відправлення чи списання

FAQ

Чи є готові модулі в Odoo App Store? Так, існують безкоштовні й комерційні модулі. Перш ніж покладатися на них у ключовій логістиці, перевірте сумісність з вашою версією Odoo, якість коду і підтримку.

Чи може клієнт обрати поштомат на checkout? Так. Поштомати входять до довідника відділень перевізника, їх можна запропонувати окремим способом доставки на сайті.

Чи потрібні вебхуки, якщо можна опитувати статус оплати? Вебхуки дають миттєве підтвердження, опитування — корисний запасний варіант для пропущених сповіщень. Використовуйте обидва.

Чи підходить цей підхід для інших перевізників і банків? Так. Фреймворки перевізників і платіжних провайдерів в Odoo універсальні, тож Укрпошта, Meest чи інші еквайри інтегруються за тим самим патерном.

Джерела

  1. Нова Пошта. API-ендпоінт і документація для розробників (доступна в бізнес-кабінеті Нової Пошти).
  2. monobank. Документація API еквайрингу.
  3. Odoo. Документація з оновлення.
  4. Odoo. Fiscal localizations.
  5. Odoo на GitHub. Модуль української локалізації.