ТЗ: імпорт замовлень у 1С із хмарного проксі

Технічне завдання · інтеграція замовлень із 1С
Статусузгоджено із замовником, готується до передачі розробникам 1С
Конфігурація 1СУТП (Управління торговельним підприємством)
Напрямокхмарний проксі (Cloud Run) → вебсервіс 1С, метод POST, тіло JSON
Версія контракту1.0

1. Загальна схема

Замовлення із сайту kohani.com.ua (Horoshop), із CRM KeyCRM і в майбутньому з бота спочатку

потрапляють у хмарний проксі. Проксі приводить їх до єдиного вигляду й одним запитом надсилає

в 1С. 1С не знає про особливості систем-джерел — він отримує один нормалізований контракт.

Сайт · Horoshop CRM · KeyCRM Бот (у майбутньому) Хмарний проксі нормалізація POST JSON Вебсервіс 1С Замовлення покупця проводиться → резерв відповідь: номер · дата · GUID замовлення 1С

Що 1С робить із замовленням:

2. Транспорт і авторизація

ПараметрЗначення
МетодPOST
Content-Typeapplication/json; charset=utf-8
КодуванняUTF-8
АвторизаціяТокен у HTTP-заголовку X-Auth-Token. 1С перевіряє його на кожному запиті. Значення токена узгоджується з розробником 1С; на боці проксі зберігається в секретах Cloud Run
ТранспортHTTPS (можливий HTTP у захищеному контурі)
Без авторизації401, замовлення не створюється

зобовʼязаний повернути JSON-відповідь за §6 (і при успіху, і при помилці).

3. Ідемпотентність і дедуплікація замовлень

Проксі може надіслати одне й те саме замовлення повторно (повтор при таймауті/обриві звʼязку).

Дублі неприпустимі.

поля (зберігає в замовленні, може знадобитися для майбутніх оновлень оплати).

чи немає вже замовлення з такою парою. Є → не створює нове, повертає наявне (номер, дату,

GUID) зі status: duplicate.

4. Бізнес-правила на боці 1С

  1. Дедуплікація замовлення — за source + external_number (§3).
  2. Дедуплікація контрагента — за нормалізованим телефоном (основний ключ; 1С нормалізує

сама, ми надсилаємо міжнародний формат). Email — вторинна підказка для збагачення картки.

**Перед запуском автоматизації розробники 1С проводять разову процедуру дедуплікації наявних

контрагентів**, щоб автостворення не плодило дублі поверх «брудної» бази.

  1. Резерв — замовлення завжди проводиться, товар резервується. Склад резерву обирає 1С за

наявністю (уточнюється при узгодженні контракту; проксі за потреби може запитати в 1С наявність

перед створенням замовлення).

  1. Суми — 1С приймає price / sum / total як є, не перераховує (джерело істини щодо

грошей — проксі: клієнт стільки заплатив). При розбіжності total і суми рядків — повертає

warning, але замовлення створює.

  1. Реалізація — не створюється автоматично (окреме завдання).

5. Структура вхідного JSON

Повний приклад — §7. Обовʼязковість: О — обовʼязково, Н — необовʼязково.

5.1. Шапка

ПолеТипОб.Опис
sourceenumОkeycrm | horoshop | bot (довідково + ключ дедуплікації)
external_numberstringОНомер замовлення в джерелі (довідково + ключ дедуплікації)
external_created_atstring (ISO-8601, UTC)ОКоли замовлення створено в джерелі
fopstring (код 1С)ОКод активного ФОПа, від імені якого створюється замовлення. 1С за ним сама підтягує банківський рахунок, Організацію ЕН, організацію НП та її ключ
price_typestring (код 1С)ОКод типу ціни номенклатури. Роздріб = 000000001 («Роздрібні»). Один на замовлення. Валюту 1С виводить із типу ціни
commentstringНКоментар клієнта/менеджера → поле «Коментар» замовлення

5.2. Контрагент (customer) — замовник/платник

Лише фізособи. Надсилаємо завжди.

ПолеТипОб.Опис
customer.full_namestringОПІБ
customer.phonestringОТелефон, міжнародний формат +380XXXXXXXXX
customer.emailstringНEmail (вторинний ключ, збагачення картки)

5.3. Отримувач (recipient)

Надсилаємо завжди повним блоком, навіть якщо збігається з контрагентом (1С не розгалужується).

ПолеТипОб.Опис
recipient.full_namestringОПІБ отримувача
recipient.phonestringОТелефон отримувача, міжнародний формат

5.4. Доставка (delivery)

Отримувач НП — завжди «Приватна особа». Міста/відділення/вулиці НП передаємо парою `ref` + назва

(API НП вимагає звʼязку). Підтримуються всі види доставки з довідника 1С.

ПолеТипОб.Опис
delivery.carrierstringОПеревізник; на старті nova_poshta
delivery.typestring (код 1С)ОКод «Виду доставки» 1С: Склад-склад / Склад-двері / Склад-поштомат тощо
delivery.city_refstring (guid НП)ОGUID населеного пункту (CityRef/SettlementRef)
delivery.city_namestringОНазва міста (обовʼязково в парі з ref)
delivery.warehouse_refstring (guid НП)Н*GUID відділення/поштомата (WarehouseRef). *Для Склад-склад/Склад-поштомат
delivery.warehouse_namestringН*Назва відділення/поштомата (у парі з ref)
delivery.street_refstring (guid НП)Н**GUID вулиці (StreetRef). **Для адресної доставки
delivery.street_namestringН**Назва вулиці (у парі з ref)
delivery.buildingstringН**Будинок
delivery.flatstringНКвартира
delivery.declared_valuenumberООголошена (оцінна) вартість = сума товарів
delivery.cod_amountnumberОКонтроль оплати (накладений платіж) = сума товарів − передоплата. Повна передоплата → 0
delivery.cargo_descriptionstringООпис вантажу («взуття»/«одяг»…). Проксі визначає за розділом каталогу
Константи (НЕ в контракті, проставляються 1С за замовчуванням): тип вантажу «Посилка», платник доставки «Отримувач», форма оплати НП «Готівка» (клієнт платить у відділенні готівкою/карткою), вага й габарити місць (заповнює 1С за шаблоном).

5.5. Оплата (payment)

ПолеТипОб.Опис
payment.methodstring (код 1С)ОКод «Способу оплати» 1С (накладений платіж / передоплата / …). Вибір клієнта; ФОП не визначає
payment.channelstringНПлатіжна система/канал (LiqPay, Mono, NovaPay…) — для бухгалтерії/аналітики. 1С поки може ігнорувати, пізніше звʼяже з платіжними терміналами
payment.statusenumОpaid | unpaid | partially_paid (для розрахунку накладеного платежу та інформації; на резерв не впливає)
payment.paid_amountnumberНСкільки вже сплачено (для часткової)
payment.paid_atstring (ISO-8601, UTC)НКоли сплачено

5.6. Відвантаження (shipping)

ПолеТипОб.Опис
shipping.desired_datestring (YYYY-MM-DD)НБажана дата відвантаження

5.7. Товари (items[])

Мінімум один рядок.

ПолеТипОб.Опис
items[].articlestringОАртикул номенклатури (той самий ключ, що в обміні залишками)
items[].namestringННазва (довідково)
items[].quantitynumberОКількість
items[].unitstring (код 1С)ОКод одиниці виміру 1С (напр. «пар»)
items[].pricenumberОЦіна за одиницю зі знижкою (1С приймає як є)
items[].price_without_discountnumberНЦіна за одиницю до знижки
items[].discount_percentnumberНЗнижка, %
items[].discount_amountnumberНЗнижка сумою (грн) на рядок
items[].vat_ratenumberОСтавка ПДВ, %. Зараз завжди 0 (працюємо без ПДВ)
items[].vat_amountnumberОСума ПДВ. Зараз завжди 0
items[].sumnumberОСума за рядком = quantity × price

5.8. Послуги (services[])

Окрема вкладка «Послуги» в «Замовленні покупця». Наразі єдиний кейс — **доставка, якщо її сплатив

клієнт наперед**. Якщо доставку платить отримувач на НП — секція порожня.

ПолеТипОб.Опис
services[].servicestring (код 1С)ОКод номенклатури послуги (напр. «Доставка»)
services[].namestringННазва (довідково)
services[].quantitynumberОКількість
services[].pricenumberОЦіна
services[].sumnumberОСума

5.9. Підсумки (totals)

Контрольні суми для звірки.

ПолеТипОб.Опис
totals.items_sumnumberОСума за товарами
totals.discount_totalnumberНЗагальна знижка (вкл. розподілену знижку на замовлення)
totals.services_sumnumberНСума послуг
totals.totalnumberОРазом = items_sum + services_sum

6. Контракт відповіді 1С

HTTP-коди й логіка повторів проксі:

КодКолиТілоПроксі повторює?
200Замовлення створено (status: created) або повтор, повернули наявне (status: duplicate)ok:true + дані замовлення + блок резервуНі, успіх
400Замовлення невалідне або бізнес-логіка не пропускає: немає обовʼязкового поля, невірний формат, артикул не знайдено в 1С, невідомий код довідникаok:false + errors[]Ні — потрібна людина
401Не пройшла авторизаціяok:false + текстНі — сповіщення
500Внутрішній збій 1С (виняток, недоступна база)ok:false + текстТак — тимчасовий збій
5031С недоступна/перевантажена/регламентні роботиТак — пізніше

Успіх (200)

{
  "ok": true,
  "order_number": "Ц0000008337",
  "order_date": "2026-06-12T14:05:00",
  "order_guid": "a1b2c3d4-0000-0000-0000-000000000000",
  "status": "created",
  "reservation": {
    "status": "partial",
    "shortages": [
      { "article": "Ц00002556", "requested": 2, "reserved": 1 }
    ]
  }
}

Помилка (400/401/500)

{
  "ok": false,
  "errors": [
    { "code": "ARTICLE_NOT_FOUND", "field": "items[2].article", "value": "X999", "message": "Номенклатура не знайдена" }
  ]
}

Коди (пропозиція): AUTH_FAILED, VALIDATION_ERROR, ARTICLE_NOT_FOUND, INTERNAL_ERROR.

7. Повний приклад запиту (накладений платіж, відділення НП)

{
  "source": "keycrm",
  "external_number": "12345",
  "external_created_at": "2026-06-12T10:30:00Z",
  "fop": "Ц00000005",
  "price_type": "000000001",
  "comment": "Прошу зателефонувати за годину до доставки",

  "customer": {
    "full_name": "Іваненко Іван Іванович",
    "phone": "+380501234567",
    "email": "ivan@example.com"
  },
  "recipient": {
    "full_name": "Петренко Петро Петрович",
    "phone": "+380671112233"
  },

  "delivery": {
    "carrier": "nova_poshta",
    "type": "00000000123",
    "city_ref": "8d5a980d-391c-11dd-90d9-001a92567626",
    "city_name": "Київ",
    "warehouse_ref": "1ec09d2e-e1c2-11e3-8c4a-0050568002cf",
    "warehouse_name": "Відділення №5: вул. Хрещатик, 22",
    "street_ref": null,
    "street_name": null,
    "building": null,
    "flat": null,
    "declared_value": 4400,
    "cod_amount": 4400,
    "cargo_description": "взуття"
  },

  "payment": {
    "method": "00000000045",
    "channel": "novapay",
    "status": "unpaid",
    "paid_amount": 0,
    "paid_at": null
  },

  "shipping": {
    "desired_date": "2026-06-13"
  },

  "items": [
    {
      "article": "Ц00002556",
      "name": "Лофери Лоретто блакитний замш, 38",
      "quantity": 1,
      "unit": "пар",
      "price": 4400,
      "price_without_discount": 4900,
      "discount_percent": 10.2,
      "discount_amount": 500,
      "vat_rate": 0,
      "vat_amount": 0,
      "sum": 4400
    }
  ],

  "services": [],

  "totals": {
    "items_sum": 4400,
    "discount_total": 500,
    "services_sum": 0,
    "total": 4400
  }
}

8. Поза межами цього ТЗ (окремими завданнями)