Обмен МойСклад и AmoCRM: остатки, отгрузки, стадии сделок

Сделка в CRM порождает заказ и отгрузку в учёте, оплата и отгрузка возвращают стадию — номенклатуру не вбивают дважды.

Стек AmoCRM, Python, REST API, МойСклад, очереди

Я делал двусторонний обмен МойСклад и AmoCRM для оптовых продаж: сделка в CRM порождала заказ покупателя и отгрузку в учёте, а факты оплаты и отгрузки возвращали стадию сделки. Менеджер не вбивал номенклатуру дважды.

Я написал коннектор к обоим API: справочник контрагентов и номенклатуры, сопоставление SKU и кастомных полей AmoCRM, создание/обновление заказа в МойСклад по смене стадии. Источник правды по остаткам — МойСклад; в сделку писал доступность и резерв, чтобы не продавали «с пустой полки».

Я программировал идемпотентный обмен документов: заказ, счёт, отгрузка, возврат. Повтор webhook не создавал второй заказ; внешние id хранил в обеих системах. Конфликты (менеджер поправил сумму в CRM, кладовщик уже отгрузил в учёте) закрывал правилами: после отгрузки финансовые поля из CRM не перезаписывают учёт.

Я собрал очередь синхронизации с ретраями, разбором 429/5xx, батчами справочников (тысячи SKU) и инкрементальным diff, а не полной выгрузкой каждую ночь. Расхождения ловил сверкой: сделка без заказа, отгрузка без стадии «успешно реализовано».

Я вывел админ-лог обмена и ручной «переотправить документ». Стек: Python, AmoCRM REST, МойСклад JSON API, PostgreSQL, Redis, Docker. NDA: юрлицо и аккаунты не публикуются.