Appearance
Guides
Гайды для партнёров и интеграторов Partizap API.
Начало работы
Базовый URL
Все запросы к API отправляются на:
| Среда | URL |
|---|---|
| Production | https://partizap.ru/api |
| Development | https://dev.partizap.ru/api |
API принимает и возвращает application/json. Загрузка файлов (изображения) выполняется через multipart/form-data.
Аутентификация
Partizap использует сессионную аутентификацию на основе cookie. JWT не используется.
Шаг 1. Регистрация или вход
bash
# Регистрация
curl -X POST https://partizap.ru/api/auth/register \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{
"name": "Иван Иванов",
"email": "ivan@example.com",
"password": "SecurePass123"
}'
# Вход
curl -X POST https://partizap.ru/api/auth/login \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{
"email": "ivan@example.com",
"password": "SecurePass123"
}'После успешного входа сервер устанавливает две cookie:
| Cookie | Назначение | HttpOnly |
|---|---|---|
PARTIZAP_SESSION | Идентификатор сессии | Да |
CSRF_TOKEN | Токен защиты от CSRF | Нет (доступен из JS) |
Шаг 2. CSRF-токен для мутирующих запросов
Все запросы POST, PUT, DELETE требуют заголовок X-CSRF-TOKEN со значением из cookie CSRF_TOKEN.
bash
# Получить CSRF-токен из cookie и передать в заголовке
curl -X POST https://partizap.ru/api/vendor/products \
-H "Content-Type: application/json" \
-H "X-CSRF-TOKEN: <значение из cookie CSRF_TOKEN>" \
-b cookies.txt \
-d '{ ... }'На JavaScript:
javascript
// Прочитать CSRF-токен из cookie
function getCsrfToken() {
const match = document.cookie.match(/CSRF_TOKEN=([^;]+)/);
return match ? match[1] : '';
}
// Пример fetch-запроса
const response = await fetch('https://partizap.ru/api/vendor/products', {
method: 'POST',
credentials: 'include', // отправить cookie
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': getCsrfToken(),
},
body: JSON.stringify({ /* ... */ }),
});Шаг 3. Проверка текущей сессии
bash
curl https://partizap.ru/api/auth/me -b cookies.txtjson
{
"data": {
"id": 42,
"name": "Иван Иванов",
"email": "ivan@example.com",
"email_verified": true,
"account_type": "personal",
"is_admin": false
}
}Совет
GET /auth/me -- удобный способ проверить, что сессия активна. Используйте его при инициализации клиентского приложения.
Формат ответов
Успешный ответ
Все данные обёрнуты в поле data:
json
{ "data": { "id": 1, "title": "Фара BMW E46 левая" } }Коллекции возвращают массив в data и мета-информацию о пагинации в meta:
json
{
"data": [ { "id": 1, "title": "..." }, { "id": 2, "title": "..." } ],
"meta": { "has_more": true, "next_cursor": "eyJpZCI6MTB9" }
}Ответ с ошибкой
json
{
"error": {
"code": "validation_error",
"message": "Ошибка валидации данных",
"details": {
"title": ["Название обязательно"],
"price": ["Цена должна быть положительной"]
}
}
}HTTP-коды ответов
| Код | Описание |
|---|---|
200 | Успешный GET, PUT |
201 | Ресурс создан (POST) |
204 | Успешный DELETE (тело пустое) |
400 | Ошибка валидации |
401 | Не авторизован (нет сессии) |
403 | Доступ запрещён / неверный CSRF |
404 | Ресурс не найден |
429 | Превышен лимит запросов |
500 | Внутренняя ошибка сервера |
Курсорная пагинация
API использует курсорную пагинацию вместо offset-based. Передавайте параметры cursor и limit:
bash
# Первая страница
curl "https://partizap.ru/api/store/products?limit=20"
# Следующая страница (cursor из meta предыдущего ответа)
curl "https://partizap.ru/api/store/products?limit=20&cursor=eyJpZCI6MjB9"Важно
Не кэшируйте значения cursor надолго. Они предназначены для последовательной навигации по результатам и могут стать невалидными при изменении данных.
Rate Limiting
API ограничивает количество запросов на уровне nginx и приложения:
| Группа эндпоинтов | Лимит | Окно |
|---|---|---|
/store/* (GET) | 100 запросов | 1 минута |
/store/* (POST) | 20 запросов | 1 минута |
/vendor/* | 60 запросов | 1 минута |
/auth/login | 5 попыток | 15 минут |
/auth/register | 5 попыток | 15 минут |
При превышении лимита API вернёт 429 Too Many Requests.
Интеграция каталога товаров
Создание товара
Товар создаётся в статусе draft. Для публикации используется отдельный эндпоинт.
bash
curl -X POST https://partizap.ru/api/vendor/products \
-H "Content-Type: application/json" \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txt \
-d '{
"title": "Фара BMW E46 левая",
"description": "Оригинальная фара в хорошем состоянии, без трещин",
"price": 15000,
"category_id": 3,
"condition": "used",
"steering": "left",
"region_id": 1,
"city_id": 1,
"car_modifications": [42, 43, 44]
}'json
{
"data": {
"id": 157,
"title": "Фара BMW E46 левая",
"status": "draft",
"price": 15000,
"category_id": 3,
"condition": "used",
"steering": "left",
"created_at": "2026-03-15T10:30:00+03:00"
}
}Поля товара
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
title | string | Да | Название (до 255 символов) |
description | string | Нет | Описание товара |
price | number | Да | Цена в рублях (> 0) |
category_id | integer | Да | ID категории запчасти |
condition | string | Да | Состояние: new, used, refurbished |
steering | string | Нет | Руль: left, right, both, universal |
oem_number | string | Нет | OEM-номер запчасти |
region_id | integer | Да | ID региона |
city_id | integer | Да | ID города |
car_modifications | int[] | Нет | Массив ID модификаций авто |
Загрузка изображений
Изображения загружаются отдельным запросом с multipart/form-data. Максимум 10 фотографий на товар.
bash
curl -X POST https://partizap.ru/api/vendor/products/157/images \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txt \
-F "image=@photo.jpg"json
{
"data": {
"id": 301,
"position": 0,
"original_url": "https://cdn.partizap.ru/products/originals/157/abc123.jpg",
"thumbnail_url": "https://cdn.partizap.ru/products/thumbnails/157/abc123.webp",
"medium_url": "https://cdn.partizap.ru/products/medium/157/abc123.webp",
"large_url": "https://cdn.partizap.ru/products/large/157/abc123.webp"
}
}Ограничения на изображения
- Форматы: JPEG, PNG, WebP
- Максимальный размер: 10 МБ
- Максимум 10 изображений на товар
- Сервер автоматически создаёт варианты: thumbnail (150x150), medium (600x600), large (1200x1200) в формате WebP
Изменение порядка изображений
bash
curl -X PUT https://partizap.ru/api/vendor/products/157/images/order \
-H "Content-Type: application/json" \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txt \
-d '{ "order": [303, 301, 302] }'Удаление изображения
bash
curl -X DELETE https://partizap.ru/api/vendor/products/157/images/301 \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txtЖизненный цикл товара
draft → (publish) → pending → (модерация) → active
→ rejected
active → (обновление/снятие) → draft| Статус | Описание |
|---|---|
draft | Черновик. Не виден в каталоге |
pending | На модерации после публикации |
active | Опубликован и виден покупателям |
rejected | Отклонён модератором |
Публикация товара
bash
curl -X POST https://partizap.ru/api/vendor/products/157/publish \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txtВажно
Товар должен иметь хотя бы одно изображение и все обязательные поля для успешной публикации. После публикации товар поступает на модерацию.
Обновление товара
bash
curl -X PUT https://partizap.ru/api/vendor/products/157 \
-H "Content-Type: application/json" \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txt \
-d '{
"price": 12000,
"description": "Обновлённое описание"
}'Получение своих товаров
bash
curl "https://partizap.ru/api/vendor/products?limit=20" -b cookies.txtУдаление товара
bash
curl -X DELETE https://partizap.ru/api/vendor/products/157 \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txtСправочник совместимости автомобилей
4-уровневая иерархия
Partizap использует четырёхуровневую иерархию для точного подбора совместимости запчастей:
Марка (Make) → Модель (Model) → Поколение (Generation) → Модификация (Modification)Пример: BMW → 3 Series → E46 (1998-2006) → 320i 2.2 AT
Каждый уровень загружается каскадно: выбор марки определяет список моделей, выбор модели -- список поколений и т.д.
Получение марок
bash
curl https://partizap.ru/api/store/cars/makesjson
{
"data": [
{ "id": 1, "name": "BMW", "slug": "bmw", "logo_url": "https://cdn.partizap.ru/car-logos/bmw.png" },
{ "id": 2, "name": "Mercedes-Benz", "slug": "mercedes-benz", "logo_url": "..." }
]
}Получение моделей по марке
bash
curl https://partizap.ru/api/store/cars/makes/1/modelsjson
{
"data": [
{ "id": 5, "name": "3 Series", "slug": "3-series", "make_id": 1 },
{ "id": 6, "name": "5 Series", "slug": "5-series", "make_id": 1 }
]
}Получение поколений по модели
bash
curl https://partizap.ru/api/store/cars/models/5/generationsjson
{
"data": [
{ "id": 12, "name": "E46", "slug": "e46", "model_id": 5, "year_start": 1998, "year_end": 2006 },
{ "id": 13, "name": "E90", "slug": "e90", "model_id": 5, "year_start": 2005, "year_end": 2013 }
]
}Получение модификаций по поколению
bash
curl https://partizap.ru/api/store/cars/generations/12/modificationsjson
{
"data": [
{ "id": 42, "name": "320i 2.2 AT", "generation_id": 12, "engine": "2.2", "power_hp": 170 },
{ "id": 43, "name": "325i 2.5 MT", "generation_id": 12, "engine": "2.5", "power_hp": 192 }
]
}Привязка совместимости к товару
При создании или обновлении товара передайте массив ID модификаций:
bash
curl -X POST https://partizap.ru/api/vendor/products \
-H "Content-Type: application/json" \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txt \
-d '{
"title": "Фара BMW E46 левая",
"price": 15000,
"category_id": 3,
"condition": "used",
"region_id": 1,
"city_id": 1,
"car_modifications": [42, 43]
}'Совет
Указывайте конкретные модификации для точного подбора. Покупатели часто фильтруют товары вплоть до уровня модификации (объём двигателя, тип КПП).
Фильтрация товаров по автомобилю
Покупатели могут фильтровать каталог на любом уровне иерархии:
bash
# Все запчасти для BMW
curl "https://partizap.ru/api/store/products?make_id=1"
# Запчасти для BMW 3 Series
curl "https://partizap.ru/api/store/products?make_id=1&model_id=5"
# Запчасти для BMW 3 Series E46
curl "https://partizap.ru/api/store/products?make_id=1&model_id=5&generation_id=12"
# Запчасти для конкретной модификации
curl "https://partizap.ru/api/store/products?modification_id=42"Интеграция чата
Архитектура
Чат в Partizap построен на двух компонентах:
- REST API -- создание диалогов, отправка сообщений, загрузка истории
- Centrifugo WebSocket -- доставка сообщений и событий в реальном времени
Клиент → REST API (PHP) → БД + Centrifugo publish → WebSocket → ПолучательREST API чата
Создание диалога
Диалог привязывается к товару. Покупатель инициирует диалог с продавцом:
bash
curl -X POST https://partizap.ru/api/vendor/conversations \
-H "Content-Type: application/json" \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txt \
-d '{ "product_id": 157 }'json
{
"data": {
"id": 89,
"product_id": 157,
"buyer_id": 42,
"seller_id": 15,
"created_at": "2026-03-15T12:00:00+03:00"
}
}Список диалогов
bash
curl "https://partizap.ru/api/vendor/conversations?limit=20" -b cookies.txtОтправка сообщения
bash
curl -X POST https://partizap.ru/api/vendor/conversations/89/messages \
-H "Content-Type: application/json" \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txt \
-d '{ "body": "Здравствуйте! Фара ещё в наличии?" }'Отправка изображения в чат
bash
curl -X POST https://partizap.ru/api/vendor/conversations/89/messages/image \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txt \
-F "image=@photo.jpg"Загрузка истории сообщений
bash
curl "https://partizap.ru/api/vendor/conversations/89/messages?limit=50" -b cookies.txtОтметка о прочтении
bash
curl -X POST https://partizap.ru/api/vendor/conversations/89/read \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txtСчётчик непрочитанных
bash
curl "https://partizap.ru/api/vendor/conversations/unread-count" -b cookies.txtjson
{ "data": { "unread_count": 3 } }WebSocket-подключение через Centrifugo
Для получения сообщений в реальном времени подключитесь к Centrifugo по WebSocket.
Подключение
URL подключения: wss://partizap.ru/connection/websocket
Centrifugo использует proxy-аутентификацию через бэкенд -- клиенту не нужен отдельный токен. Достаточно передать сессионную cookie при подключении.
javascript
import { Centrifuge } from 'centrifuge';
const client = new Centrifuge('wss://partizap.ru/connection/websocket', {
// Cookie передаётся автоматически при same-origin подключении
});
client.connect();Подписка на каналы чата
Каждый диалог имеет канал формата chat:<conversation_id>:
javascript
const sub = client.newSubscription('chat:89');
sub.on('publication', (ctx) => {
const message = ctx.data;
console.log('Новое сообщение:', message);
});
sub.on('join', (ctx) => {
console.log('Пользователь онлайн:', ctx.info);
});
sub.on('leave', (ctx) => {
console.log('Пользователь офлайн:', ctx.info);
});
sub.subscribe();События в канале
| Событие | Данные | Описание |
|---|---|---|
publication (message) | { id, body, sender_id, type, created_at } | Новое сообщение |
publication (typing) | { type: "typing", user_id } | Индикатор набора текста |
publication (read) | { type: "read", user_id, last_read_id } | Отметка о прочтении |
Отправка индикатора набора
bash
curl -X POST https://partizap.ru/api/vendor/conversations/89/typing \
-H "X-CSRF-TOKEN: <csrf_token>" \
-b cookies.txtСовет
Для экономии ресурсов используйте SharedWorker на фронтенде -- один WebSocket на все вкладки браузера. Partizap frontend использует именно этот подход.
Поиск по сообщениям
bash
# Поиск по всем диалогам
curl "https://partizap.ru/api/vendor/messages/search?q=фара" -b cookies.txt
# Поиск в конкретном диалоге
curl "https://partizap.ru/api/vendor/conversations/89/messages/search?q=фара" -b cookies.txtСправочные эндпоинты
Категории
bash
curl https://partizap.ru/api/store/categoriesКатегории возвращаются деревом (parent_id для вложенности). Типы категорий: part (тип запчасти), condition (состояние), attribute (характеристика).
Регионы и города
bash
# Список регионов
curl https://partizap.ru/api/store/geo/regions
# Города региона
curl https://partizap.ru/api/store/geo/regions/1/cities
# Районы города
curl https://partizap.ru/api/store/geo/cities/1/districts
# Станции метро города
curl https://partizap.ru/api/store/geo/cities/1/metroПродавцы
bash
# Публичный профиль продавца
curl https://partizap.ru/api/store/sellers/15
# Товары продавца
curl "https://partizap.ru/api/store/sellers/15/products?limit=20"Поиск товаров
bash
# Полнотекстовый поиск (через каталог с параметром q)
curl "https://partizap.ru/api/store/products?q=фара+bmw+e46&sort=relevance"
# Автокомплит для строки поиска (лёгкий endpoint)
curl "https://partizap.ru/api/store/products/suggest?q=фара&limit=6"
# Фильтрация каталога с комбинацией параметров
curl "https://partizap.ru/api/store/products?make_id=1&category_id=3&price_min=5000&price_max=30000&city_id=1&sort=price_asc&limit=20"Параметры фильтрации каталога
| Параметр | Тип | Описание |
|---|---|---|
category_id | integer | ID категории |
make_id | integer | ID марки авто |
model_id | integer | ID модели авто |
generation_id | integer | ID поколения |
modification_id | integer | ID модификации |
region_id | integer | ID региона |
city_id | integer | ID города |
price_min | number | Минимальная цена |
price_max | number | Максимальная цена |
steering | string | Руль: left, right, both, universal |
sort | string | Сортировка: newest, price_asc, price_desc |
cursor | string | Курсор для пагинации |
limit | integer | Количество записей (по умолчанию 20, макс. 100) |