Bounded Webhook Payload Examples For External Projections — Примеры внешних bounded webhook payloads
Версия: 1.0
Дата: 24.04.2026
Статус: Готов к обсуждению
Назначение документа
Этот документ фиксирует первые bounded example payloads для внешних async projections платформы.
Его задача — показать:
- как внутренние high-value events должны проецироваться во внешние webhook contracts;
- какие поля допустимы во внешнем payload, а какие должны оставаться внутренними;
- как удерживаются
tenant,partner,correlation,delivery,retryиreconciliationsemantics на внешнем surface; - как bounded projection отличается от richer internal domain event.
Документ не является финальным webhook schema package. Он является example-layer для внешнего async surface после catalog и compatibility/boundary policy.
Опорные документы
- External Async Projection Catalog By Surface And Partner Class — Каталог внешних async-проекций по surface-ам и классам партнёров
- Webhook Compatibility Checklist For External Async Notifications — Границы внешних async уведомлений и их совместимости
- Producer Readiness Checklist For Async Contract Changes — Проверка готовности producers к безопасному выпуску изменений async contracts
- Consumer Compatibility Checklist By Release Unit — Проверка готовности consumers к эволюции async contracts
- Payload Examples For Top Critical Events — Первые example payloads для ключевых async событий
- API Contracts — Surface Contracts и правила внешнего взаимодействия
- Clients Layer — Клиентские поверхности и рабочие модели
- Tenant Configuration And Enablement — Тенантная настройка, policy и ввод в эксплуатацию
Почему Этот Документ Нужен Отдельно
После появления:
- внутреннего example-layer;
- webhook boundary policy;
- external projection catalog;
уже недостаточно знать только, какие projections разрешены теоретически.
Нужен следующий практический слой, который показывает:
- как именно должна выглядеть bounded внешняя форма;
- где проходит граница между полезным внешним контекстом и утечкой внутренней кухни;
- как делать webhook payload usable, не превращая его во второй internal event bus.
Без этого команда будет либо слишком копировать внутренние payload-ы наружу, либо делать слишком бедные уведомления без operational value.
Главный Принцип
Внешний webhook payload должен быть:
- partner-comprehensible;
- contract-stable;
- bounded;
- sufficient for external workflow continuation;
- explicit about pull reconciliation where full truth is not embedded.
Общая Внешняя Envelope Discipline
Для примеров ниже используется bounded external envelope:
notification_namenotification_versionnotification_idoccurred_atdelivery_scopepartner_idtenant_idsurface_classcorrelation_ididempotency_keypull_reconciliation_refpayload
Во внешний envelope намеренно не выносятся:
- raw internal
schema_family - internal
delivery_class - operator-only causation chains
- raw internal producer/runtime names
Example 1. quote-invalidated
Surface Fit
- agency working surface
- partner API surface
- white-label surface
Example Payload
{
"notification_name": "quote-invalidated",
"notification_version": "1.0",
"notification_id": "wh_qinv_01J9X2A7B8C9D0E1F2G3H4J5",
"occurred_at": "2026-04-24T18:14:20Z",
"delivery_scope": "partner-webhook",
"partner_id": "partner_standard_travelhub",
"tenant_id": "tenant_travelhub_eu",
"surface_class": "partner-api",
"correlation_id": "corr_quote_01J9X28A7S6D5F4G3H2J1K0L",
"idempotency_key": "quote-invalidated:quote_01J9X27AA11BB22CC33DD44EE:v1",
"pull_reconciliation_ref": "quote_01J9X27AA11BB22CC33DD44EE",
"payload": {
"quote_id": "quote_01J9X27AA11BB22CC33DD44EE",
"quote_state": "invalidated",
"reason_class": "upstream-offer-change",
"action_required": "refresh-before-booking",
"customer_visible_effect": "quoted-price-no-longer-valid"
}
}
Что Здесь Важно
- нет внутренних repricing internals;
- есть чёткий bounded
reason_class; - webhook не притворяется полным price snapshot;
- consumer понимает, что нужно подтянуть fresh quote state через pull.
Example 2. booking-confirmed
Surface Fit
- agency working surface
- partner API surface
- white-label surface
- selected customer-facing self-service surface
Example Payload
{
"notification_name": "booking-confirmed",
"notification_version": "1.0",
"notification_id": "wh_bconf_01J9X2M4N5B6V7C8X9Z0A1S2",
"occurred_at": "2026-04-24T18:20:42Z",
"delivery_scope": "partner-webhook",
"partner_id": "partner_standard_travelhub",
"tenant_id": "tenant_travelhub_eu",
"surface_class": "partner-api",
"correlation_id": "corr_booking_01J9X2K3L4M5N6B7V8C9X0Z1",
"idempotency_key": "booking-confirmed:booking_01J9X2J1H2G3F4D5S6A7P8O9:v1",
"pull_reconciliation_ref": "booking_01J9X2J1H2G3F4D5S6A7P8O9",
"payload": {
"booking_id": "booking_01J9X2J1H2G3F4D5S6A7P8O9",
"booking_state": "confirmed",
"external_reference": "BK-2026-000184",
"supplier_reference_available": true,
"follow_up_state": "none",
"customer_visible_effect": "booking-confirmed"
}
}
Что Здесь Важно
- есть bounded external reference;
- supplier reference не утаскивает весь внутренний transactional context;
- payload пригоден и для machine consumer, и для human workflow refresh.
Example 3. booking-requires-action
Surface Fit
- agency working surface
- partner API surface
- white-label surface
Example Payload
{
"notification_name": "booking-requires-action",
"notification_version": "1.0",
"notification_id": "wh_bact_01J9X31Q2W3E4R5T6Y7U8I9O",
"occurred_at": "2026-04-24T18:27:09Z",
"delivery_scope": "partner-webhook",
"partner_id": "partner_whitelabel_orbit",
"tenant_id": "tenant_orbit_whitelabel",
"surface_class": "white-label",
"correlation_id": "corr_booking_01J9X2K3L4M5N6B7V8C9X0Z1",
"idempotency_key": "booking-requires-action:booking_01J9X2J1H2G3F4D5S6A7P8O9:v1",
"pull_reconciliation_ref": "booking_01J9X2J1H2G3F4D5S6A7P8O9",
"payload": {
"booking_id": "booking_01J9X2J1H2G3F4D5S6A7P8O9",
"booking_state": "requires_action",
"action_class": "partner-follow-up-needed",
"severity_class": "high",
"customer_visible_effect": "booking-not-fully-resolved"
}
}
Что Здесь Важно
- не раскрывается внутренний recovery path;
- но внешний consumer понимает urgency и bounded action class;
- pull reconciliation ref даёт путь к более полной read model.
Example 4. supplier-disruption-affecting-booking
Surface Fit
- agency working surface
- partner API surface
- white-label surface
- selected customer-facing self-service surface
Example Payload
{
"notification_name": "supplier-disruption-affecting-booking",
"notification_version": "1.0",
"notification_id": "wh_disrupt_01J9X3C4V5B6N7M8A9S0D1F2",
"occurred_at": "2026-04-24T18:36:55Z",
"delivery_scope": "partner-webhook",
"partner_id": "partner_standard_travelhub",
"tenant_id": "tenant_travelhub_eu",
"surface_class": "partner-api",
"correlation_id": "corr_postbooking_01J9X3A1S2D3F4G5H6J7K8L9",
"idempotency_key": "supplier-disruption-affecting-booking:booking_01J9X2J1H2G3F4D5S6A7P8O9:v1",
"pull_reconciliation_ref": "postbooking_case_01J9X39P8O7I6U5Y4T3R2E1W",
"payload": {
"booking_id": "booking_01J9X2J1H2G3F4D5S6A7P8O9",
"impact_class": "supplier-service-disruption",
"action_required": "review-updated-booking-options",
"customer_visible_effect": "confirmed-booking-needs-follow-up",
"service_case_state": "open"
}
}
Что Здесь Важно
- внешний payload не показывает внутренний SLA или operator routing;
- но даёт партнёру достаточно сигнала для service workflow;
- case truth остаётся доступной через bounded pull contract.
Example 5. quota-exhausted
Surface Fit
- partner API surface
- white-label operator surface
Example Payload
{
"notification_name": "quota-exhausted",
"notification_version": "1.0",
"notification_id": "wh_quota_01J9X3N5M6B7V8C9X0Z1A2S3",
"occurred_at": "2026-04-24T18:42:11Z",
"delivery_scope": "partner-webhook",
"partner_id": "partner_standard_travelhub",
"tenant_id": "tenant_travelhub_eu",
"surface_class": "partner-api",
"correlation_id": "corr_usage_01J9X3M4N5B6V7C8X9Z0A1S2",
"idempotency_key": "quota-exhausted:partner_standard_travelhub:search-requests:v1",
"pull_reconciliation_ref": "usage_profile_partner_standard_travelhub",
"payload": {
"governance_state": "quota_exhausted",
"affected_capability": "search-requests",
"enforcement_effect": "requests-may-be-rejected",
"action_required": "contact-platform-or-wait-for-reset",
"customer_visible_effect": "integration-capacity-limited"
}
}
Что Здесь Важно
- payload не раскрывает внутреннюю enforcement matrix;
- но честно отражает business effect для партнёра;
- bounded capability naming и effect semantics пригодны для стабильного контракта.
Example 6. proposal-published
Surface Fit
- agency working surface
- white-label surface
- customer-facing proposal surface
Example Payload
{
"notification_name": "proposal-published",
"notification_version": "1.0",
"notification_id": "wh_prop_01J9X3Z7X8C9V0B1N2M3A4S5",
"occurred_at": "2026-04-24T18:48:33Z",
"delivery_scope": "proposal-webhook",
"partner_id": "partner_whitelabel_orbit",
"tenant_id": "tenant_orbit_whitelabel",
"surface_class": "white-label",
"correlation_id": "corr_proposal_01J9X3Y6T5R4E3W2Q1A0S9D8",
"idempotency_key": "proposal-published:proposal_01J9X3X5C4V3B2N1M0L9K8J7:v1",
"pull_reconciliation_ref": "proposal_01J9X3X5C4V3B2N1M0L9K8J7",
"payload": {
"proposal_id": "proposal_01J9X3X5C4V3B2N1M0L9K8J7",
"proposal_state": "published",
"publication_scope": "customer-viewable",
"current_version_label": "v3",
"customer_visible_effect": "proposal-ready-to-view"
}
}
Что Здесь Важно
- proposal publication не смешан с internal offer publication;
- payload остаётся presentation-safe;
- customer-facing effect явно отделён от internal composition lifecycle.
Что Не Надо Делать По Образцу Этих Примеров
Пока не нужно:
- делать внешние webhook payload-ы snapshot-heavy без необходимости;
- копировать внутренние
schema_family,producer,delivery_classи operator-only codes; - пытаться через webhook полностью заменить bounded pull/read contracts;
- смешивать partner-facing и end-customer-facing payload semantics в одном contract family.
Что Должно Появиться Следом
Следующий практический слой после этого документа:
- partner-class-specific subscription policy draft;
- webhook delivery operations and support playbook;
- first field catalogs for external webhook contracts;
- future formal external webhook schema package.
Этот документ делает внешний async surface заметно ближе к реальному implementation-ready contract layer.
Уточнение под Фазы 4–6 (28.04.2026)
Bounded webhook payload examples для external projections — использовать каноничные структуры из reference-документов фаз 4–6:
- Booking webhook examples → booking-state-machine.md (14 каноничных состояний);
- Payment webhook examples → payment-domain.md;
- Tour saga partner webhooks → tour-builder-operational-model.md;
- Notification webhook semantics → notification-and-communication.md;
- Truth visibility per entity (что попадает в external webhook payload) → clients.md, Visibility Matrix;
- Per partner class projections → api-as-product.md;
- Tenant scoping → multi-tenant-isolation-strength.md;
- HMAC signing → security-architecture.md;
- GDPR consent для marketing webhooks → compliance-and-legal.md.
Каноничный сводный каталог имён — initial-event-taxonomy.md.
Уточнение выполнено через no-destruction.