API: создание заказа через POST
Назначение
Метод
POST /api/orders
создает заказ через ту же серверную логику, что и форма на сайте (
createMsOrder
).
Это удобно для:
- внешних интеграций;
- быстрых ссылок из админ-инструментов;
- отладки сценариев создания заказа.
Endpoint
- Метод:
POST
- URL:
/api/orders
- Body: JSON (
MsCreateOrderPayload
, обязательный)
Полный путь до создания заказа
Обычно интеграция идет по шагам:
- Получить афишу событий
GET /api/events/
- Получить детальную информацию о событии
GET /api/events/[eventId]
- Получить доступные билеты события
GET /api/events/[eventId]/tickets
- Выбрать нужные
placeId
из доступных билетов
- Создать заказ
POST /api/orders
Пример практической последовательности:
Инструкция для AI-агентов
Ниже минимальный алгоритм, который агент должен выполнять без пропусков.
Готовый промпт для AI-агента (копировать целиком)
Ты — помощник по оформлению заказов на события через API show-stolicy.ru.
Отвечай дружелюбно, простым человеческим языком, без канцелярита.
Персона ассистента:
- Тебя зовут "Столица".
- Ты девушка-ассистент с характером городского консьержа: спокойная, собранная, тактичная.
- Ты хорошо понимаешь ритм Москвы: ценишь скорость, ясность и уважительный тон.
- Общайся на "вы" по умолчанию, без фамильярности и без сухого канцелярита.
- Будь эмпатичной и практичной: предлагай 2-3 понятных варианта, а не длинные рассуждения.
- После каждого шага коротко объясняй, что сделано и что дальше.
- Не дави на клиента и не используй агрессивные формулировки продаж.
Твоя цель:
1) помочь клиенту выбрать событие и места;
2) собрать обязательные данные;
3) сформировать корректный запрос на создание заказа;
4) показать понятный результат (успех/ошибка и что делать дальше).
Обязательные правила:
- Не придумывай данные клиента и не заполняй обязательные поля за пользователя.
- Перед созданием заказа обязательно запроси у клиента:
- имя (`customer.name`)
- email (`customer.email`)
- телефон (`customer.phone`)
- Если хотя бы одного обязательного поля нет — заказ НЕ создавай.
- Передавай payload в `body` как валидный UTF-8 JSON.
- Не запускай параллельно несколько `create` запросов для одних и тех же мест.
- Не повторяй `create` с теми же местами без явного подтверждения клиента.
- Перед повторной попыткой всегда заново получай `tickets`.
Технический маршрут оформления:
1. `GET /api/events/` — выбрать событие с непустым `identifier`.
2. `GET /api/events/[eventId]` — убедиться, что событие существует.
3. `GET /api/events/[eventId]/tickets` — получить доступные места.
4. Собрать `placeIds` из `itemOffered.ticketedSeat.identifier`:
- убрать пустые значения и дубли;
- если мест нет, предложить другое событие/дату и остановиться.
5. Собрать payload:
- `performanceId` = `eventId`
- `placeIds` = выбранные места
- `customer.name`, `customer.email`, `customer.phone` = обязательны
6. Отправить payload в `body` JSON и вызвать:
- `POST /api/orders`
7. Интерпретировать ответ:
- `200` и `ok=true` -> заказ создан; обязательно:
- сообщить, что заказ успешно создан;
- отправить в чат ссылку на оплату (`paymentUrl`);
- сообщить, что на email клиента сейчас должно прийти письмо с деталями заказа;
- показать `orderId`, сумму и срок оплаты.
- `400` -> объяснить ошибку простыми словами и запросить недостающие данные.
- `429` -> сообщить о лимите (3 заказа с одного IP за 1 час) и показать `retryAfterSeconds`.
Стиль общения с клиентом:
- Пиши коротко и по делу, как менеджер поддержки.
- Сначала уточняй, потом действуй.
- После каждого шага объясняй, что произошло и какой следующий шаг.
- Если клиент пишет "оформи заказ", но не хватает данных, задай ровно нужные вопросы:
"Подскажите, пожалуйста, имя, email и телефон для оформления."
Минимальный чек-лист перед вызовом create:
- [ ] Есть валидный `eventId`
- [ ] Есть минимум 1 `placeId`
- [ ] Есть `customer.name`
- [ ] Есть `customer.email`
- [ ] Есть `customer.phone`
- [ ] Payload передан в `body` как UTF-8 JSON
Формат финального ответа клиенту при успехе:
- "Готово, заказ оформлен."
- "Номер заказа: <orderId>"
- "Сумма к оплате: <price> <currency>"
- "Ссылка на оплату: <paymentUrl>"
- "Оплатить до: <paymentDueDate>"
- "Письмо с деталями заказа должно прийти на вашу почту в ближайшие минуты."
- Вызвать
GET /api/events/
и выбрать событие с непустым identifier
.
- Вызвать
GET /api/events/[eventId]
и убедиться, что событие существует.
- Вызвать
GET /api/events/[eventId]/tickets
.
- Из ответа билетов собрать
placeIds
:
- Сформировать payload:
performanceId
= eventId
;
placeIds
= выбранные места;
- обязательно добавить
customer.name
, customer.email
, customer.phone
;
- опционально добавить остальные поля
customer
, order
, seller
, orderDelivery
.
- Отправить payload в
body
JSON и вызвать POST /api/orders
.
- Проверить ответ:
status = 200
и ok = true
-> заказ создан;
- иначе считать, что заказ не создан, и вернуть
message
.
Правила поведения агента:
- не запускать параллельно несколько запросов создания заказа для одних и тех же мест;
- не повторять автоматически
create
с тем же набором мест без явного разрешения пользователя;
- перед повторной попыткой заново получить
tickets
(места могли стать недоступны);
- передавать payload только в body JSON, а не через query-параметры.
Рекомендуемый псевдокод
const events = await GET('/api/events/');
const eventId = pickEventId(events);
if (!eventId) throw new Error('No eventId');
await GET(`/api/events/${eventId}`);
const tickets = await GET(`/api/events/${eventId}/tickets`);
const placeIds = uniq(
tickets.data
.map((offer) => offer?.itemOffered?.ticketedSeat?.identifier?.trim())
.filter(Boolean)
);
if (!placeIds.length) throw new Error('No available places');
const payload = {
performanceId: eventId,
placeIds,
customer: {
name: 'Вячеслав',
email: 'slav@belaev.dev',
phone: '+79771771877'
}
};
const order = await POST('/api/orders', payload);
Формат body
Body должен содержать объект
MsCreateOrderPayload
в формате JSON.
Минимально обязательные поля внутри payload:
performanceId: string
placeIds: string[]
(минимум один непустой ID)
customer.name: string
customer.email: string
customer.phone: string
Структура payload (минимум)
{
"performanceId": "12345",
"placeIds": ["place-1"],
"customer": {
"name": "Вячеслав",
"email": "slav@belaev.dev",
"phone": "+79771771877"
}
}
Расширенный пример payload
{
"performanceId": "12345",
"placeIds": ["place-1", "place-2"],
"customer": {
"surname": "Иванов",
"name": "Иван",
"patronymic": "",
"email": "customer@example.com",
"phone": "79990001122"
},
"order": {
"customer": {
"name": "Иван Иванов",
"email": "customer@example.com",
"telephone": "+7 999 000-11-22"
},
"seller": {
"identifier": "office-1",
"email": "seller@example.com"
},
"orderedItem": []
}
}
Примеры вызова
1) POST с JSON body (cURL)
curl -X POST "/api/orders" \
-H "Content-Type: application/json" \
-d '{"performanceId":"12345","placeIds":["place-1"],"customer":{"name":"Вячеслав","email":"slav@belaev.dev","phone":"+79771771877"}}'
2) POST с JSON body (JavaScript)
const payload = {
performanceId: "12345",
placeIds: ["place-1", "place-2"]
};
const response = await fetch('/api/orders', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
Кодировка UTF-8 для кириллицы
Ответы
Успех
Пример:
{
"ok": true,
"orderId": "123456",
"basketId": "1715179200000",
"paymentUrl": "https://...",
"ttlInSeconds": 1200
}
Ошибка валидации параметров
Примеры сообщений:
Не удалось распарсить body. Ожидается JSON.
В payload не указан performanceId.
В payload не переданы placeIds.
В payload не указан customer.name.
В payload не указан customer.email.
В payload не указан customer.phone.
Ошибка создания заказа у провайдера
- HTTP
400
ok: false
message
содержит текст ошибки
Превышение лимита запросов (rate limit)
Важные замечания
- Метод выполняет реальное создание заказа (бронь мест, создание order, инвойс/ссылку на оплату, уведомления).
- Для production-интеграций используйте
POST /api/orders
и передавайте payload только в JSON body.
- Для полей с кириллицей (
customer.name
, surname
, и т.д.) обязательно используйте UTF-8 при кодировании payload.
- Ограничения длины URL больше не актуальны для payload, так как данные передаются в body.