< Summary

Information
Class: Services.OzonWebhookServices.Models.OzonDeliveryDateChangedNotification
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/OzonWebhookServices/Models/OzonWebhookInputModels.cs
Line coverage
100%
Covered lines: 8
Uncovered lines: 0
Coverable lines: 8
Total lines: 580
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_MessageType()100%11100%
get_PostingNumber()100%11100%
get_NewDeliveryDateBegin()100%11100%
get_NewDeliveryDateEnd()100%11100%
get_OldDeliveryDateBegin()100%11100%
get_OldDeliveryDateEnd()100%11100%
get_WarehouseId()100%11100%
get_SellerId()100%11100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/OzonWebhookServices/Models/OzonWebhookInputModels.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Text.Json.Serialization;
 4
 5namespace Services.OzonWebhookServices.Models
 6{
 7    // ─────────────────────────────────────────────────────────────────────────
 8    // Общие вложенные типы
 9    // ─────────────────────────────────────────────────────────────────────────
 10
 11    /// <summary>
 12    /// Товар из уведомления об отправлении (используется в TYPE_NEW_POSTING и TYPE_POSTING_CANCELLED).
 13    /// </summary>
 14    public sealed class OzonPostingProduct
 15    {
 16        /// <summary>Идентификатор товара в системе Ozon (SKU).</summary>
 17        [JsonPropertyName("sku")]
 18        public long Sku { get; init; }
 19
 20        /// <summary>Идентификатор товара в системе продавца (артикул). Присутствует только в TYPE_NEW_POSTING.</summary
 21        [JsonPropertyName("offer_id")]
 22        public string? OfferId { get; init; }
 23
 24        /// <summary>Количество товара.</summary>
 25        [JsonPropertyName("quantity")]
 26        public long Quantity { get; init; }
 27    }
 28
 29    /// <summary>
 30    /// Информация о причине отмены отправления.
 31    /// </summary>
 32    public sealed class OzonCancelReason
 33    {
 34        /// <summary>Идентификатор причины отмены.</summary>
 35        [JsonPropertyName("id")]
 36        public long Id { get; init; }
 37
 38        /// <summary>Текстовое описание причины отмены.</summary>
 39        [JsonPropertyName("reason")]
 40        public string? Message { get; init; }
 41    }
 42
 43    /// <summary>
 44    /// Остатки товара на конкретном складе.
 45    /// </summary>
 46    public sealed class OzonWarehouseStock
 47    {
 48        /// <summary>Идентификатор склада.</summary>
 49        [JsonPropertyName("warehouse_id")]
 50        public long WarehouseId { get; init; }
 51
 52        /// <summary>Общее количество на складе.</summary>
 53        [JsonPropertyName("present")]
 54        public long Present { get; init; }
 55
 56        /// <summary>Зарезервированное количество.</summary>
 57        [JsonPropertyName("reserved")]
 58        public long Reserved { get; init; }
 59    }
 60
 61    /// <summary>
 62    /// Элемент массива товаров в уведомлении об изменении остатков.
 63    /// </summary>
 64    public sealed class OzonStocksItem
 65    {
 66        /// <summary>Идентификатор товара в системе Ozon.</summary>
 67        [JsonPropertyName("product_id")]
 68        public long ProductId { get; init; }
 69
 70        /// <summary>SKU товара при работе по схемам FBS или rFBS.</summary>
 71        [JsonPropertyName("sku")]
 72        public long Sku { get; init; }
 73
 74        /// <summary>Дата и время изменения (UTC).</summary>
 75        [JsonPropertyName("updated_at")]
 76        public DateTime? UpdatedAt { get; init; }
 77
 78        /// <summary>Остатки по складам.</summary>
 79        [JsonPropertyName("stocks")]
 80        public List<OzonWarehouseStock> Stocks { get; init; } = new();
 81    }
 82
 83    /// <summary>
 84    /// Участник чата (покупатель, поддержка или Ozon).
 85    /// </summary>
 86    public sealed class OzonChatUser
 87    {
 88        /// <summary>Идентификатор пользователя.</summary>
 89        [JsonPropertyName("id")]
 90        public string Id { get; init; } = string.Empty;
 91
 92        /// <summary>
 93        /// Тип пользователя:
 94        /// Customer — покупатель,
 95        /// Support — поддержка,
 96        /// NotificationUser — Ozon.
 97        /// </summary>
 98        [JsonPropertyName("type")]
 99        public string Type { get; init; } = string.Empty;
 100    }
 101
 102    // ─────────────────────────────────────────────────────────────────────────
 103    // TYPE_PING
 104    // ─────────────────────────────────────────────────────────────────────────
 105
 106    /// <summary>
 107    /// Запрос TYPE_PING — проверка готовности сервиса.
 108    /// Отправляется при первичном подключении и периодически после него.
 109    /// </summary>
 110    public sealed class OzonPingRequest : IOzonWebhookMessage
 111    {
 112        /// <inheritdoc/>
 113        [JsonPropertyName("message_type")]
 114        public string MessageType { get; init; } = string.Empty;
 115
 116        /// <summary>Дата и время отправки проверочного запроса (UTC).</summary>
 117        [JsonPropertyName("time")]
 118        public DateTime Time { get; init; }
 119    }
 120
 121    // ─────────────────────────────────────────────────────────────────────────
 122    // TYPE_NEW_POSTING
 123    // ─────────────────────────────────────────────────────────────────────────
 124
 125    /// <summary>
 126    /// Уведомление о новом отправлении (только FBS и rFBS).
 127    /// Примечание: при поздней оплате поле InProcessAt может быть пустым.
 128    /// </summary>
 129    public sealed class OzonNewPostingNotification : IOzonWebhookMessage
 130    {
 131        /// <inheritdoc/>
 132        [JsonPropertyName("message_type")]
 133        public string MessageType { get; init; } = string.Empty;
 134
 135        /// <summary>Номер отправления.</summary>
 136        [JsonPropertyName("posting_number")]
 137        public string PostingNumber { get; init; } = string.Empty;
 138
 139        /// <summary>Товары в отправлении.</summary>
 140        [JsonPropertyName("products")]
 141        public List<OzonPostingProduct> Products { get; init; } = new();
 142
 143        /// <summary>Дата и время начала обработки отправления (UTC). Может быть null при поздней оплате.</summary>
 144        [JsonPropertyName("in_process_at")]
 145        public DateTime? InProcessAt { get; init; }
 146
 147        /// <summary>Идентификатор склада.</summary>
 148        [JsonPropertyName("warehouse_id")]
 149        public long WarehouseId { get; init; }
 150
 151        /// <summary>Дата и время, до которой необходимо собрать отправление.</summary>
 152        [JsonPropertyName("shipment_date")]
 153        public DateTime? ShipmentDate { get; init; }
 154
 155        /// <summary>
 156        /// Тип интеграции со службой доставки:
 157        /// ozon, 3pl_tracking, non_integrated, aggregator, hybryd.
 158        /// </summary>
 159        [JsonPropertyName("tpl_integration_type")]
 160        public string? TplIntegrationType { get; init; }
 161
 162        /// <summary>Признак доставки express.</summary>
 163        [JsonPropertyName("is_express")]
 164        public bool IsExpress { get; init; }
 165
 166        /// <summary>Трек-номер отправления.</summary>
 167        [JsonPropertyName("tracking_number")]
 168        public string? TrackingNumber { get; init; }
 169
 170        /// <summary>Дата и время начала доставки.</summary>
 171        [JsonPropertyName("delivery_date_begin")]
 172        public DateTime? DeliveryDateBegin { get; init; }
 173
 174        /// <summary>Дата и время конца доставки.</summary>
 175        [JsonPropertyName("delivery_date_end")]
 176        public DateTime? DeliveryDateEnd { get; init; }
 177
 178        /// <summary>Идентификатор продавца.</summary>
 179        [JsonPropertyName("seller_id")]
 180        public long SellerId { get; init; }
 181    }
 182
 183    // ─────────────────────────────────────────────────────────────────────────
 184    // TYPE_POSTING_CANCELLED
 185    // ─────────────────────────────────────────────────────────────────────────
 186
 187    /// <summary>
 188    /// Уведомление об отмене отправления (только FBS и rFBS).
 189    /// </summary>
 190    public sealed class OzonPostingCancelledNotification : IOzonWebhookMessage
 191    {
 192        /// <inheritdoc/>
 193        [JsonPropertyName("message_type")]
 194        public string MessageType { get; init; } = string.Empty;
 195
 196        /// <summary>Номер отправления.</summary>
 197        [JsonPropertyName("posting_number")]
 198        public string PostingNumber { get; init; } = string.Empty;
 199
 200        /// <summary>Товары в отправлении.</summary>
 201        [JsonPropertyName("products")]
 202        public List<OzonPostingProduct> Products { get; init; } = new();
 203
 204        /// <summary>Предыдущий статус отправления.</summary>
 205        [JsonPropertyName("old_state")]
 206        public string? OldState { get; init; }
 207
 208        /// <summary>Новый статус отправления (posting_canceled).</summary>
 209        [JsonPropertyName("new_state")]
 210        public string NewState { get; init; } = string.Empty;
 211
 212        /// <summary>Дата и время изменения статуса (UTC).</summary>
 213        [JsonPropertyName("changed_state_date")]
 214        public DateTime ChangedStateDate { get; init; }
 215
 216        /// <summary>Причина отмены.</summary>
 217        [JsonPropertyName("reason")]
 218        public OzonCancelReason? Reason { get; init; }
 219
 220        /// <summary>Идентификатор склада.</summary>
 221        [JsonPropertyName("warehouse_id")]
 222        public long WarehouseId { get; init; }
 223
 224        /// <summary>Идентификатор продавца.</summary>
 225        [JsonPropertyName("seller_id")]
 226        public long SellerId { get; init; }
 227    }
 228
 229    // ─────────────────────────────────────────────────────────────────────────
 230    // TYPE_STATE_CHANGED
 231    // ─────────────────────────────────────────────────────────────────────────
 232
 233    /// <summary>
 234    /// Уведомление об изменении статуса отправления (только FBS и rFBS).
 235    /// </summary>
 236    public sealed class OzonStateChangedNotification : IOzonWebhookMessage
 237    {
 238        /// <inheritdoc/>
 239        [JsonPropertyName("message_type")]
 240        public string MessageType { get; init; } = string.Empty;
 241
 242        /// <summary>Номер отправления.</summary>
 243        [JsonPropertyName("posting_number")]
 244        public string PostingNumber { get; init; } = string.Empty;
 245
 246        /// <summary>Новый статус отправления.</summary>
 247        [JsonPropertyName("new_state")]
 248        public string NewState { get; init; } = string.Empty;
 249
 250        /// <summary>Дата и время изменения статуса (UTC).</summary>
 251        [JsonPropertyName("changed_state_date")]
 252        public DateTime ChangedStateDate { get; init; }
 253
 254        /// <summary>Идентификатор склада.</summary>
 255        [JsonPropertyName("warehouse_id")]
 256        public long WarehouseId { get; init; }
 257
 258        /// <summary>Идентификатор продавца.</summary>
 259        [JsonPropertyName("seller_id")]
 260        public long SellerId { get; init; }
 261    }
 262
 263    // ─────────────────────────────────────────────────────────────────────────
 264    // TYPE_CUTOFF_DATE_CHANGED
 265    // ─────────────────────────────────────────────────────────────────────────
 266
 267    /// <summary>
 268    /// Уведомление об изменении даты отгрузки отправления.
 269    /// Внимание: поле NewCutoffDate может быть null из-за удаления интервала доставки.
 270    /// Работает в тестовом режиме. Рекомендуется проверять через POST /v3/posting/fbs/get.
 271    /// </summary>
 272    public sealed class OzonCutoffDateChangedNotification : IOzonWebhookMessage
 273    {
 274        /// <inheritdoc/>
 275        [JsonPropertyName("message_type")]
 276        public string MessageType { get; init; } = string.Empty;
 277
 278        /// <summary>Номер отправления.</summary>
 279        [JsonPropertyName("posting_number")]
 280        public string PostingNumber { get; init; } = string.Empty;
 281
 282        /// <summary>Новые дата и время отгрузки (UTC). Может быть null.</summary>
 283        [JsonPropertyName("new_cutoff_date")]
 284        public DateTime? NewCutoffDate { get; init; }
 285
 286        /// <summary>Предыдущие дата и время отгрузки (UTC).</summary>
 287        [JsonPropertyName("old_cutoff_date")]
 288        public DateTime? OldCutoffDate { get; init; }
 289
 290        /// <summary>Идентификатор склада.</summary>
 291        [JsonPropertyName("warehouse_id")]
 292        public long WarehouseId { get; init; }
 293
 294        /// <summary>Идентификатор продавца.</summary>
 295        [JsonPropertyName("seller_id")]
 296        public long SellerId { get; init; }
 297    }
 298
 299    // ─────────────────────────────────────────────────────────────────────────
 300    // TYPE_DELIVERY_DATE_CHANGED
 301    // ─────────────────────────────────────────────────────────────────────────
 302
 303    /// <summary>
 304    /// Уведомление об изменении даты доставки отправления (rFBS и FBS).
 305    /// Внимание: поля NewDeliveryDateBegin/End могут быть null из-за удаления интервала доставки.
 306    /// </summary>
 307    public sealed class OzonDeliveryDateChangedNotification : IOzonWebhookMessage
 308    {
 309        /// <inheritdoc/>
 310        [JsonPropertyName("message_type")]
 5311        public string MessageType { get; init; } = string.Empty;
 312
 313        /// <summary>Номер отправления.</summary>
 314        [JsonPropertyName("posting_number")]
 5315        public string PostingNumber { get; init; } = string.Empty;
 316
 317        /// <summary>Новые дата и время начала доставки (UTC). Может быть null.</summary>
 318        [JsonPropertyName("new_delivery_date_begin")]
 4319        public DateTime? NewDeliveryDateBegin { get; init; }
 320
 321        /// <summary>Новые дата и время окончания доставки (UTC). Может быть null.</summary>
 322        [JsonPropertyName("new_delivery_date_end")]
 4323        public DateTime? NewDeliveryDateEnd { get; init; }
 324
 325        /// <summary>Предыдущие дата и время начала доставки (UTC).</summary>
 326        [JsonPropertyName("old_delivery_date_begin")]
 3327        public DateTime? OldDeliveryDateBegin { get; init; }
 328
 329        /// <summary>Предыдущие дата и время окончания доставки (UTC).</summary>
 330        [JsonPropertyName("old_delivery_date_end")]
 3331        public DateTime? OldDeliveryDateEnd { get; init; }
 332
 333        /// <summary>Идентификатор склада.</summary>
 334        [JsonPropertyName("warehouse_id")]
 3335        public long WarehouseId { get; init; }
 336
 337        /// <summary>Идентификатор продавца.</summary>
 338        [JsonPropertyName("seller_id")]
 3339        public long SellerId { get; init; }
 340    }
 341
 342    // ─────────────────────────────────────────────────────────────────────────
 343    // TYPE_CREATE_OR_UPDATE_ITEM / TYPE_CREATE_ITEM / TYPE_UPDATE_ITEM
 344    // ─────────────────────────────────────────────────────────────────────────
 345
 346    /// <summary>
 347    /// Уведомление о создании или обновлении товара (TYPE_CREATE_OR_UPDATE_ITEM).
 348    /// Также используется для устаревших TYPE_CREATE_ITEM и TYPE_UPDATE_ITEM —
 349    /// у них идентичная структура payload.
 350    /// </summary>
 351    public sealed class OzonItemNotification : IOzonWebhookMessage
 352    {
 353        /// <inheritdoc/>
 354        [JsonPropertyName("message_type")]
 355        public string MessageType { get; init; } = string.Empty;
 356
 357        /// <summary>Идентификатор продавца.</summary>
 358        [JsonPropertyName("seller_id")]
 359        public long SellerId { get; init; }
 360
 361        /// <summary>Идентификатор товара в системе продавца (артикул).</summary>
 362        [JsonPropertyName("offer_id")]
 363        public string? OfferId { get; init; }
 364
 365        /// <summary>Идентификатор товара в системе Ozon (product_id).</summary>
 366        [JsonPropertyName("product_id")]
 367        public long ProductId { get; init; }
 368
 369        /// <summary>
 370        /// Признак, что при создании или обновлении товара возникли ошибки:
 371        /// true — ошибки есть, товар не создан/не обновлён;
 372        /// false — успешно.
 373        /// </summary>
 374        [JsonPropertyName("is_error")]
 375        public bool IsError { get; init; }
 376
 377        /// <summary>Дата и время изменения (UTC).</summary>
 378        [JsonPropertyName("changed_at")]
 379        public DateTime ChangedAt { get; init; }
 380    }
 381
 382    // ─────────────────────────────────────────────────────────────────────────
 383    // TYPE_STOCKS_CHANGED
 384    // ─────────────────────────────────────────────────────────────────────────
 385
 386    /// <summary>
 387    /// Уведомление об изменении остатков на складах продавца.
 388    /// </summary>
 389    public sealed class OzonStocksChangedNotification : IOzonWebhookMessage
 390    {
 391        /// <inheritdoc/>
 392        [JsonPropertyName("message_type")]
 393        public string MessageType { get; init; } = string.Empty;
 394
 395        /// <summary>Идентификатор продавца.</summary>
 396        [JsonPropertyName("seller_id")]
 397        public long SellerId { get; init; }
 398
 399        /// <summary>Массив товаров с изменёнными остатками.</summary>
 400        [JsonPropertyName("items")]
 401        public List<OzonStocksItem> Items { get; init; } = new();
 402    }
 403
 404    // ─────────────────────────────────────────────────────────────────────────
 405    // TYPE_NEW_MESSAGE
 406    // ─────────────────────────────────────────────────────────────────────────
 407
 408    /// <summary>
 409    /// Уведомление о новом сообщении в чате.
 410    /// </summary>
 411    public sealed class OzonNewMessageNotification : IOzonWebhookMessage
 412    {
 413        /// <inheritdoc/>
 414        [JsonPropertyName("message_type")]
 415        public string MessageType { get; init; } = string.Empty;
 416
 417        /// <summary>Идентификатор чата.</summary>
 418        [JsonPropertyName("chat_id")]
 419        public string ChatId { get; init; } = string.Empty;
 420
 421        /// <summary>
 422        /// Тип чата: Seller_Support, Buyer_Seller или Seller_Notification.
 423        /// </summary>
 424        [JsonPropertyName("chat_type")]
 425        public string ChatType { get; init; } = string.Empty;
 426
 427        /// <summary>Идентификатор сообщения.</summary>
 428        [JsonPropertyName("message_id")]
 429        public string MessageId { get; init; } = string.Empty;
 430
 431        /// <summary>Дата создания сообщения (UTC).</summary>
 432        [JsonPropertyName("created_at")]
 433        public DateTime CreatedAt { get; init; }
 434
 435        /// <summary>Информация об отправителе.</summary>
 436        [JsonPropertyName("user")]
 437        public OzonChatUser? User { get; init; }
 438
 439        /// <summary>Содержимое сообщения в формате Markdown (массив строк).</summary>
 440        [JsonPropertyName("data")]
 441        public List<string> Data { get; init; } = new();
 442
 443        /// <summary>Идентификатор продавца.</summary>
 444        [JsonPropertyName("seller_id")]
 445        public long SellerId { get; init; }
 446    }
 447
 448    // ─────────────────────────────────────────────────────────────────────────
 449    // TYPE_UPDATE_MESSAGE
 450    // ─────────────────────────────────────────────────────────────────────────
 451
 452    /// <summary>
 453    /// Уведомление об изменении сообщения в чате.
 454    /// </summary>
 455    public sealed class OzonUpdateMessageNotification : IOzonWebhookMessage
 456    {
 457        /// <inheritdoc/>
 458        [JsonPropertyName("message_type")]
 459        public string MessageType { get; init; } = string.Empty;
 460
 461        /// <summary>Идентификатор чата.</summary>
 462        [JsonPropertyName("chat_id")]
 463        public string ChatId { get; init; } = string.Empty;
 464
 465        /// <summary>Тип чата: Seller_Support, Buyer_Seller или Seller_Notification.</summary>
 466        [JsonPropertyName("chat_type")]
 467        public string ChatType { get; init; } = string.Empty;
 468
 469        /// <summary>Идентификатор сообщения.</summary>
 470        [JsonPropertyName("message_id")]
 471        public string MessageId { get; init; } = string.Empty;
 472
 473        /// <summary>Дата создания сообщения (UTC).</summary>
 474        [JsonPropertyName("created_at")]
 475        public DateTime CreatedAt { get; init; }
 476
 477        /// <summary>Дата изменения сообщения (UTC).</summary>
 478        [JsonPropertyName("updated_at")]
 479        public DateTime UpdatedAt { get; init; }
 480
 481        /// <summary>Информация об отправителе.</summary>
 482        [JsonPropertyName("user")]
 483        public OzonChatUser? User { get; init; }
 484
 485        /// <summary>Содержимое изменённого сообщения в формате Markdown.</summary>
 486        [JsonPropertyName("data")]
 487        public List<string> Data { get; init; } = new();
 488
 489        /// <summary>Идентификатор продавца.</summary>
 490        [JsonPropertyName("seller_id")]
 491        public long SellerId { get; init; }
 492    }
 493
 494    // ─────────────────────────────────────────────────────────────────────────
 495    // TYPE_MESSAGE_READ
 496    // ─────────────────────────────────────────────────────────────────────────
 497
 498    /// <summary>
 499    /// Уведомление о том, что сообщение продавца прочитано покупателем или поддержкой.
 500    /// </summary>
 501    public sealed class OzonMessageReadNotification : IOzonWebhookMessage
 502    {
 503        /// <inheritdoc/>
 504        [JsonPropertyName("message_type")]
 505        public string MessageType { get; init; } = string.Empty;
 506
 507        /// <summary>Идентификатор чата.</summary>
 508        [JsonPropertyName("chat_id")]
 509        public string ChatId { get; init; } = string.Empty;
 510
 511        /// <summary>Тип чата: Seller_Support, Buyer_Seller или Seller_Notification.</summary>
 512        [JsonPropertyName("chat_type")]
 513        public string ChatType { get; init; } = string.Empty;
 514
 515        /// <summary>Идентификатор сообщения.</summary>
 516        [JsonPropertyName("message_id")]
 517        public string MessageId { get; init; } = string.Empty;
 518
 519        /// <summary>Дата создания сообщения (UTC).</summary>
 520        [JsonPropertyName("created_at")]
 521        public DateTime CreatedAt { get; init; }
 522
 523        /// <summary>Информация о пользователе, прочитавшем сообщение.</summary>
 524        [JsonPropertyName("user")]
 525        public OzonChatUser? User { get; init; }
 526
 527        /// <summary>Идентификатор последнего прочитанного сообщения.</summary>
 528        [JsonPropertyName("last_read_message_id")]
 529        public string? LastReadMessageId { get; init; }
 530
 531        /// <summary>Идентификатор продавца.</summary>
 532        [JsonPropertyName("seller_id")]
 533        public long SellerId { get; init; }
 534    }
 535
 536    // ─────────────────────────────────────────────────────────────────────────
 537    // TYPE_CHAT_CLOSED
 538    // ─────────────────────────────────────────────────────────────────────────
 539
 540    /// <summary>
 541    /// Уведомление о закрытии чата.
 542    /// </summary>
 543    public sealed class OzonChatClosedNotification : IOzonWebhookMessage
 544    {
 545        /// <inheritdoc/>
 546        [JsonPropertyName("message_type")]
 547        public string MessageType { get; init; } = string.Empty;
 548
 549        /// <summary>Идентификатор чата.</summary>
 550        [JsonPropertyName("chat_id")]
 551        public string ChatId { get; init; } = string.Empty;
 552
 553        /// <summary>Тип чата: Seller_Support, Buyer_Seller или Seller_Notification.</summary>
 554        [JsonPropertyName("chat_type")]
 555        public string ChatType { get; init; } = string.Empty;
 556
 557        /// <summary>Информация о пользователе, закрывшем чат.</summary>
 558        [JsonPropertyName("user")]
 559        public OzonChatUser? User { get; init; }
 560
 561        /// <summary>Идентификатор продавца.</summary>
 562        [JsonPropertyName("seller_id")]
 563        public long SellerId { get; init; }
 564    }
 565
 566    // ─────────────────────────────────────────────────────────────────────────
 567    // Fallback для неизвестных типов
 568    // ─────────────────────────────────────────────────────────────────────────
 569
 570    /// <summary>
 571    /// Обёртка для неизвестного или нераспознанного типа уведомления.
 572    /// Позволяет сохранить payload и не потерять данные при появлении новых типов от Ozon.
 573    /// </summary>
 574    public sealed class OzonUnknownNotification : IOzonWebhookMessage
 575    {
 576        /// <inheritdoc/>
 577        [JsonPropertyName("message_type")]
 578        public string MessageType { get; init; } = string.Empty;
 579    }
 580}