Содержание

  1. Типичные проблемы при ручной работе
  2. API Wildberries и Ozon
  3. Синхронизация остатков
  4. Автоматическое обновление цен
  5. Получение и обработка заказов
  6. Авто-ответы на отзывы
  7. Аналитика продаж
  8. Архитектура системы

Продавцы на маркетплейсах тратят огромное количество времени на рутину: обновление остатков, изменение цен, ответы на отзывы, выгрузку заказов. При работе с несколькими площадками это превращается в кошмар — данные расходятся, менеджеры не успевают, штрафы за стокаут растут.

Python + официальные API решают всё это автоматически.

1. Типичные проблемы при ручной работе

  • Расхождение остатков — продали на WB, забыли обновить на Ozon — штраф за отмену
  • Устаревшие цены — конкурент снизил цену, вы узнали через день — потеряли продажи
  • Задержка обработки заказов — менеджер не проверил кабинет вовремя — просрочка сборки
  • Непроработанные отзывы — негативные отзывы без ответа снижают рейтинг
  • Нет сводной аналитики — данные по площадкам в разных кабинетах, сводить вручную
Реальный кейс: клиент из Екатеринбурга терял 80 000 ₽/мес на штрафах WB за стокаут — менеджеры не успевали обновлять остатки при продажах на других площадках. После автоматизации штрафы стали 0 ₽.

2. API Wildberries и Ozon

Wildberries API

  • Документация: openapi.wildberries.ru
  • Авторизация: API-ключ из личного кабинета (Профиль → Настройки → Доступ к API)
  • Базовый URL: https://suppliers-api.wildberries.ru
  • Лимиты: 5–60 запросов/мин в зависимости от метода

Ozon API

  • Документация: docs.ozon.ru/api/seller
  • Авторизация: Client-Id + Api-Key из личного кабинета
  • Базовый URL: https://api-seller.ozon.ru
  • Лимиты: 1000–10000 запросов/мин в зависимости от метода
# pip install requests

import requests
from typing import Optional

class WildberriesAPI:
    BASE_URL = 'https://suppliers-api.wildberries.ru'

    def __init__(self, api_key: str):
        self.headers = {
            'Authorization': api_key,
            'Content-Type': 'application/json'
        }

    def _get(self, endpoint: str, params: dict = None):
        resp = requests.get(
            f'{self.BASE_URL}{endpoint}',
            headers=self.headers, params=params
        )
        resp.raise_for_status()
        return resp.json()

    def _post(self, endpoint: str, data: dict):
        resp = requests.post(
            f'{self.BASE_URL}{endpoint}',
            headers=self.headers, json=data
        )
        resp.raise_for_status()
        return resp.json()


class OzonAPI:
    BASE_URL = 'https://api-seller.ozon.ru'

    def __init__(self, client_id: str, api_key: str):
        self.headers = {
            'Client-Id': client_id,
            'Api-Key': api_key,
            'Content-Type': 'application/json'
        }

    def _post(self, endpoint: str, data: dict):
        resp = requests.post(
            f'{self.BASE_URL}{endpoint}',
            headers=self.headers, json=data
        )
        resp.raise_for_status()
        return resp.json()

3. Синхронизация остатков

Самая критичная задача — синхронизация остатков между вашей системой учёта (1С, база данных) и маркетплейсами. Запускается каждые 15–30 минут.

def sync_stocks_to_wb(wb: WildberriesAPI, stocks: list[dict]):
    """
    stocks = [{'sku': '123456', 'amount': 50}, ...]
    sku — баркод товара на WB
    """
    payload = {'stocks': [
        {'sku': s['sku'], 'amount': s['amount']}
        for s in stocks
    ]}
    result = wb._post('/api/v3/stocks/{warehouseId}', payload)
    return result


def sync_stocks_to_ozon(ozon: OzonAPI, stocks: list[dict]):
    """
    stocks = [{'offer_id': 'ART-001', 'stock': 50, 'warehouse_id': 123}]
    offer_id — артикул товара в вашей системе
    """
    payload = {'stocks': [
        {
            'offer_id': s['offer_id'],
            'stock': s['stock'],
            'warehouse_id': s['warehouse_id']
        }
        for s in stocks
    ]}
    result = ozon._post('/v2/products/stocks', payload)
    return result


# Основная функция синхронизации
def sync_all_stocks():
    # Получаем актуальные остатки из 1С или БД
    stocks = get_stocks_from_db()

    # Синхронизируем на обе площадки параллельно
    import concurrent.futures
    with concurrent.futures.ThreadPoolExecutor() as ex:
        wb_future = ex.submit(sync_stocks_to_wb, wb, prepare_wb_stocks(stocks))
        oz_future = ex.submit(sync_stocks_to_ozon, ozon, prepare_ozon_stocks(stocks))

    print(f'Синхронизировано {len(stocks)} позиций на WB и Ozon')

4. Автоматическое обновление цен

Репрайсер — инструмент который следит за ценами конкурентов и автоматически корректирует ваши цены по заданным правилам.

def update_prices_ozon(ozon: OzonAPI, prices: list[dict]):
    """Обновление цен на Ozon"""
    payload = {'prices': [
        {
            'offer_id': p['offer_id'],
            'price': str(p['price']),
            'old_price': str(p.get('old_price', '')),
            'min_price': str(p.get('min_price', '')),
        }
        for p in prices
    ]}
    return ozon._post('/v1/product/import/prices', payload)


def repricer(my_price: float, competitor_price: float,
              min_price: float, max_price: float) -> float:
    """Простой репрайсер: держимся на 1% ниже конкурента"""
    target = competitor_price * 0.99
    # Не опускаемся ниже минимума и не поднимаемся выше максимума
    return max(min_price, min(max_price, target))

5. Получение и обработка заказов

def get_new_orders_wb(wb: WildberriesAPI) -> list:
    """Получить новые заказы с WB за последние 24 часа"""
    from datetime import datetime, timedelta
    date_from = (datetime.now() - timedelta(hours=24)).strftime('%Y-%m-%dT%H:%M:%SZ')
    result = wb._get('/api/v3/orders', {'dateFrom': date_from, 'limit': 1000})
    return result.get('orders', [])


def process_new_orders():
    """Основной цикл обработки новых заказов"""
    wb_orders = get_new_orders_wb(wb)
    ozon_orders = get_new_orders_ozon(ozon)

    all_orders = wb_orders + ozon_orders
    new_count = 0

    for order in all_orders:
        order_id = order.get('id') or order.get('order_id')

        # Проверяем не обработан ли уже
        if order_exists_in_db(order_id):
            continue

        # Сохраняем в БД
        save_order_to_db(order)

        # Создаём задачу на сборку
        create_assembly_task(order)

        # Уведомляем склад в Telegram
        send_telegram(
            f'📦 Новый заказ #{order_id}\n'
            f'Площадка: {order.get("marketplace", "WB")}\n'
            f'Товар: {order.get("article", "")}'
        )
        new_count += 1

    print(f'Обработано новых заказов: {new_count}')

6. Авто-ответы на отзывы

Отвечать на каждый отзыв вручную — часы работы. Система авто-ответов обрабатывает типовые отзывы автоматически, сложные передаёт менеджеру:

import openai

def generate_review_reply(review_text: str, rating: int) -> str:
    """Генерация ответа на отзыв с помощью GPT-4"""
    tone = 'сочувствующий и решающий проблему' if rating <= 3 else 'благодарный'

    response = openai.chat.completions.create(
        model='gpt-4o',
        messages=[{
            'role': 'system',
            'content': f"""Ты менеджер интернет-магазина.
Пиши короткие (2-3 предложения), искренние ответы на отзывы.
Тон: {tone}. Не используй шаблонные фразы."""
        }, {
            'role': 'user',
            'content': f'Отзыв (оценка {rating}/5): {review_text}'
        }]
    )
    return response.choices[0].message.content


def process_reviews_ozon(ozon: OzonAPI):
    """Обработать неотвеченные отзывы на Ozon"""
    reviews = ozon._post('/v1/review/list', {
        'status': 'ALL', 'limit': 100
    }).get('reviews', [])

    for review in reviews:
        if review.get('comment_for_review'):
            continue  # уже отвечено

        rating = review['rating']
        text = review.get('text', '')

        # Низкие оценки — передаём менеджеру
        if rating <= 2:
            send_telegram(f'⚠️ Низкий отзыв {rating}⭐:\n{text[:200]}')
            continue

        # Генерируем и публикуем ответ
        reply = generate_review_reply(text, rating)
        ozon._post('/v1/review/comment/create', {
            'review_id': review['id'],
            'text': reply
        })

7. Аналитика продаж

Сводная аналитика по всем площадкам в одном месте — ежедневный отчёт в Telegram или Google Sheets:

def daily_analytics_report():
    """Ежедневный отчёт в Telegram"""
    from datetime import date, timedelta
    yesterday = date.today() - timedelta(days=1)

    # Получаем данные с обеих площадок
    wb_sales = get_wb_sales(yesterday)
    ozon_sales = get_ozon_sales(yesterday)

    total_revenue = wb_sales['revenue'] + ozon_sales['revenue']
    total_orders = wb_sales['orders'] + ozon_sales['orders']

    report = f"""
📊 *Отчёт за {yesterday.strftime('%d.%m.%Y')}*

💰 Выручка: {total_revenue:,.0f} ₽
📦 Заказов: {total_orders}

🛍 Wildberries:
  • Выручка: {wb_sales['revenue']:,.0f} ₽
  • Заказов: {wb_sales['orders']}
  • Возвраты: {wb_sales['returns']}

🔵 Ozon:
  • Выручка: {ozon_sales['revenue']:,.0f} ₽
  • Заказов: {ozon_sales['orders']}
  • Отмены: {ozon_sales['cancels']}
"""
    send_telegram(report)

8. Архитектура системы

Рекомендуемая архитектура для автоматизации маркетплейсов:

  • VPS-сервер — Ubuntu, 2 CPU, 4 GB RAM (~1 000 ₽/мес)
  • PostgreSQL — хранение заказов, остатков, истории цен
  • Cron-задачи — синхронизация остатков каждые 15 мин, заказы каждые 5 мин
  • Telegram-бот — уведомления и управление
  • Grafana — дашборд с аналитикой продаж
Важно: WB и Ozon периодически меняют API. Подписывайтесь на их developer-рассылки и следите за changelog. Критические изменения обычно объявляются за 1–2 месяца.

Нужна автоматизация маркетплейсов под ключ?

Настраиваем интеграцию с WB, Ozon и Яндекс Маркет: остатки, цены, заказы, отзывы. От 40 000 ₽, срок 2–3 недели.

Получить оценку