Обновление цен на Wildberries с учётом скидки WB

Комментариев: 1

И так, поступила задача настроить обновление цены на Wildberries таким образом, чтобы после всех скидок, цена не была ниже РРЦ. Понижение цены ниже РРЦ, происходит из-за того, что Wildberries применяет свою скидку, которая периодически изменяется и следовательно, меняется финальная стоимость товара на площадке.

Решил использовать API для получения необходимой информации по скидкам и обновления цены, но был несколько удивлен тем, что API Wildberries не отдаёт никакой информации о скидке WB, но ещё больше был удивлён, что эту информацию он отдаёт без какого-либо API и без необходимости парсить фронт.

В общем, чтобы долго не мусолить тему, предлагаю готовое решение на PHP, которое работает с Google Sheets. Для того, чтобы всё работала, ваша табличка должна иметь 2 столбца: Артикул WB и Финальная цена. Важно, чтобы они назывались именно так (ну или поправьте в коде на то, как вам нужно). Таблицу Google необходимо опубликовать в Интернете в формате CSV (только нужный лист). После запуска скрипта, цена на Wildberries с учетом всех скидок, будет той, что указана в вашей табличке в столбце "Окончательная цена".


В самом скрипте, необходимо будет указать 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&regions=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
Уведомлять о новых комментариях
Уведомлять
guest
1 Комментарий
Inline Feedbacks
View all comments
Даниил
Даниил
2 месяцев назад

Вылетает ошибка, при 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