Тип карточки через API

В POST /api/products и PUT /api/products можно передать of_type: 1 — обычный, 2 — составной, 3 — компонент, 4 — расходник, 5 — упаковка. Запрос — массив карточек. Тип 2 создаёт карточку без состава; составы существующих наборов эта операция не меняет.

[{"of_shop_id":12,"of_name":"Крем 100 мл","of_type":3}]

Для изменения только типа: [{"of_id":1201,"of_type":3}] либо ключи of_ext_id + of_shop_id. Поля имени и цены при обновлении необязательны. Отсутствующий тип сохраняет прежнее поведение; null, пустая строка, дробь или неизвестный код вызывают ошибку.

Нужны право создания/изменения товара, доступ к магазину и право работы с составом для типов 2/3; функция составных товаров должна быть включена. Связи состава, кванты и зависимые складские документы могут запрещать смену типа (422); отсутствие прав — 403. Старые запросы без типа не изменяются.

Успех возвращает массив {"data":{"of_id":1201,"of_type":3,...}}; GET /api/products/1201 позволяет независимо проверить сохранённый тип. Цена набора независима от цен компонентов.

Каждая карточка применяется отдельно. Если последующий элемент не прошёл проверку бизнес-правил, предыдущие могут быть уже записаны. Перед повтором ошибочного пакета прочитайте результаты. Для массового создания новых наборов с составом используйте отдельный импорт в ЛК; он не обновляет старые наборы.

API V1 Legacy
Эта страница относится только к старому совместимому контракту /api/*. Новый API v2 находится в отдельной ветке сайта.

Товары

API каталога rw_offers. Поддерживаются bulk create/update, описание товара, кванты/упаковки и синхронизация штрихкодов.

GET/api/products

Постраничный список товаров. Нужен доступ offers.view.

Фильтры exact/inof_id, of_sku, of_ext_id, of_shop_id, of_status, of_type, of_package_kind, of_parent_offer_id, of_base_offer_id, of_datamatrix, of_expiration_required, of_price, of_estimated_price. Можно передавать одиночное значение или массив.
Изменения остатковinventoryUpdated_from, inventoryUpdated_to. Timestamp обновляется у товара и связанных родителей/базовых товаров при движениях по квантам.
LIKEof_name, of_article, of_comment, одиночное значение или массив фрагментов.
Сортировкаsort_by, sort_dir=asc|desc.
Пагинацияper_page, максимум 250.
GET /api/products?of_shop_id[]=12&of_status[]=1&of_package_kind=quant&inventoryUpdated_from=2026-07-05%2010:00:00&sort_by=of_id&sort_dir=desc&per_page=20
POST/api/products

Bulk создание товаров. Payload: JSON-массив. Нужен доступ offers.create.

[
  {
    "of_shop_id": 12,
    "of_name": "Cotton T-shirt",
    "of_ext_id": "EXT-1001",
    "of_article": "ART-01",
    "of_sku": "SKU-01",
    "of_price": 19.99,
    "of_estimated_price": 21.50,
    "of_img": "https://cdn.site/img.jpg",
    "of_dimensions": {
      "x": 105,
      "y": 200,
      "z": 32
    },
    "of_weight": 250,
    "of_datamatrix": 0,
    "of_expiration_required": 0,
    "of_comment": "Some note",
    "of_description": "Basic cotton T-shirt",
    "package": {
      "kind": "quant",
      "parent_offer_id": 77,
      "multiplicity": 5
    },
    "barcodes": [
      {"br_barcode": "4601234567890", "br_main": 1},
      {"br_barcode": "4601234567891", "br_main": 0}
    ]
  }
]

Если barcodes передан и не пустой, ровно один штрихкод должен иметь br_main=1. Штрихкод уникален в рамках магазина.

of_expiration_required=1 помечает товар как требующий сроки годности/дату производства/партию на складах, где режим сроков включен только для отмеченных товаров.

package.kind=quant создает товар-квант. parent_offer_id указывает непосредственного родителя, multiplicity - сколько родительских единиц содержит один квант.

PUT/api/products

Bulk обновление товаров. Нужен доступ offers.update.

ИдентификацияКаждая строка должна содержать of_id или пару of_ext_id + of_shop_id.
barcodesЕсли передан массив barcodes, список штрихкодов товара заменяется полностью.
of_descriptionЕсли поле передано, описание обновляется. Пустая строка удаляет описание.
packagepackage.kind=quant обновляет параметры кванта; package.kind=base очищает упаковочные поля товара.
[
  {
    "of_id": 10,
    "of_name": "Updated name",
    "of_expiration_required": 1,
    "of_description": "Updated long description",
    "package": {
      "kind": "quant",
      "parent_offer_id": 77,
      "multiplicity": 10
    },
    "barcodes": [
      {"br_barcode": "4601234567890", "br_main": 1}
    ]
  }
]
GET/api/products/{id}

Один товар с описанием, штрихкодами, упаковочными полями и остатками. Нужен offers.view. В ответе есть package, physical_stocks, aggregate_stocks и inventoryUpdated.

DELETE/api/products/{id}

Удаляет товар, если по нему нет движений в whc_wh_items. Нужен offers.delete, legacy delete также разрешен admin/warehouse_manager.

{
  "message": "Deleted"
}
GET/api/products/offer

OrderAdmin-compatible список товаров. Формат ответа приближен к OA: _links, _embedded.product_offer, page_count, total_items.

Пагинацияpage, per_page максимум 250.
Фильтрыfilter[n][field]=shop|state, filter[n][type]=eq|neq, filter[n][value].
Сортировкаorder-by[n][field]=created|updated|name, direction=asc|desc.
GET /api/products/offer?filter[0][type]=eq&filter[0][field]=shop&filter[0][value]=206279&order-by[0][type]=field&order-by[0][field]=created&order-by[0][direction]=desc