Замовлення із сайту kohani.com.ua (Horoshop), із CRM KeyCRM і в майбутньому з бота спочатку
потрапляють у хмарний проксі. Проксі приводить їх до єдиного вигляду й одним запитом надсилає
в 1С. 1С не знає про особливості систем-джерел — він отримує один нормалізований контракт.
Що 1С робить із замовленням:
| Параметр | Значення |
|---|---|
| Метод | POST |
| Content-Type | application/json; charset=utf-8 |
| Кодування | UTF-8 |
| Авторизація | Токен у HTTP-заголовку X-Auth-Token. 1С перевіряє його на кожному запиті. Значення токена узгоджується з розробником 1С; на боці проксі зберігається в секретах Cloud Run |
| Транспорт | HTTPS (можливий HTTP у захищеному контурі) |
| Без авторизації | 401, замовлення не створюється |
1С зобовʼязаний повернути JSON-відповідь за §6 (і при успіху, і при помилці).
Проксі може надіслати одне й те саме замовлення повторно (повтор при таймауті/обриві звʼязку).
Дублі неприпустимі.
source + external_number для неї — довідковіполя (зберігає в замовленні, може знадобитися для майбутніх оновлень оплати).
чи немає вже замовлення з такою парою. Є → не створює нове, повертає наявне (номер, дату,
GUID) зі status: duplicate.
source + external_number (§3).сама, ми надсилаємо міжнародний формат). Email — вторинна підказка для збагачення картки.
**Перед запуском автоматизації розробники 1С проводять разову процедуру дедуплікації наявних
контрагентів**, щоб автостворення не плодило дублі поверх «брудної» бази.
наявністю (уточнюється при узгодженні контракту; проксі за потреби може запитати в 1С наявність
перед створенням замовлення).
price / sum / total як є, не перераховує (джерело істини щодо грошей — проксі: клієнт стільки заплатив). При розбіжності total і суми рядків — повертає
warning, але замовлення створює.
Повний приклад — §7. Обовʼязковість: О — обовʼязково, Н — необовʼязково.
| Поле | Тип | Об. | Опис |
|---|---|---|---|
source | enum | О | keycrm | horoshop | bot (довідково + ключ дедуплікації) |
external_number | string | О | Номер замовлення в джерелі (довідково + ключ дедуплікації) |
external_created_at | string (ISO-8601, UTC) | О | Коли замовлення створено в джерелі |
fop | string (код 1С) | О | Код активного ФОПа, від імені якого створюється замовлення. 1С за ним сама підтягує банківський рахунок, Організацію ЕН, організацію НП та її ключ |
price_type | string (код 1С) | О | Код типу ціни номенклатури. Роздріб = 000000001 («Роздрібні»). Один на замовлення. Валюту 1С виводить із типу ціни |
comment | string | Н | Коментар клієнта/менеджера → поле «Коментар» замовлення |
customer) — замовник/платникЛише фізособи. Надсилаємо завжди.
| Поле | Тип | Об. | Опис |
|---|---|---|---|
customer.full_name | string | О | ПІБ |
customer.phone | string | О | Телефон, міжнародний формат +380XXXXXXXXX |
customer.email | string | Н | Email (вторинний ключ, збагачення картки) |
recipient)Надсилаємо завжди повним блоком, навіть якщо збігається з контрагентом (1С не розгалужується).
| Поле | Тип | Об. | Опис |
|---|---|---|---|
recipient.full_name | string | О | ПІБ отримувача |
recipient.phone | string | О | Телефон отримувача, міжнародний формат |
delivery)Отримувач НП — завжди «Приватна особа». Міста/відділення/вулиці НП передаємо парою `ref` + назва
(API НП вимагає звʼязку). Підтримуються всі види доставки з довідника 1С.
| Поле | Тип | Об. | Опис |
|---|---|---|---|
delivery.carrier | string | О | Перевізник; на старті nova_poshta |
delivery.type | string (код 1С) | О | Код «Виду доставки» 1С: Склад-склад / Склад-двері / Склад-поштомат тощо |
delivery.city_ref | string (guid НП) | О | GUID населеного пункту (CityRef/SettlementRef) |
delivery.city_name | string | О | Назва міста (обовʼязково в парі з ref) |
delivery.warehouse_ref | string (guid НП) | Н* | GUID відділення/поштомата (WarehouseRef). *Для Склад-склад/Склад-поштомат |
delivery.warehouse_name | string | Н* | Назва відділення/поштомата (у парі з ref) |
delivery.street_ref | string (guid НП) | Н** | GUID вулиці (StreetRef). **Для адресної доставки |
delivery.street_name | string | Н** | Назва вулиці (у парі з ref) |
delivery.building | string | Н** | Будинок |
delivery.flat | string | Н | Квартира |
delivery.declared_value | number | О | Оголошена (оцінна) вартість = сума товарів |
delivery.cod_amount | number | О | Контроль оплати (накладений платіж) = сума товарів − передоплата. Повна передоплата → 0 |
delivery.cargo_description | string | О | Опис вантажу («взуття»/«одяг»…). Проксі визначає за розділом каталогу |
payment)| Поле | Тип | Об. | Опис |
|---|---|---|---|
payment.method | string (код 1С) | О | Код «Способу оплати» 1С (накладений платіж / передоплата / …). Вибір клієнта; ФОП не визначає |
payment.channel | string | Н | Платіжна система/канал (LiqPay, Mono, NovaPay…) — для бухгалтерії/аналітики. 1С поки може ігнорувати, пізніше звʼяже з платіжними терміналами |
payment.status | enum | О | paid | unpaid | partially_paid (для розрахунку накладеного платежу та інформації; на резерв не впливає) |
payment.paid_amount | number | Н | Скільки вже сплачено (для часткової) |
payment.paid_at | string (ISO-8601, UTC) | Н | Коли сплачено |
shipping)| Поле | Тип | Об. | Опис |
|---|---|---|---|
shipping.desired_date | string (YYYY-MM-DD) | Н | Бажана дата відвантаження |
items[])Мінімум один рядок.
| Поле | Тип | Об. | Опис |
|---|---|---|---|
items[].article | string | О | Артикул номенклатури (той самий ключ, що в обміні залишками) |
items[].name | string | Н | Назва (довідково) |
items[].quantity | number | О | Кількість |
items[].unit | string (код 1С) | О | Код одиниці виміру 1С (напр. «пар») |
items[].price | number | О | Ціна за одиницю зі знижкою (1С приймає як є) |
items[].price_without_discount | number | Н | Ціна за одиницю до знижки |
items[].discount_percent | number | Н | Знижка, % |
items[].discount_amount | number | Н | Знижка сумою (грн) на рядок |
items[].vat_rate | number | О | Ставка ПДВ, %. Зараз завжди 0 (працюємо без ПДВ) |
items[].vat_amount | number | О | Сума ПДВ. Зараз завжди 0 |
items[].sum | number | О | Сума за рядком = quantity × price |
services[])Окрема вкладка «Послуги» в «Замовленні покупця». Наразі єдиний кейс — **доставка, якщо її сплатив
клієнт наперед**. Якщо доставку платить отримувач на НП — секція порожня.
| Поле | Тип | Об. | Опис |
|---|---|---|---|
services[].service | string (код 1С) | О | Код номенклатури послуги (напр. «Доставка») |
services[].name | string | Н | Назва (довідково) |
services[].quantity | number | О | Кількість |
services[].price | number | О | Ціна |
services[].sum | number | О | Сума |
totals)Контрольні суми для звірки.
| Поле | Тип | Об. | Опис |
|---|---|---|---|
totals.items_sum | number | О | Сума за товарами |
totals.discount_total | number | Н | Загальна знижка (вкл. розподілену знижку на замовлення) |
totals.services_sum | number | Н | Сума послуг |
totals.total | number | О | Разом = items_sum + services_sum |
HTTP-коди й логіка повторів проксі:
| Код | Коли | Тіло | Проксі повторює? |
|---|---|---|---|
| 200 | Замовлення створено (status: created) або повтор, повернули наявне (status: duplicate) | ok:true + дані замовлення + блок резерву | Ні, успіх |
| 400 | Замовлення невалідне або бізнес-логіка не пропускає: немає обовʼязкового поля, невірний формат, артикул не знайдено в 1С, невідомий код довідника | ok:false + errors[] | Ні — потрібна людина |
| 401 | Не пройшла авторизація | ok:false + текст | Ні — сповіщення |
| 500 | Внутрішній збій 1С (виняток, недоступна база) | ok:false + текст | Так — тимчасовий збій |
| 503 | 1С недоступна/перевантажена/регламентні роботи | — | Так — пізніше |
{
"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 }
]
}
}status: created | duplicate.reservation.status: full | partial | none. За partial/none замовлення створене, але не проведене — резерв не відбувся; проксі надсилає менеджерам сповіщення в Telegram зі списком shortages для ручного втручання.{
"ok": false,
"errors": [
{ "code": "ARTICLE_NOT_FOUND", "field": "items[2].article", "value": "X999", "message": "Номенклатура не знайдена" }
]
}Коди (пропозиція): AUTH_FAILED, VALIDATION_ERROR, ARTICLE_NOT_FOUND, INTERNAL_ERROR.
{
"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
}
}vat_* = 0).