Подключение по схеме FBS
Особенности работы с заказами, отгрузками и складами витрины.
FBS (Fulfillment by Seller) – схема, при которой продавец собирает клиентские заказы на своем складе и передаёт их на склады маркетплейса для дальнейшей доставки. Маркетплейс предоставляет список своих складов (фулфилмент-центров), доступных для приёмки товаров.
Введение
Участники
| Мерчант | Продавец — хранит товары на своём складе, собирает заказы, упаковывает их в грузоместа и передаёт на склад витрины (FBS). |
|---|---|
| API | FBS Seller API — REST-интерфейс (POST JSON). |
| Витрина | Бэкенд маркетплейса — назначает склад витрины для сдачи, обрабатывает статусы отгрузок и заказов, управляет логикой приёмки. |
Константы примеров
| Склад мерчанта | merchant_location_id: "wh-msk-01" |
|---|---|
| Склад витрины | market_location_id: "koledino" (Коледино) |
| Отгрузка | shipment_id: SHP-FBS-2026-101 |
| Заказы | ORD-FBS-2026-001, ORD-FBS-2026-002 |
| Дата отгрузки | 2026-07-15 |
В FBS заказы собираются на складе мерчанта и передаются отгрузками на склад витрины. Отгрузка всегда едет целиком в одной машине, не разделяется на несколько транспортных средств. В составе отгрузки — грузоместа (короба или паллеты), в каждом грузоместе — один или несколько заказов. Заказы без грузомест не отгружаются. Важно: один заказ всегда соответствует одному товару; несколько товаров в одном заказе не допускаются.
Сценарий 0: Подготовка инфраструктуры FBS
До поступления заказов мерчант настраивает свой склад, подключает его к складу витрины, загружает остатки и цены.
Пошаговое описание
- Создание склада мерчанта. POST
/v1/merchant/location/create— локация типаWAREHOUSE. В ответе —location_id. Статус отслеживается черезmerchant/location/list. - Получение списка складов витрины. POST
/v1/market/location/list— выбираем доступный фулфилмент-центр (например,koledino). - Привязка склада мерчанта к складу витрины. При создании склада мерчанта или обновлении через
merchant/location/updateпередаётся массивmarket_location_id— указываем, к каким складам витрины будет подключаться склад мерчанта. - Загрузка остатков. POST
/v1/product/stock/update— актуальное количество товаров на складе мерчанта. Текущие остатки — POST/v1/product/stock/info. - Загрузка цен. POST
/v1/product/price/update— цены товаров. Текущие цены — POST/v1/product/price/info.
После привязки склада мерчанта к складу витрины на витрине появляется возможность оформлять заказы FBS с указанием этого склада мерчанта. Склад можно архивировать через POST
/v1/merchant/location/archive.
JSON-примеры
Шаг 1 — POST /v1/merchant/location/create
{
"locations": [{
"merchant_location_id": "wh-msk-01",
"location_types": "WAREHOUSE",
"name": "Склад мерчанта Москва",
"address_tail": "125009, г. Москва, ул. Тверская, д. 1",
"latitude": 55.7558,
"longitude": 37.6173,
"working_schedule": [
{ "day": "MONDAY", "schedule": { "time_start": "09:00", "time_end": "18:00" } }
],
"market_location_id": ["koledino"]
}]
}
{
"locations": [
{
"location_id": "loc-123",
"merchant_location_id": "wh-msk-01",
"name": "Склад мерчанта Москва",
"status": "PENDING"
}
]
}
Шаг 2 — POST /v1/market/location/list
{
"filter": { "is_active": true },
"cursor": "",
"limit": 100
}
{
"locations": [{
"market_location_id": "koledino",
"name": "Коледино",
"city": "Москва",
"is_active": true,
"shipment_limits": { "accepts_standard": true }
}]
}
Шаг 4 — POST /v1/product/stock/update
{
"items": [
{ "offer_id": "PHONE-001", "product_id": "PRD-PHONE-01", "location_id": "wh-msk-01", "count": 50 }
]
}
{
"failed": []
}
Шаг 5 — POST /v1/product/price/update
{
"items": [
{ "offer_id": "PHONE-001", "product_id": "PRD-PHONE-01", "price": 1999900, "old_price": 2499900, "vat": "VAT_22" }
],
"currency": "RUB"
}
{
"failed": []
}
Сценарий 1: Полный happy path (сборка и отгрузка на склад витрины)
Мерчант получает заказы ORD-FBS-2026-001 и ORD-FBS-2026-002 в статусе NEW на складе мерчанта wh-msk-01. Склад витрины для сдачи — koledino, дата отгрузки 2026-07-15. Мерчант подтверждает, собирает, упаковывает, печатает этикетки, оформляет пропуск и передаёт отгрузку.
Диаграмма последовательности
Пошаговое описание (1–12)
- Опрос обновлений заказов. POST
/v1/order/fbs/status/list— получаем новые заказы в статусеNEW. - Карточка заказа. POST
/v1/order/fbs/list— детали: состав, адрес доставки,requirements(требования к маркировке),market_location_id(склад витрины для сдачи). - Подтверждение заказа. POST
/v1/order/fbs/status/update→ CONFIRMED,changed_by: "MERCHANT". - Передача экземпляров. POST
/v1/order/fbs/exemplar/set— для каждого заказа передаём массивexemplarsс маркировкой (IMEI, «Честный знак», ГТД и т.д.) согласноrequirements. - Готовность к отгрузке. POST
/v1/order/fbs/status/update→ READY_TO_SHIP. Заказ собран и упакован (на уровне товаров). - Создание отгрузки. POST
/v1/shipment/create— указываемmarket_location_id(куда везём),shipment_dateиpackages(список грузомест сmerchant_order_ids). Метод не учитывает внутрискладские процессы; он используется после фактической сборки заказов и формирования грузомест. Передаётся весь набор заказов, уже рассортированных по грузоместам. Можно создать отгрузку без грузомест, а затем добавить их черезpackage/add. - Этикетки заказов. POST
/v1/order/fbs/labels/get— файл с этикетками для каждого заказа (стикеры на товары). Формат может быть любым (PDF, ZPL, PNG и т.д.) в зависимости от настроек. Печатаем и наклеиваем на товары. - Этикетки грузомест. POST
/v1/label/fbs/packages/get— этикетки для указанныхpackage_id. Наклеиваем на короба/паллеты. - Пропуск. POST
/v1/shipment/pass/update— передаём данные водителя и ТС для въезда на склад витрины. Можно указать несколькоshipment_idsдля одной машины. - Статус отгрузки READY. POST
/v1/shipment/fbs/status/update→READY— отгрузка готова к отправке. - Статус IN_TRANSIT. POST
/v1/shipment/fbs/status/update→IN_TRANSIT— машина выехала на склад витрины. - Мониторинг приёмки. POST
/v1/shipment/getилиshipment/list— отслеживаем статусыACCEPTED_AT_GATE(принята на воротах),PARTIALLY_ACCEPTED(частично) иACCEPTED(полностью). Витрина автоматически меняет статусы по мере приёмки.
Отгрузка может быть создана и без грузомест (пустая), затем грузоместа добавляются через
package/add. Статус отгрузкиCANCELLEDустанавливается только черезshipment/cancel, не черезshipment/fbs/status/update. Отмена доступна только из статусовDRAFTилиREADY(до отправки в путь). Отмена не расформировывает грузоместа и не меняет их статус.
Порядок маркировки и сборки на складе
┌─────────────────────────────────────────────────────────────┐
│ 1. Заказы подтверждены (CONFIRMED) │
│ 2. API: exemplar/set — передать IMEI/маркировку на каждый │
│ 3. API: status/update → READY_TO_SHIP │
│ 4. API: order/fbs/labels/get → стикеры на товары │
│ 5. НАКЛЕИТЬ стикер на каждый товар (или на его упаковку) │
│ 6. Рассортировать товары по грузоместам (короба/паллеты) │
│ 7. API: shipment/create или package/add — создать ГМ │
│ 8. API: label/fbs/packages/get → этикетки на ГМ │
│ 9. НАКЛЕИТЬ этикетку на каждое грузоместо │
│ 10. (опц.) API: label/fbs/shipment/get → документ отгрузки │
│ 11. API: pass/update — пропуск на водителя │
│ 12. API: status/update → READY → IN_TRANSIT │
│ 13. Ожидать приёмки на складе витрины │
└─────────────────────────────────────────────────────────────┘
Порядок действий может варьироваться в зависимости от типа товара (крупный/мелкий) и внутренних процессов склада. Главное — этикетка заказа должна быть на товаре (или его упаковке) до того, как он попадёт в грузоместо.
JSON-примеры
Шаг 1 — POST /v1/order/fbs/status/list
{
"filter": {
"status": ["NEW"],
"updated_since": "2026-07-14T00:00:00+03:00"
},
"cursor": "",
"limit": 100
}
{
"order_updates": [
{
"merchant_order_id": "ORD-FBS-2026-001",
"client_order_id": "CLT-1001",
"status": "NEW",
"updated_at": "2026-07-14T10:00:00+03:00"
}
],
"next_cursor": ""
}
Шаг 2 — POST /v1/order/fbs/list
{
"filter": {
"merchant_order_id": ["ORD-FBS-2026-001"]
},
"cursor": "",
"limit": 100
}
{
"orders": [{
"merchant_order_id": "ORD-FBS-2026-001",
"client_order_id": "CLT-1001",
"merchant_location_id": "wh-msk-01",
"market_location_id": "koledino",
"shipment_date": "2026-07-15",
"status": "NEW",
"delivery": { "delivery_type": "COURIER", "address_tail": "..." },
"product_id": "PRD-PHONE-01",
"offer_id": "PHONE-001",
"requirements": { "requires_imei": true }
}]
}
Шаг 3 — POST /v1/order/fbs/status/update (CONFIRMED)
{
"merchant_order_id": "ORD-FBS-2026-001",
"status": "CONFIRMED",
"changed_at": "2026-07-14T10:05:00+03:00",
"changed_by": "MERCHANT",
"comment": "Принят в работу"
}
{}
Шаг 4 — POST /v1/order/fbs/exemplar/set
{
"merchant_order_id": "ORD-FBS-2026-001",
"product_id": "PRD-PHONE-01",
"offer_id": "PHONE-001",
"exemplars": [{
"exemplar_id": 1,
"marks": [{ "mark": "35693803564341", "mark_type": "imei" }],
"weight": 0.22
}]
}
{}
Шаг 5 — POST /v1/order/fbs/status/update (READY_TO_SHIP)
{
"merchant_order_id": "ORD-FBS-2026-001",
"status": "READY_TO_SHIP",
"changed_at": "2026-07-14T11:00:00+03:00",
"changed_by": "MERCHANT"
}
{}
Шаг 6 — POST /v1/shipment/create
{
"market_location_id": "koledino",
"shipment_date": "2026-07-15",
"packages": [
{
"package_number": 1,
"type": "BOX",
"merchant_order_ids": ["ORD-FBS-2026-001", "ORD-FBS-2026-002"]
},
{
"package_number": 2,
"type": "PALLET",
"merchant_order_ids": ["ORD-FBS-2026-003"]
}
],
"idempotency_key": "create-shp-2026-07-15-001"
}
{
"shipment_id": "SHP-FBS-2026-101",
"packages": [
{ "package_id": "PKG-001", "package_number": 1, "type": "BOX", "merchant_order_ids": ["ORD-FBS-2026-001", "ORD-FBS-2026-002"] },
{ "package_id": "PKG-002", "package_number": 2, "type": "PALLET", "merchant_order_ids": ["ORD-FBS-2026-003"] }
]
}
Шаг 7 — POST /v1/order/fbs/labels/get
{
"merchant_order_id": ["ORD-FBS-2026-001", "ORD-FBS-2026-002"],
"format": "PDF"
}
{
"labels": [
{
"merchant_order_id": "ORD-FBS-2026-001",
"client_order_id": "CLT-1001",
"file_name": "label_ORD-FBS-2026-001.pdf",
"content_base64": "JVBERi0xLjQK...",
"content_type": "application/pdf"
}
],
"failed": []
}
Шаг 8 — POST /v1/label/fbs/packages/get
{
"shipment_id": "SHP-FBS-2026-101",
"package_ids": ["PKG-001", "PKG-002"],
"format": "PDF",
"size": "SIZE_100x150"
}
{
"labels": [
{
"package_id": "PKG-001",
"label": { "format": "PDF", "content_base64": "..." }
}
],
"failed": []
}
Шаг 9 — POST /v1/shipment/pass/update
{
"shipment_ids": ["SHP-FBS-2026-101"],
"vehicle": {
"driver_name": "Иванов Иван Иванович",
"driver_phone": "+79001234567",
"vehicle_model": "ГАЗель NEXT",
"vehicle_plate": "А123ВС777"
},
"idempotency_key": "pass-2026-07-15-001"
}
{}
Шаг 10–11 — POST /v1/shipment/fbs/status/update (READY → IN_TRANSIT)
{
"shipment_id": "SHP-FBS-2026-101",
"status": "READY",
"changed_at": "2026-07-15T08:00:00+03:00",
"changed_by": "MERCHANT"
}
{}
{
"shipment_id": "SHP-FBS-2026-101",
"status": "IN_TRANSIT",
"changed_at": "2026-07-15T09:00:00+03:00",
"changed_by": "MERCHANT"
}
{}
Шаг 12 — POST /v1/shipment/get (мониторинг)
{
"shipment_id": "SHP-FBS-2026-101"
}
{
"shipment_id": "SHP-FBS-2026-101",
"market_location_id": "koledino",
"status": "ACCEPTED",
"accepted_qty_packages": 2,
"planned_qty_packages": 2
}
Сценарий 2: Отмена отгрузки
Отгрузку можно отменить только в статусах DRAFT или READY через POST /v1/shipment/cancel. После перехода в IN_TRANSIT и далее отмена недоступна.
- Мерчант создал отгрузку (DRAFT) или перевёл в READY.
- По каким-то причинам отгрузка не состоится.
- POST
/v1/shipment/cancelс обязательными полями:shipment_id,reason,cancelled_by,idempotency_key. - Статус отгрузки становится CANCELLED.
Отмена отгрузки не отменяет автоматически заказы внутри неё. Заказы остаются в статусе
READY_TO_SHIPилиCONFIRMEDи могут быть включены в другую отгрузку. Грузоместа при отмене не расформировываются и не меняют свой статус — они просто остаются в отменённой отгрузке.
JSON — POST /v1/shipment/cancel
{
"shipment_id": "SHP-FBS-2026-101",
"reason": "Невозможно отправить в указанную дату",
"cancelled_by": "MERCHANT",
"idempotency_key": "cancel-shp-101-001"
}
{}
Сценарий 3: Отмена заказа продавцом
Мерчант может отменить заказ вручную через POST /v1/order/fbs/cancel до тех пор, пока заказ не перешёл в статус SHIPPED (отгружен).
- Заказ в статусе
NEW,CONFIRMEDилиREADY_TO_SHIP. - Мерчант отправляет запрос с
merchant_order_id,reason_code,reason_comment,changed_at. - Статус заказа меняется на CANCELLED.
JSON — POST /v1/order/fbs/cancel
{
"merchant_order_id": "ORD-FBS-2026-001",
"reason_code": "OUT_OF_STOCK",
"reason_comment": "Товар закончился на складе",
"changed_at": "2026-07-14T12:00:00+03:00"
}
{ "success": true }
Статусы и ключевые правила
Статусы заказа FBS
| NEW | Новый заказ, ожидает подтверждения |
|---|---|
| CONFIRMED | Подтверждён продавцом, можно собирать |
| READY_TO_SHIP | Собран и упакован, готов к включению в отгрузку |
| SHIPPED | Отгружен (включён в отгрузку, которая перешла в статус READY или выше) |
| ACCEPTED_AT_WAREHOUSE | Принят на складе витрины |
| DELIVERED | Доставлен покупателю |
| CANCELLED | Отменён (через order/fbs/cancel) |
Статусы отгрузки FBS
| DRAFT | Черновик, можно изменять состав, добавлять/удалять грузоместа, отменить |
|---|---|
| READY | Готова к отправке, можно изменить пропуск, перевести в IN_TRANSIT или отменить |
| IN_TRANSIT | В пути на склад витрины, отмена недоступна |
| ACCEPTED_AT_GATE | Принята на воротах склада (автоматически от витрины) |
| PARTIALLY_ACCEPTED | Частично принята (принято меньше грузомест, чем заявлено) |
| ACCEPTED | Полностью принята |
| CANCELLED | Отменена (только через shipment/cancel из DRAFT или READY) |
State machine отгрузки FBS
| Из | В | Кто инициирует | Метод |
|---|---|---|---|
| — | DRAFT | MERCHANT | shipment/create |
| DRAFT | DRAFT (обновление) | MERCHANT | shipment/update, package/add, package/remove, pass/update |
| DRAFT | READY | MERCHANT | shipment/fbs/status/update |
| DRAFT | CANCELLED | MERCHANT | shipment/cancel |
| READY | IN_TRANSIT | MERCHANT | shipment/fbs/status/update |
| READY | CANCELLED | MERCHANT | shipment/cancel |
| IN_TRANSIT | ACCEPTED_AT_GATE | Витрина | (автоматически) |
| ACCEPTED_AT_GATE | PARTIALLY_ACCEPTED | Витрина | (автоматически) |
| ACCEPTED_AT_GATE | ACCEPTED | Витрина | (автоматически) |
| PARTIALLY_ACCEPTED | ACCEPTED | Витрина | (при дозачёте) |
| CANCELLED | — | — | Терминальный статус |
| ACCEPTED | — | — | Терминальный статус |
Статус
CANCELLEDне может быть установлен черезshipment/fbs/status/update, только черезshipment/cancel.
Сценарии приёмки на складе витрины
При прибытии отгрузки на склад витрины статусы обновляются автоматически в зависимости от результатов приёмки:
1. Отгрузка прибыла на ворота
| Сущность | Статус |
|---|---|
| Отгрузка | ACCEPTED_AT_GATE |
| Грузоместа | PLANNED (ожидают осмотра) |
| Заказы | SHIPPED (уже отгружены) |
2. Часть грузомест принята, часть отклонена
| Сущность | Статус |
|---|---|
| Отгрузка | PARTIALLY_ACCEPTED (если принято хотя бы одно грузоместо) |
| Принятые грузоместа | ACCEPTED |
| Отклонённые грузоместа | REJECTED |
| Ненайденные грузоместа | PLANNED |
| Заказы в принятых грузоместах | SHIPPED (позже станут ACCEPTED_AT_WAREHOUSE после вскрытия грузомест) |
| Заказы в отклонённых/ненайденных грузоместах | SHIPPED (остаются в этом статусе, возвращаются мерчанту) |
3. Ни одного грузоместа не принято
| Сущность | Статус |
|---|---|
| Отгрузка | IN_TRANSIT (остаётся, но фактически возвращается) |
| Грузоместа | REJECTED или PLANNED |
| Заказы | SHIPPED |
4. После вскрытия грузомест (внутренняя приёмка)
| Сущность | Статус |
|---|---|
| Товары, принятые витриной | ACCEPTED_AT_WAREHOUSE |
| Товары, не принятые или не найденные | SHIPPED |
| Отгрузка (если не все заказы приняты) | PARTIALLY_ACCEPTED |
| Отгрузка (если все заказы приняты) | ACCEPTED |
5. Особые случаи
- Заказы, которые сразу возвращаются (не приняты на воротах): отгрузка остаётся
PARTIALLY_ACCEPTED,ACCEPTED_AT_GATEилиIN_TRANSIT, грузоместа —REJECTED, заказы —SHIPPED. - Заказы, возвращаемые со склада после внутренней приёмки: отгрузка —
PARTIALLY_ACCEPTED, грузоместа —ACCEPTED, заказы —SHIPPED.
Витрина автоматически обновляет статусы; мерчант отслеживает их через
shipment/getиorder/fbs/list.
Ключевые правила интеграции FBS
| Склады | Два типа: merchant/location (склад мерчанта) и market/location (склад витрины). Привязка через market_location_id при создании/обновлении склада мерчанта. Архивация — merchant/location/archive. |
|---|---|
| Остатки и цены | Запись: product/stock/update, product/price/update. Чтение: product/stock/info, product/price/info. |
| Заказы | Один заказ = один товар. Заказы собираются в грузоместа (короба/паллеты), в одном грузоместе может быть несколько заказов. |
| Отгрузка | Создаётся в DRAFT, содержит грузоместа (packages) с типом BOX/PALLET. Состав изменяется только в DRAFT (shipment/update, package/add, package/remove). Отгрузка всегда едет целиком в одной машине, не разделяется. |
| Грузоместа | В отгрузку обязательно должны входить грузоместа, в каждом грузоместе — один или несколько заказов. Заказы без грузомест не отгружаются. |
| Валидация витриной | При создании и обновлении отгрузки витрина проверяет, что заказы не привязаны более чем к одному грузоместу и одной отгрузке, а грузоместа не привязаны более чем к одной отгрузке. |
| Этикетки | Три вида: на заказы (order/fbs/labels/get), на грузоместа (label/fbs/packages/get), на всю отгрузку (label/fbs/shipment/get). Формат может быть любым (PDF, ZPL, PNG и т.д.). |
| Пропуск | Обновляется через shipment/pass/update для одной или нескольких отгрузок, статус отгрузки должен быть DRAFT, READY или IN_TRANSIT. |
| Статус заказа | Мерчант может менять через order/fbs/status/update на CONFIRMED, READY_TO_SHIP, SHIPPED, CANCELLED (но CANCELLED лучше через отдельный метод order/fbs/cancel). |
| Отмена заказа | order/fbs/cancel — обязательны reason_code и reason_comment. |
| Отмена отгрузки | Только из DRAFT или READY, не расформировывает грузоместа. |
| Идемпотентность | Методы shipment/create, shipment/cancel, pass/update поддерживают idempotency_key. |
Полный справочник методов FBS
Все методы FBS с детальными параметрами и ответами доступны в разделе API Reference FBS.