Integration of Online Store with Wildberries (API)
Wildberries is the largest Russian marketplace. API is poorly documented and frequently changes without notice. Integration requires continuous monitoring of changes.
Authentication
Wildberries uses API tokens issued in the seller's personal cabinet:
class WildberriesClient
{
private string $apiToken;
private string $statsToken; // separate token for statistics
public function request(string $method, string $url, array $data = []): array
{
return Http::withHeaders([
'Authorization' => $this->apiToken,
'Content-Type' => 'application/json',
])->{strtolower($method)}($url, $data)->json();
}
}
Product Upload
WB works through product cards — a specific structure with subjects and characteristics:
public function createCard(Product $product): void
{
$payload = [[
'subjectID' => $this->getSubjectId($product->category),
'variants' => [[
'vendorCode' => $product->sku,
'title' => $product->name,
'description'=> $product->description,
'brand' => $product->brand,
'dimensions' => [
'length' => $product->length_cm,
'width' => $product->width_cm,
'height' => $product->height_cm,
'isValid'=> true,
],
'characteristics' => $this->mapCharacteristics($product),
]],
]];
$this->request('POST', 'https://content-api.wildberries.ru/content/v2/cards/upload', $payload);
}
Updating Prices and Discounts
WB separates base price and discount:
public function setPriceAndDiscount(string $sku, int $basePrice, int $discountPercent): void
{
// Setting base price
$this->request('POST', 'https://discounts-prices-api.wildberries.ru/api/v2/upload/task', [
'data' => [[
'nmID' => $this->getNmId($sku),
'price' => $basePrice,
]]
]);
// Setting discount
$this->request('POST', 'https://discounts-prices-api.wildberries.ru/api/v2/upload/task', [
'data' => [[
'nm' => $this->getNmId($sku),
'discount' => $discountPercent,
]]
]);
}
Stock Updates (FBS)
public function updateStocks(array $items): void
{
// items: [['sku' => 'SKU-123', 'amount' => 10]]
$this->request('PUT', 'https://marketplace-api.wildberries.ru/api/v3/stocks/{warehouseId}', [
'stocks' => array_map(fn($item) => [
'sku' => $item['sku'],
'amount' => $item['amount'],
], $items)
]);
}
Getting FBS Orders
public function getOrders(string $since): array
{
return $this->request('GET', 'https://marketplace-api.wildberries.ru/api/v3/orders', [
'limit' => 1000,
'next' => 0,
'dateFrom' => strtotime($since),
])['orders'] ?? [];
}
Typical Challenges
- Unstable documentation: methods change, URLs become outdated
-
Different domains for different APIs:
content-api,discounts-prices-api,marketplace-api,statistics-api— each with its own base URL and sometimes own authorization -
NmID vs vendorCode: WB uses an internal numeric identifier
nmID, which needs to be matched with yoursku/vendorCode - Order statuses change unpredictably, polling is needed
Timeline
Integration with WB (products + prices + stock + orders): 14–20 business days considering the unstable API.







