Order Service — Events
(Добавлено в BR 2.1)
Публикует
order.created
Публикуется при создании нового заказа.
Topic: order.created
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"order_number": "string",
"order_type": "takeaway",
"status": "new",
"created_by": "uuid"
}
}order.paid
Публикуется при фиксации оплаты заказа (paid_at проставлен). Не переводит в ready — изменено в BR 2.5; статус на момент события = текущий (ready / delivered).
Topic: order.paid
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"customer_id": "uuid | null",
"order_number": "string",
"total": "decimal",
"payment_method": "cash | card | qr | mixed",
"paid_amount": "decimal",
"status": "ready | delivered"
}
}Консьюмеры:
- Warehouse Service — возможно перенесён с
order.completedнаorder.paidдля более точного списания (см. открытый вопрос BR 2.5 §10.1) - Webhook dispatcher (Aggregator Service) — пересылает подписанным внешним POS (KOALa и т.п.)
order.cooking_started
(Добавлено в BR 2.5)
Публикуется при переходе new → accepted (кассир/официант нажал «Начать готовку»).
Topic: order.cooking_started
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"order_number": "string",
"accepted_by": "uuid",
"accepted_at": "datetime"
}
}order.ready
(Добавлено в BR 2.5; в BR 5.1 добавлен автотриггер от KDS)
Публикуется при переходе accepted → ready. Триггеры:
- Кассир тапнул «Готово» на POS (
POST /orders/{id}/mark-ready) - Автопереход — все
order_items.kitchen_status = 'ready'(закрытие через KDS) — (BR 5.1)
Topic: order.ready
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"order_number": "string",
"ready_at": "datetime",
"trigger": "manual" | "kds_auto"
}
}order.item.kitchen_status_changed
(Добавлено в BR 5.1)
Публикуется при изменении kitchen_status позиции через KDS-endpoints:
PATCH /orders/{id}/items/{itemId}/kitchen-status— одна позицияPATCH /orders/{id}/kitchen-status?station_id=...— все позиции одной станции (per item публикуется отдельным событием)
Consumers:
pos-bff— broadcast в WebSocket подписчикам KDS (фильтр поkitchen_station_id∈ session.selected_station_ids)- (P2)
analytics-service— метрики времени готовки на станцию
Topic: order.item.kitchen_status_changed
{
"event_id": "uuid",
"event_type": "order.item.kitchen_status_changed",
"timestamp": "datetime",
"version": 1,
"source": "order-service",
"payload": {
"order_id": "uuid",
"item_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"kitchen_station_id": "uuid",
"product_id": "uuid",
"previous_status": "pending" | "preparing" | "ready",
"new_status": "preparing" | "ready",
"changed_by_user_id": "uuid",
"changed_at": "datetime"
}
}order.closed
(Добавлено в BR 2.5)
Публикуется при переходе → closed.
Alias
order.completedСобытие
order.completedпродолжает публиковаться параллельно сorder.closedдля обратной совместимости с Customer Service. Оба события имеют одинаковый payload.
Topic: order.closed
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"customer_id": "uuid | null",
"order_number": "string",
"total": "decimal",
"status": "closed"
}
}order.handed_over
(Добавлено в BR 2.5)
Публикуется при переходе ready → handed_over (заказ передан курьеру).
Topic: order.handed_over
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"order_number": "string",
"courier_id": "uuid",
"handed_over_at": "datetime"
}
}order.in_delivery
(Добавлено в BR 2.5)
Публикуется при переходе handed_over → in_delivery.
Topic: order.in_delivery
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"order_number": "string",
"courier_id": "uuid",
"in_delivery_at": "datetime"
}
}order.delivered
(Добавлено в BR 2.5)
Публикуется при переходе in_delivery → delivered.
Topic: order.delivered
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"customer_id": "uuid | null",
"order_number": "string",
"courier_id": "uuid",
"delivered_at": "datetime"
}
}order.completed
Публикуется при завершении заказа (выдан клиенту).
Topic: order.completed
(Payload обогащён
customer_idв BR 3.1 — используется Customer Service для точечного пересчёта dynamic групп)
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"order_number": "string",
"total": "decimal",
"status": "closed",
"customer_id": "uuid | null"
}
}Консьюмеры:
- Customer Service — если
customer_id IS NOT NULL, триггерит пересчёт dynamic групп для клиента (правила «LTV», «days_inactive» и т.п.). Если NULL — событие игнорируется.
order.cancelled
Публикуется при отмене заказа.
Topic: order.cancelled
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"order_number": "string",
"total": "decimal",
"cancel_reason": "string",
"status": "cancelled"
}
}order.payment_requested
(Добавлено в BR 3.3)
Публикуется когда кассир / клиент нажимает «К оплате» на заказе — сигнал Paykeeper Adapter создать инвойс в PK.
Topic: order.payment_requested
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"order_number": "string",
"total": "decimal",
"cart": [
{
"name": "string",
"quantity": "decimal",
"price": "decimal",
"sum": "decimal",
"tax": "none | vat0 | vat10 | vat20 | vat110 | vat120",
"payment_subject": "goods | service | work | ...",
"payment_type": "full | prepay | advance | ..."
}
],
"customer_name": "string | null",
"customer_phone": "string | null",
"customer_email": "string | null"
}
}Консьюмеры:
- Paykeeper Adapter (
paykeeper-adapter-invoice) — создаёт инвойс в PK.
order.refund_requested
(Добавлено в BR 3.3)
Публикуется при инициации возврата из админки / POS — сигнал Paykeeper Adapter вызвать POST /change/payment/reverse/ в PK.
Topic: order.refund_requested
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"pk_payment_id": "string",
"amount": "decimal",
"is_full_refund": "boolean",
"refund_cart": [
{
"name": "string",
"quantity": "decimal",
"price": "decimal",
"sum": "decimal",
"tax": "string"
}
],
"reason": "string",
"initiated_by": "admin | pos",
"cashier_id": "uuid | null"
}
}Консьюмеры:
- Paykeeper Adapter (
paykeeper-adapter-refund) — вызов PK reverse.
order.refunded
Публикуется при создании записи возврата (refund_records) через POST /internal/orders/{id}/refund. Одна продажа может породить несколько order.refunded (частичные возвраты).
Topic: order.refunded
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"refund_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"order_number": "string",
"order_total": "decimal",
"refund_amount": "decimal",
"refund_total_so_far": "decimal",
"is_full_refund": "boolean",
"type": "refund | reversal",
"payment_method": "cash | card",
"rrn": "string | null",
"fiscal_doc_number": "string | null",
"initiated_by": "pos | admin",
"cashier_id": "uuid"
}
}order.status.changed
Публикуется при любом переходе статуса заказа (new → in_progress → ready → closed/cancelled) а также при переходах агрегаторского flow (accepted → ready → handed_over / rejected). Консьюмируется Store Service для синхронизации статуса столов (zal_tables).
Topic: order.status.changed
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"order_id": "uuid",
"store_id": "uuid",
"franchise_id": "uuid",
"order_number": "string",
"previous_status": "string",
"status": "string",
"reason": "string | null"
}
}Консьюмеры:
- Store Service (
store-service-tables) — обновляетzal_tables.statusпри закрытии/отмене заказа - Aggregator Service (
StatusChangedConsumer) — пушит статус в агрегатор (Я.Еда / МД)
pos.shift.opened
Публикуется при открытии кассовой смены ФЯ на POS-терминале. Источник — POS BFF (POST /internal/shifts/open). Order Service не хранит shift persistence — только транслирует событие для консьюмеров (админка, аналитика).
Topic: pos.shift.opened
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"store_id": "uuid",
"franchise_id": "uuid",
"cashier_id": "uuid",
"fiscal_cycle": "integer",
"opened_at": "datetime (ISO-8601)"
}
}pos.shift.closed
Публикуется при закрытии кассовой смены (Z-отчёт). Payload содержит итоги смены от ФЯ.
Topic: pos.shift.closed
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"store_id": "uuid",
"franchise_id": "uuid",
"cashier_id": "uuid",
"fiscal_cycle": "integer",
"closed_at": "datetime (ISO-8601)",
"z_report_doc_number": "integer | null",
"sales_total": "decimal",
"refunds_total": "decimal",
"cash_total": "decimal",
"card_total": "decimal",
"sales_count": "integer",
"refunds_count": "integer"
}
}Потребляет
| Event | Topic | Consumer group | Зачем |
|---|---|---|---|
aggregator.order.received | aggregator.order.received | order-service-aggregator | AggregatorOrderConsumer принимает заказ из Aggregator Service, создаёт Order с channel=aggregator, aggregator_order_id, aggregator_channel (yandex/delivery_club) |
paykeeper.invoice.created | paykeeper.invoice.created | order-service-pk-invoice | Сохраняет orders.pk_invoice_id, orders.pk_invoice_url после создания инвойса в PK. (BR 3.3) |
paykeeper.payment.received | paykeeper.payment.received | order-service-pk-payment | Фиксация оплаты: orders.paid_at, orders.pk_payment_id, orders.payment_method (маппинг из payment_system_id PK), эмит собственного order.paid. (BR 3.3) |
paykeeper.payment.refunded | paykeeper.payment.refunded | order-service-pk-refund | Создание/обновление RefundRecord.status=done, эмит order.refunded. (BR 3.3) |
paykeeper.receipt.fiscalized | paykeeper.receipt.fiscalized | order-service-pk-receipt | Заполнение orders.fiscal_data (JSONB с ФН/ФД/ФП/смена), orders.pk_fop_receipt_key. (BR 3.3) |
paykeeper.receipt.failed | paykeeper.receipt.failed | order-service-pk-receipt-fail | Ставит orders.fiscal_failed=true — визуальная метка в UI. (BR 3.3) |
paykeeper.refund.failed | paykeeper.refund.failed | order-service-pk-refund-fail | Обновляет RefundRecord.status=failed + сохраняет error_message. (BR 3.3) |
Phase 2+
Дополнительно возможно:
catalog.product.updated— обновление кэша товаровwarehouse.stock.depleted— автоматический стоп-лист при нулевых остатках