И так, поступила задача настроить обновление цены на Wildberries таким образом, чтобы после всех скидок, цена не была ниже РРЦ. Понижение цены ниже РРЦ, происходит из-за того, что Wildberries применяет свою скидку, которая периодически изменяется и следовательно, меняется финальная стоимость товара на площадке.
Решил использовать API для получения необходимой информации по скидкам и обновления цены, но был несколько удивлен тем, что API Wildberries не отдаёт никакой информации о скидке WB, но ещё больше был удивлён, что эту информацию он отдаёт без какого-либо API и без необходимости парсить фронт.
В общем, чтобы долго не мусолить тему, предлагаю готовое решение на PHP, которое работает с Google Sheets. Для того, чтобы всё работала, ваша табличка должна иметь 2 столбца: Артикул WB и Финальная цена. Важно, чтобы они назывались именно так (ну или поправьте в коде на то, как вам нужно). Таблицу Google необходимо опубликовать в Интернете в формате CSV (только нужный лист). После запуска скрипта, цена на Wildberries с учетом всех скидок, будет той, что указана в вашей табличке в столбце "Окончательная цена".
![](https://fixcode.ru/app/uploads/2023/08/image-1024x456.png)
В самом скрипте, необходимо будет указать API-ключ WB и ссылку на опубликованную таблицу в формате CSV ну или любой другой URL на CSV файл с нужными нам столбцами. Цена будет обновляться только при условии, что цена в файле и цена в WB отличаются. Обновление цен в WB занимает некоторое время, после запуска скрипта, необходимо будут подождать 1-3 минуту для того, чтобы изменения отобразились в вашей карточке товара.
<?php
require 'vendor/autoload.php';
use League\Csv\Reader;
// Указываем токен WB (API ключ)
$token = '';
// Указываем URL для загрузки CSV файла
$csvUrl = '';
// Функция для чтения данных из CSV файла по URL и преобразования в массив
function readCsvFromUrl($url)
{
// Получаем содержимое CSV файла по URL как строку
$csvString = file_get_contents($url);
// Создаем объект-читатель для данных CSV из строки
$reader = Reader::createFromString($csvString);
$reader->setHeaderOffset(0); // Устанавливаем номер строки с заголовками
// Получаем все данные из CSV файла и преобразуем их в массив
$dataArray = iterator_to_array($reader->getRecords());
return $dataArray;
}
// Получаем массив данных из CSV файла по URL
$dataArray = readCsvFromUrl($csvUrl);
//Делаем массив артикулов из файла
$skuArray = [];
foreach ($dataArray as $data) {
$skuArray[] = $data['Артикул WB'];
}
//Переводим массив артикулов в строку и разделяем запятой.
$skuString = implode(';', $skuArray);
//Теперь делаем наш запрос для получения информации о товарах из прайс-листа.
//На данный момент используем view-source: https://card.wb.ru/cards/detail?appType=2&curr=rub&dest=123585969®ions=80,38,83,4,64,33,68,70,30,40,86,69,22,1,31,66,110,48,114&spp=29&nm=12478322
$parametrs_get = array(
'appType' => '2',
'curr' => 'rub',
'dest' => '123585969',
'regions' => '80,38,83,4,64,33,68,70,30,40,86,69,22,1,31,66,110,48,114',
'spp' => '99',
'nm' => $skuString
);
//Получаем ответ сервера с массивом всех данных о товарах
$response = curlRequest('https://card.wb.ru/cards/detail', 'GET', $parametrs_get);
//Готовый объем со всеми необходимыми данным для дальнейшей обработки
$response_encode = json_decode($response);
echo 'Получено товаров: '.count($response_encode->data->products)."\n";
//Теперь собственно нужно сравнить то, что в файле и то, что на WB.
//Если будут расхождения, будем запускать обновление цены на WB.
$parametrs_post = [];
foreach ($dataArray as $dataCSV) {
foreach ($response_encode->data->products as $dataWb) {
if ($dataCSV['Артикул WB'] == $dataWb->id) {
//Преоборазуем цену на WB в нормальный вид
$price_wb = $dataWb->salePriceU / 100;
if ($dataCSV['Финальная цена'] != $price_wb) {
$price = ceil(($dataCSV['Финальная цена'] / (1 - 0.01 * $dataWb->params->spp))) / (1 - 0.01 * $dataWb->sale);
$parametrs_post[] = array(
'nmId' => intval($dataWb->id),
'price' => ceil($price),
);
}
}
}
}
echo 'Будет обновлено товаров: '.count($parametrs_post)."\n";
if (count($parametrs_post) > 0) {
//Отправляем запрос на обновление цены
$update_price = curlRequest('https://suppliers-api.wildberries.ru/public/api/v1/prices', 'POST', $parametrs_post);
//Готовый объем со всеми необходимыми данным для дальнейшей обработки
$response_update = json_decode($update_price);
echo 'Отправили запрос на обновление остатков';
} else {
echo 'Нет товаров для обновления';
}
//Функция выполнения запросов GET/POST
function curlRequest($url, $method, $data = array())
{
$ch = curl_init();
if ($method === 'GET' && !empty($data)) {
$url .= '?' . http_build_query($data);
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if ($method === 'POST') {
global $token;
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization:' . $token,
'Content-Type:application/json'
));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
}
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Ошибка cURL: ' . curl_error($ch);
}
curl_close($ch);
return $response;
}
Для установки необходимых зависимостей, используйте команду:
composer require league/csv:^9.0
Вылетает ошибка, при 100 строках, с меньшим количеством строк работает
Warning: count(): Parameter must be an array or an object that implements Countable in /m_inst/autoload.php on line 60
Получено товаров: 0
Warning: Invalid argument supplied for foreach() in /m_inst/autoload.php on line 68