# REST API — методы и примеры (richcode.api) Полный справочник действий модуля `richcode.api` и примеры запросов. Составлено по исходникам контроллеров (`bitrix/modules/richcode.api/lib/*/controllers/*.php`) и ядра модуля (`lib/core/`). Обзор и настройки — в [[REST API (richcode.api)]]. ## Содержание - URL-схема - Авторизация и фильтры - Формат ответа - Справочник действий (по контроллерам) - Примеры запросов - Точные схемы (проверено по моделям) ## URL-схема ``` /{apiPath}/{module}/{token}/{controller}/{action} ``` - `apiPath` — базовый путь, по умолчанию `api` (модуль срабатывает, если первый сегмент URL равен ему — из `Init::checkPathApi`). - `module` / `controller` — из карты в `lib/core/Init.php`: `iblock/element`, `sale/product|order|store|discount|measure`, `main/user`, `crm/deal`. - `token` — сегмент URL с токеном (если включена авторизация). - `action` — **оставшиеся сегменты пути после контроллера, склеенные точкой**. Поэтому `.../element/section/add` → действие `section.add`, `.../order/status/set` → `status.set`. - Параметры: для GET — query-строка; для POST/PUT/DELETE — тело JSON (`Content-Type: application/json`) или form-data. ## Авторизация и фильтры Проверки идут по порядку (`Init::checkFilters`): **токен → только HTTPS → IP-список → группа пользователя**. Любая непройденная — ответ `403`. - Токен берётся из **сегмента URL** и ищется в поле пользователя **`UF_API_TOKEN`** (`Tokens::checkToken`). Запрос выполняется **от имени этого пользователя** — его правами и ограничен. - Пользователь-владелец токена должен состоять в группе, заданной в настройках модуля (`Config::getGroupId()`). - Формат токена: `xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx` (например `b2b23c2b-8df82f85-256913d3-ff261962`), генерируется в настройках модуля. > [!warning] Расхождения, которые собьют с толку > - В подсказке настроек модуля поле названо `UF_RESTFUL_API_TOKEN`, но в коде используется **`UF_API_TOKEN`**. Верно то, что в коде. > - Та же подсказка предлагает передавать токен заголовком `Authorization-Token`, но рабочий код (`Route`+`Init`) читает токен **из сегмента URL**, а не из заголовка. Заголовок лишь разрешён в CORS. Используйте токен в URL. > - Токен в URL попадёт в логи веб-сервера и в собственный лог модуля (HL-блок). Это чувствительно — см. [[Информационная безопасность (apelsincom)]]. ## Формат ответа Всегда JSON `{"status", "result"}` (из `lib/core/Response.php`): - Успех — HTTP 200: `{"status":200,"result": <данные>}`. - Бизнес-ошибка — HTTP 400: `{"status":400,"result":{"type":"error","message":"..."}}`. - Отказ фильтра (нет токена / не HTTPS / чужой IP / не та группа) — HTTP 403: `{"status":403,"result":{"type":"error","message":"Forgbiden"}}` (опечатка в исходнике сохранена как есть). ## Справочник действий ### iblock / element (и sale / product — те же действия, но по товарам каталога) | Действие (URL) | Параметры | Что делает | |---|---|---| | `add` | поля элемента | создать элемент, вернуть ID | | `update` | `ID` + поля | обновить элемент | | `delete` | `ID` | удалить | | `get` | `ID` | элемент по ID | | `list` | фильтр/выборка | список элементов | | `fields` | — | доступные поля элемента | | `property.list` | (`IBLOCK_ID`) | список свойств инфоблока | | `property.get` | `ID` | свойство по ID | | `property.enumeration.fields` | параметры свойства | значения списочного свойства | | `property.add` / `property.update` | поля свойства | создать/изменить свойство | | `property.enumeration.add` / `.update` | поля | значения списочного свойства | | `property.add.group` / `property.update.group` / `property.enumeration.add.group` / `property.enumeration.update.group` | `fields[]` | групповые операции | | `section.add` / `section.update` | поля раздела | создать/изменить раздел | | `section.update.group` | `fields[]` | групповое изменение разделов | | `section.list` | фильтр | список разделов | | `section.get` | `ID` | раздел по ID | | `section.property.list` | `IBLOCK_ID` | свойства раздела | | `section.property.enumeration.fields` | — | значения свойств раздела | | `update.group` | `fields[]` | групповое обновление элементов | | `file.add` | файл | добавить файл | | `measure.ratio.update` | параметры | коэффициент единицы измерения | | `store.amount.get` / `store.amount.set` | параметры остатков | остатки товара по складам | ### sale / order | Действие | Параметры | Что делает | |---|---|---| | `create` | поля заказа | создать заказ, вернуть ID | | `get` | `ORDER_ID` | заказ по ID | | `list` | фильтр | список заказов | | `fields` | — | поля заказа | | `basket` | `ORDER_ID` | состав корзины заказа | | `status.list` | — | список статусов заказа | | `status.set` | `ORDER_ID`, `STATUS_ID` | сменить статус | | `cancel` / `uncancel` | `ORDER_ID` | отмена / снятие отмены | | `payed` / `unpayed` | `ORDER_ID` | отметить оплаченным / нет | | `delivery.status.list` | — | статусы доставки | | `delivery.status.set` | `ORDER_ID`, `STATUS_ID` | статус доставки | | `delivery.accept` / `delivery.decline` | `ORDER_ID` | принять / отклонить доставку | | `shipment.accept` / `shipment.decline` | `ORDER_ID` | отгрузка | | `payer.list` | — | типы плательщиков | | `property.list` / `property.enum` | — | свойства заказа | | `payment.list` / `delivery.list` | — | доступные оплаты / доставки | ### sale / store | Действие | Параметры | Что делает | |---|---|---| | `add` | `fields` | создать склад | | `update` | `fields` | изменить склад | | `set.amount` | `PRODUCT_ID`, `STORE_ID`, кол-во | задать остаток | | `set.amount.group` | `fields[]` | групповые остатки | | `list` | — | список складов | ### sale / measure, sale / discount, main / user, crm / deal | Контроллер | Действия | |---|---| | `sale/measure` | `add`, `update` (`fields.ID`), `delete` (`ID`), `list` | | `sale/discount` | `add`, `update`, `delete` (`ID`), `list` | | `main/user` | `list`, `add`, `update`, `delete` (`ID`), `fields` | | `crm/deal` | `productrows.set` (задать товарные позиции сделки) | ## Примеры запросов Ниже `https://<домен>` = адрес сайта, `` = токен из `UF_API_TOKEN`, `apiPath` = `api`. Reads — через GET, writes — через POST (роутер разбирает параметры и там, и там; метод влияет только на способ передачи данных). > [!warning] Каталог vs обычный инфоблок — разные контроллеры > Проверено по моделям: **`iblock/element` работает только с НЕ-каталожными инфоблоками**, а для товаров и разделов **каталога (инфоблок 2) нужен `sale/product`** (те же действия). Перепутаете — получите ошибку «Инфоблок с указанным ID не найден». Поэтому примеры для каталога ниже — на `sale/product`. И у `add`/`update`/`section.*` тело обёрнуто в ключ **`fields`** (у `order/create` — нет). Полные схемы — в разделе «Точные схемы». **Доступные поля элемента:** ```bash curl "https://<домен>/api/iblock//element/fields" ``` **Получить товар каталога по ID:** ```bash curl "https://<домен>/api/sale//product/get?ID=123" # → {"status":200,"result":{ ...поля товара... }} ``` **Список товаров каталога:** ```bash curl "https://<домен>/api/sale//product/list?filter[IBLOCK_ID]=2" ``` **Создать товар каталога (инфоблок 2):** ```bash curl -X POST "https://<домен>/api/sale//product/add" \ -H "Content-Type: application/json" \ -d '{"fields":{ "IBLOCK_ID": 2, "NAME": "Кроссовки Модель X", "CODE": "krossovki-model-x", "ACTIVE": "Y", "PRICE": 4990, "CURRENCY": "RUB", "QUANTITY": 10, "PROPERTY_ARTNUMBER": "ART-001" }}' # → {"status":200,"result": <новый ID>} ``` **Создать элемент обычного (не каталог) инфоблока:** ```bash curl -X POST "https://<домен>/api/iblock//element/add" \ -H "Content-Type: application/json" \ -d '{"fields":{"IBLOCK_ID":5,"NAME":"Новость","CODE":"novost","ACTIVE":"Y","PROPERTY_AUTHOR":"Редакция"}}' ``` **Обновить товар:** ```bash curl -X POST "https://<домен>/api/sale//product/update" \ -H "Content-Type: application/json" \ -d '{"fields":{"ID": 123, "NAME": "Новое название", "PRICE": 5490}}' ``` **Удалить товар:** ```bash curl -X POST "https://<домен>/api/sale//product/delete" \ -H "Content-Type: application/json" -d '{"ID": 123}' ``` **Разделы каталога:** ```bash # список разделов curl "https://<домен>/api/sale//product/section/list?filter[IBLOCK_ID]=2" # создать раздел curl -X POST "https://<домен>/api/sale//product/section/add" \ -H "Content-Type: application/json" \ -d '{"fields":{"IBLOCK_ID":2,"NAME":"Мужская обувь","CODE":"muzhskaya-obuv","ACTIVE":"Y"}}' ``` **Остатки на складе:** ```bash curl -X POST "https://<домен>/api/sale//store/set/amount" \ -H "Content-Type: application/json" \ -d '{"PRODUCT_ID":123,"STORE_ID":1,"AMOUNT":10}' ``` **Заказы:** ```bash # получить заказ curl "https://<домен>/api/sale//order/get?ORDER_ID=1001" # список заказов curl "https://<домен>/api/sale//order/list" # создать заказ (полная схема — в разделе «Точные схемы») curl -X POST "https://<домен>/api/sale//order/create" \ -H "Content-Type: application/json" \ -d '{"PERSON_TYPE_ID":1,"DELIVERY_ID":1,"PAYSYSTEM_ID":1, "ITEMS":[{"PRODUCT_ID":412,"QUANTITY":1}], "PROPERTIES":[{"ID":1,"VALUE":"Иван"}]}' # сменить статус curl -X POST "https://<домен>/api/sale//order/status/set" \ -H "Content-Type: application/json" -d '{"ORDER_ID":1001,"STATUS_ID":"F"}' # отметить оплаченным curl -X POST "https://<домен>/api/sale//order/payed" \ -H "Content-Type: application/json" -d '{"ORDER_ID":1001}' ``` **Пользователь:** ```bash curl -X POST "https://<домен>/api/main//user/add" \ -H "Content-Type: application/json" -d '{ ...поля пользователя... }' ``` ## Точные схемы (проверено по моделям) Схемы ниже сверены по коду моделей (`lib/…/models/…`), а не по догадкам. ### Правило: каталог vs обычный инфоблок - `iblock/element/*` — только **не-каталожные** инфоблоки (`add`, `list`, `get`, `section.*` внутренне исключают каталоги). - `sale/product/*` — только **каталог** (инфоблок 2); те же действия, но модель работает с ценой, остатком и товарными полями. - У `add` / `update` / `section.add` / `section.update` тело обёрнуто в ключ **`fields`** (плоская карта). Свойства элемента — с префиксом `PROPERTY_<КОД>`, поля раздела — `UF_<КОД>`. ### element/add — элемент обычного инфоблока `POST /api/iblock//element/add` ```json { "fields": { "IBLOCK_ID": 5, "NAME": "Заголовок", "CODE": "zagolovok", "ACTIVE": "Y", "SORT": 100, "PREVIEW_TEXT": "…", "DETAIL_TEXT": "…", "IBLOCK_SECTION_ID": 12, "PROPERTY_AUTHOR": "Редакция" } } ``` Стандартные поля (`getAvailableElementFields`): `ID, IBLOCK_ID, IBLOCK_SECTION_ID, ACTIVE, XML_ID, DATE_ACTIVE_FROM, DATE_ACTIVE_TO, SORT, NAME, PREVIEW_PICTURE, PREVIEW_TEXT, DETAIL_PICTURE, DETAIL_TEXT, CODE`. Если `CODE` пуст, а в инфоблоке включён транслит — сгенерируется из `NAME`. Возвращает ID нового элемента. Каталог (ИБ 2) метод отклонит. ### sale/product/add — товар каталога (инфоблок 2) `POST /api/sale//product/add` ```json { "fields": { "IBLOCK_ID": 2, "NAME": "Кроссовки Модель X", "CODE": "krossovki-model-x", "ACTIVE": "Y", "IBLOCK_SECTION_ID": 15, "PRICE": 4990, "CURRENCY": "RUB", "QUANTITY": 10, "VAT_ID": 1, "VAT_INCLUDED": "Y", "MEASURE": 5, "WEIGHT": 800, "PROPERTY_ARTNUMBER": "ART-001", "PROPERTY_MANUFACTURER": "Производитель" } } ``` Помимо полей элемента поддерживаются товарные (`Product::getAvailableElementFields`): `PRICE, CURRENCY, QUANTITY, QUANTITY_RESERVED, VAT_ID, VAT_INCLUDED, MEASURE, EXTERNAL_ID, PURCHASING_PRICE, PURCHASING_CURRENCY, WIDTH, HEIGHT, LENGTH, WEIGHT`. Метод сам заводит товар в торговом каталоге и ставит базовую цену. Требует именно каталог. ### section.add — раздел `POST /api/sale//product/section/add` (каталог) или `/api/iblock//element/section/add` (обычный ИБ) ```json { "fields": { "IBLOCK_ID": 2, "NAME": "Мужская обувь", "CODE": "muzhskaya-obuv", "SORT": 100, "ACTIVE": "Y", "IBLOCK_SECTION_ID": 0, "UF_SHOW_IN_MENU": 1 } } ``` Поля раздела: `ID, IBLOCK_SECTION_ID, IBLOCK_ID, NAME, CODE, SORT, ACTIVE` + пользовательские `UF_*` (например `UF_SHOW_IN_MENU`, см. [[Инфоблоки и каталог (apelsincom)]]). ### order/create — заказ `POST /api/sale//order/create` (**без** обёртки `fields`). Заказ создаётся на пользователя токена. ```json { "PERSON_TYPE_ID": 1, "DELIVERY_ID": 1, "PAYSYSTEM_ID": 1, "ITEMS": [ { "PRODUCT_ID": 412, "QUANTITY": 1 }, { "PRODUCT_ID": 413, "QUANTITY": 4 } ], "PROPERTIES": [ { "ID": 1, "VALUE": "Иван" }, { "ID": 5, "VALUE": ["Опция А", "Опция Б"] } ] } ``` - `ITEMS[].PRODUCT_ID` — ID товара/предложения каталога, `QUANTITY` — количество. Корзина строится через провайдер `catalog`, валюта — базовая. - `PROPERTIES[].ID` — ID свойства заказа (значения списков — из `order/property.list`), `VALUE` может быть массивом для множественных. - `DELIVERY_ID` / `PAYSYSTEM_ID` — из `order/delivery.list` и `order/payment.list`; `PERSON_TYPE_ID` — из `order/payer.list`. - Возвращает ID созданного заказа; при ошибке — 400 с текстом от `sale`. ### Остальные схемы — сверять в моделях Для `store/set.amount`, `user/add`, `measure/*`, `discount/*` и свойств (`property.*`) точный формат — в `lib/sale/models/Store.php`, `Product/DmlStore.php`, `lib/main/models/User.php`, `lib/iblock/models/Element/DmlProperty.php`. Быстро узнать поля вживую: `…/product/fields`, `…/order/fields`, `…/user/fields`, `…/product/property/list?filter[IBLOCK_ID]=2`. ## См. также - [[REST API (richcode.api)]] - [[Сценарии. Товары и разделы]] - [[Информационная безопасность (apelsincom)]]