ПрайсЛинк
Документация REST API v1

Инструкция по API-подключению

Полная техническая спецификация для интеграции самописных CMS, ERP-систем (1С, МойСклад) и кастомных интернет-магазинов с платформой ПрайсЛинк. Три эндпоинта реализуются на стороне вашего сайта — ПрайсЛинк обращается к ним сам, по расписанию и по кнопке в кабинете.

Base URL: https://ваш-сайт/api/pricelink/ Format: JSON / UTF-8 Auth: Bearer API Token
Быстрый старт

Как подключиться к API за 3 шага

1

Придумайте API-ключ

Сгенерируйте на своей стороне случайную строку (32+ символа) и положите её в конфиг сайта. Тот же ключ впишите в кабинете: Магазины → Настройки → «API-ключ коннектора».

2

Проверяйте Header

Каждый запрос приходит с Authorization: Bearer KEY. Сверяйте ключ через hash_equals и отвечайте 401, если он не совпал.

3

Нажмите «Проверить связь»

В настройках магазина выберите платформу «Своя CMS / REST API», укажите адрес сайта и ключ, проверьте связь и загрузите каталог.

GET /api/pricelink/ping
Проверка связи

Отвечает на кнопку «Проверить связь» в кабинете. Нужен, чтобы неверный адрес или ключ обнаружились сразу, а не на середине загрузки каталога.

Пример ответа сервера (200 OK):

{
  "status": "ok",
  "shop": "alfira.by",
  "platform": "laravel",
  "products_total": 1658
}
GET /api/pricelink/products
Экспорт каталога товаров

Постраничная выгрузка каталога: параметры page и limit (до 1000). Сортировка обязательно устойчивая, по id — страницы забираются отдельными запросами, и при «плавающем» порядке часть товаров попадёт в выгрузку дважды, а часть ни разу. categories — путь от корня к листу, по нему ПрайсЛинк строит то же дерево разделов, что и витрина.

Пример ответа сервера (200 OK):

{
  "data": [
    {
      "product_id": 5,
      "name": "Кондиционер TCL GentleCool (25 кв.м.)",
      "model": "TAC-09CHSD/TPG11IHB",
      "sku": null,
      "manufacturer": "TCL",
      "categories": ["Кондиционеры", "Кондиционеры для дома и офиса"],
      "price": 2180.00,
      "special_price": null,
      "quantity": 1,
      "stock_status_id": 1,
      "status": true,
      "image": "https://alfira.by/images/uploads/5fca270b.webp",
      "url": "https://alfira.by/product/konditsioner-tcl-gentlecool-25-kvm",
      "date_modified": "2026-09-01 09:35:42"
    }
  ],
  "pagination": { "page": 1, "limit": 500, "total": 1658 }
}

Обязательны только product_id и name. Остальное можно отдавать null — но чем больше заполнено model, sku и manufacturer, тем точнее автоматическое сопоставление с прайсами.

POST /api/pricelink/update
Пакетное обновление цен

Принимает рассчитанные розничные цены и остатки. Позиции адресуются тем же product_id, который вы отдали в выгрузке. Сам по себе ПрайсЛинк ничего не меняет: запрос уходит только после того, как владелец магазина подтвердил изменения в кабинете.

Тело запроса (Request Body):

{
  "items": [
    { "product_id": 5,  "price": 2219.90, "quantity": 1 },
    { "product_id": 88, "price": 450.00,  "quantity": 0 }
  ]
}

Ожидаемый ответ (200 OK):

{
  "updated": 1,
  "errors": [
    { "product_id": 88, "message": "not_found" }
  ]
}

Отвечайте 200 и с ошибками внутри: массив errors показывается в кабинете по каждой позиции, а весь запрос из-за одного битого id падать не должен. Поле quantity можно игнорировать, если у вас не числовой остаток, а статус наличия.

Пример реализации на PHP (Laravel)

PHP 8.x
<?php
// routes/api.php
Route::middleware(PriceLinkToken::class)->prefix('pricelink')->group(function () {
    Route::get('ping',     [PriceLinkController::class, 'ping']);
    Route::get('products', [PriceLinkController::class, 'products']);
    Route::post('update',  [PriceLinkController::class, 'update']);
});

// app/Http/Middleware/PriceLinkToken.php — сверка ключа
$expected = (string) config('services.pricelink.token');
$provided = (string) str($request->header('Authorization'))->after('Bearer ')->trim();

if ($expected === '' || $provided === '' || ! hash_equals($expected, $provided)) {
    return response()->json(['error' => 'unauthorized'], 401);
}

// app/Http/Controllers/Api/PriceLinkController.php — приём цен
foreach ((array) $request->input('items') as $item) {
    $product = Product::find((int) ($item['product_id'] ?? 0));

    if (! $product) {
        $errors[] = ['product_id' => $item['product_id'] ?? null, 'message' => 'not_found'];
        continue;
    }

    $product->forceFill(['price' => round((float) $item['price'], 2)])->save();
    $updated++;
}

return response()->json(['updated' => $updated, 'errors' => $errors]);

Три вещи, на которых спотыкаются

  • Заголовок Authorization до PHP не доходит. На Apache с CGI/FastCGI его срезает — нужна строка RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] в .htaccess. Симптом: всё отдаёт 401 при верном ключе.
  • Адрес со слешем на конце или в верхнем регистре. Если сайт канонизирует адреса редиректом, POST после 301 теряет тело запроса, и обновление молча уходит в пустоту.
  • Кэш каталога. Если цены закэшированы (фильтры, карта сайта, витрина), сбросьте кэш после записи — иначе новая цена появится на сайте с задержкой в часы.

Нужна помощь с интеграцией API?

Наши технические специалисты помогут настроить интеграцию под вашу кастомную CMS или 1С бесплатно в рамках первого месяца.