Периодически ко мне приходят с одной и той же задачей: нужно, чтобы сайт или внутренняя система сама обновляла цены, остатки и карточки товаров на Wildberries, без ручного захода в личный кабинет каждый день. Разбираю здесь, как я обычно организую такую интеграцию на PHP, чтобы было понятно и тем, кто делает это в первый раз.
Wildberries открыл продавцам довольно приличный REST API, через который можно управлять карточками товаров, ценами, остатками и смотреть статистику по продажам. Работает всё по HTTP, ответы приходят в JSON, так что для PHP это стандартная история с curl и json_decode. Официальная документация лежит на https://dev.wildberries.ru, но там сухой справочник методов без разжёвывания, поэтому расскажу по-человечески, как я это применяю на практике.
Первое, что нужно сделать, это зайти в личный кабинет продавца, раздел Профиль → Настройки → Доступ к новому API, и сгенерировать токен. Генерирует его только владелец кабинета, это важно, потому что от роли токена зависит, какие методы будут доступны: только чтение или ещё и запись.
Токен потом просто прокидывается в заголовок каждого запроса:
$headers = [ 'Authorization: ' . $token, 'Content-Type: application/json' ];
Никакого OAuth, никаких сессий и обновления токенов раз в час, что приятно, но и накладывает ответственность: токен нужно хранить так же аккуратно, как пароль, и не светить его в публичном коде или логах.
Дальше обычно нужно вытащить список товаров, чтобы понять, с чем вообще предстоит работать. Для этого я обращаюсь к методу получения карточек товаров:
$token = 'ВАШ_ТОКЕН_API';
$payload = [ 'sort' => [ 'cursor' => ['limit' => 100], 'filter' => ['withPhoto' => -1] ]
];
$ch = curl_init('https://content-api.wildberries.ru/content/v2/get/cards/list');
curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: ' . $token, 'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);Лимит в 100 карточек за один запрос — это максимум, который отдаёт API за раз, поэтому если у продавца в каталоге больше ста позиций, придётся пагинировать через курсор, который приходит в ответе. Я обычно сразу оборачиваю это в цикл, чтобы не забыть про пагинацию, когда каталог вырастет.
В ответе на каждую карточку приходит артикул продавца, бренд, название, ссылки на изображения, цвета и, что важнее всего для интеграции, nmID — внутренний артикул товара на Wildberries. Именно по нему потом идёт вся дальнейшая работа с ценами и остатками, так что я всегда сохраняю связку nmID ↔ артикул в своей базе, чтобы не гонять лишние запросы.
Когда список товаров и их nmID уже есть, можно двигаться к обновлению цен. Здесь тоже действует ограничение: за один запрос Wildberries принимает не больше 1000 позиций, и привязка идёт именно по nmID, а не по артикулу продавца, что часто путает на старте.
$prices = [ ['nmId' => 123456789, 'price' => 2990], ['nmId' => 987654321, 'price' => 1590]
];
$ch = curl_init('https://discounts-prices-api.wildberries.ru/api/v2/upload/task');
curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: ' . $token, 'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($prices, JSON_UNESCAPED_UNICODE));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);Момент, на который стоит обратить внимание: цена, которую вы отправляете, не всегда равна той, что видит покупатель, потому что Wildberries может применять свои скидки и акции сверху. Поэтому если цены на сайте и в кабинете расходятся с ожиданиями, сначала проверяю именно этот момент, а не логику самого запроса.
Отдельная и не менее важная часть интеграции — синхронизация остатков, чтобы на маркетплейсе не продавалось то, чего уже нет на складе. Здесь тоже работа идёт по связке склад плюс баркод товара, и я обычно завожу отдельный крон-скрипт, который раз в 15-30 минут подтягивает актуальные остатки из внутренней системы учёта и пушит их в Wildberries. Частота обновления напрямую влияет на количество отмен заказов из-за отсутствия товара, так что здесь лучше не экономить на регулярности синхронизации.
Прямые curl-запросы, как в примерах выше, отлично подходят, чтобы разобраться и протестировать метод руками. Но когда речь идёт о рабочей интеграции для реального магазина, я обычно добавляю очередь запросов с учётом лимитов API, логирование ответов и ошибок, автоматический повтор при сбоях сети и отдельную таблицу сопоставления товаров, чтобы синхронизация с Wildberries не расползалась по всему проекту кусками кода. У нас в студии такие интеграции с маркетплейсами и внешними API мы делаем на регулярной основе, поэтому если нужна не разовая доработка, а полноценное подключение с автоматизацией, обращайтесь, обсудим задачу.
Мы используем файлы cookie для улучшения вашего опыта на нашем сайте. Прочтите наше соглашение о конфиденциальности для получения дополнительной информации.