0 бонусных баллов
0
+7 (341) 279-28-29
Ежедневно с 10:00 до 23:00

Скачайте приложение

Отсканируйте QR-код камерой телефона

Откуда заберёте заказ?
Ничего не найдено
Начните вводить название блюда

Документация API

Публичный каталог · REST API · JSON · версия v1

Получайте товары Royal Rolls для вашего приложения, каталога или помощника: состав, цены, фотографии, КБЖУ, категории и добавки. Опубликованные товары доступны без регистрации и API-ключа.

Базовый адрес · метод GEThttps://royal-rolls.com/wp-json/royal/v1/

Первый запрос

Откройте адрес в браузере или отправьте обычный GET-запрос. Ответ имеет тип application/json. Список товаров — массив объектов; запрос одного товара возвращает один объект.

cURL · один товар из списка
curl 'https://royal-rolls.com/wp-json/royal/v1/products?per_page=1&modifiers=true'

Сокращённый пример ответа. Цены и состав каталога обновляются; значения ниже приведены для иллюстрации.

JSON · часть полей ответа
[
  {
    "id": 3865,
    "slug": "c-kurinoj-grudkoj-s-imbirnoj-zapravkoj",
    "sku": "112224",
    "name": "C куриной грудкой с имбирной заправкой",
    "price": 360,
    "sale_price": null,
    "weight": "163 г",
    "calories": "227",
    "calories100": "139",
    "modifiers": []
  }
]

Адреса запросов

Все адреса относительно базового URL
Метод и путьЧто возвращает
GET /productsОпубликованные товары, по страницам.
GET /products/{id}Один товар с соусами и добавками. Вместо ID можно передать slug.
GET /categoriesКатегории: id, name, slug, parent, count. Включая пустые.
GET /tagsТеги: id, name, slug, parent, count. Включая пустые.

Например: /products/3865. Артикул sku не заменяет ID в этом адресе. У корневой категории parent = 0; поле count считает товары непосредственно в категории, без суммирования дочерних разделов.

Фильтры списка

Параметры GET /products
ПараметрЗначениеПо умолчанию
pageНомер страницы, начиная с 1.1
per_pageТоваров на странице, максимум 100.50
searchТекст для поиска по названию и описанию.Без поиска
categoryID или slug категории, например rolly.Все категории
tagID или slug тега, например losos.Все теги
modifierstrue включает группы соусов и добавок.false

Фильтры можно сочетать. Кириллицу и специальные символы кодируйте через URLSearchParams или средствами вашей HTTP-библиотеки.

URL · роллы с лососем
https://royal-rolls.com/wp-json/royal/v1/products?category=rolly&tag=losos&per_page=100&modifiers=true

Если per_page больше 100, сервер вернёт до 100 записей; если значение ≤ 0 — до 50. Значение page меньше 1 приводится к 1. Без modifiers=true массив modifiers в списке пуст; это не означает, что у товара нет добавок.

Поля товара

Схема публичной карточки товара
ПоляТип и смысл
id, slug, sku, iiko_idID — число; остальные — строки. Идентификаторы товара.
name, descСтроки: название, описание и состав. Описание может содержать HTML.
price, sale_priceЦена в рублях: числа; sale_price также может быть null. При скидке price — старая цена.
weight, quantity, unitСтроки: вес или объём, количество в порции, единица продажи.
image_url, thumbnail_id, permalinkURL оригинального фото, числовой ID изображения, URL страницы товара.
calories, proteins, fats, carbsСтроки: калории (ккал), белки, жиры и углеводы (г) на порцию.
calories100, proteins100, fats100, carbs100Те же показатели на 100 г, также строки.
tags, categoriesМассивы объектов с id, name, slug; у категорий также parent.
has_sauces, has_mods, modifiersПризнаки выбора соуса и добавок; массив групп модификаторов.
force_sale_badge, cashback_boost, priorityАкционный бейдж (boolean), дополнительный кешбэк и приоритет (числа).
post_status, publish_dateСтроки: publish и дата публикации во времени сайта (Ижевск, UTC+4).

Как читать цену

Актуальная цена — sale_price, если она не null, иначе price. Используйте проверку на null, чтобы корректно обработать нулевую цену.

TypeScript · цена для покупателя
const currentPrice = product.sale_price ?? product.price;

Соусы и добавки

В каждой группе modifiers есть name, iiko_id, minAmount, maxAmount, required и массив items. У каждой добавки: name, price, iiko_item_id, iiko_group_id. Цена добавки указана в рублях.

Отсутствующие текстовые данные могут быть пустой строкой, списки — пустыми массивами. КБЖУ передаются строками. Не выводите незаполненные значения как подтверждённый ноль.

Для отображения названий используйте textContent. Если выводите HTML из desc, обработайте его проверенным HTML-санитайзером вашего приложения.

Как получить весь каталог

Запрашивайте страницы последовательно с per_page=100. Заголовок X-WP-Total содержит общее число товаров после фильтрации, X-WP-TotalPages — число страниц. Не фиксируйте количество страниц в коде.

TypeScript · весь каталог с проверкой ответа
interface ProductSummary {
  id: number;
  name: string;
  price: number;
  sale_price: number | null;
}

function isProduct(value: unknown): value is ProductSummary {
  if (typeof value !== 'object' || value === null) return false;
  return 'id' in value && typeof value.id === 'number'
    && 'name' in value && typeof value.name === 'string'
    && 'price' in value && typeof value.price === 'number'
    && 'sale_price' in value
    && (value.sale_price === null || typeof value.sale_price === 'number');
}

async function loadCatalog(): Promise<ProductSummary[]> {
  const products: ProductSummary[] = [];
  let totalPages = 1;
  for (let page = 1; page <= totalPages; page += 1) {
    const url = new URL('https://royal-rolls.com/wp-json/royal/v1/products');
    url.search = new URLSearchParams({
      per_page: '100', page: String(page), modifiers: 'true',
    }).toString();
    const response = await fetch(url);
    if (!response.ok) throw new Error('HTTP ' + response.status);
    const data: unknown = await response.json();
    if (!Array.isArray(data) || !data.every(isProduct)) {
      throw new Error('Unexpected API response');
    }
    const paginationHeader = response.headers.get('X-WP-TotalPages');
    if (paginationHeader === null) {
      throw new Error('Missing pagination header');
    }
    const pages = Number(paginationHeader);
    if (!Number.isInteger(pages) || pages < 0) {
      throw new Error('Invalid pagination header');
    }
    totalPages = pages;
    products.push(...data);
  }
  return products;
}

const products = await loadCatalog();
for (const product of products) {
  const currentPrice = product.sale_price ?? product.price;
  console.log(product.name, currentPrice);
}

Пример проверяет минимальные поля для названия и цены; в исходном JSON доступны остальные поля карточки. Порядок API — заданный порядок товаров, затем название; он может отличаться от сортировки витрины по популярности. Между страницами данные могут обновляться: для периодической синхронизации сопоставляйте товары по id.

Ошибки и ограничения

Основные HTTP-ответы
КодЧто означает
200Успешный ответ. Пустой массив списка тоже корректный результат.
400Некорректный тип параметра, например текст вместо номера страницы.
404Товар не найден, не опубликован или адрес API не существует.
JSON · товар не найден
{
  "code": "rr_not_found",
  "message": "Товар не найден",
  "data": {
    "status": 404
  }
}
  • Публичное чтение возвращает опубликованные товары. Черновики, отложенные и закрытые товары не доступны без дополнительных прав.
  • Отдельного признака текущей доступности, стоп-листа и расписания продаж в этом ответе нет. Наличие товара в API не гарантирует возможность заказать его прямо сейчас.
  • Этот API предназначен для чтения каталога. Адресов создания заказа, оплаты или изменения товаров здесь нет.
  • Цены и данные могут меняться. Обновляйте их перед использованием и обрабатывайте ошибки HTTP и сети.

Для программ и AI-агентов

Спецификация OpenAPI 3.0.3 описывает четыре адреса, параметры, заголовки пагинации и схемы ответов. Её можно импортировать в Postman, Swagger Editor или использовать для создания клиента.

В HTML страницы встроена разметка JSON-LD: TechArticle для документации и WebAPI для сервиса, со ссылкой на OpenAPI. Весь текст документации доступен в исходном HTML без выполнения JavaScript.

Стандарты: Schema.org WebAPI, Schema.org TechArticle, OpenAPI 3.0.3.

Войти

Войти через ВКонтакте
или по телефону