Інтеграція з 1С/BAS
Практичні функції 1С 8 для створення операції, відправки одного або багатьох документів, отримання результату, webhook і розбору JSON.
API документація Кабінет1. Налаштування підключення
| Параметр | Значення |
|---|---|
| Хост | jdoc.net.ua |
| HTTPS | Так, порт 443. |
| Авторизація | Authorization: Bearer <API_KEY> |
| Створення операції | POST /api/v1/operations |
| Файли | multipart/form-data, поле files[]. |
| Пакет | До 100 файлів за один запит. |
Перем JDOC_API_HOST;
Перем JDOC_API_KEY;
Процедура JDOC_Ініціалізувати(APIКлюч) Экспорт
JDOC_API_HOST = "jdoc.net.ua";
JDOC_API_KEY = APIКлюч;
КонецПроцедуры
Функция JDOC_Соединение() Экспорт
Возврат Новый HTTPСоединение(JDOC_API_HOST, 443,,,,, Новый ЗащищенноеСоединениеOpenSSL);
КонецФункции
Функция JDOC_НовыйIdempotencyKey(Префикс = "jdoc") Экспорт
Возврат Префикс + "-" + Строка(Новый УникальныйИдентификатор);
КонецФункции
2. Допоміжні функції JSON і HTTP
Функция JDOC_ПрочитатьJSON(ОтветHTTP) Экспорт
Тело = ОтветHTTP.ПолучитьТелоКакСтроку();
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Тело);
Возврат ПрочитатьJSON(ЧтениеJSON);
КонецФункции
Процедура JDOC_ПроверитьHTTP(ОтветHTTP) Экспорт
Код = ОтветHTTP.КодСостояния;
Если Код < 200 Или Код >= 300 Тогда
ВызватьИсключение "JDOC HTTP " + Строка(Код) + ": " + ОтветHTTP.ПолучитьТелоКакСтроку();
КонецЕсли;
КонецПроцедуры
3. Multipart/form-data для файлів
JDOC приймає файли у полі files[]. Для багатьох документів додайте кілька частин з однаковим name files[].
Функция JDOC_СобратьMultipart(МассивПутейКФайлам, Boundary, WebhookURL = "", MetadataJSON = "", ClientOperationID = "") Экспорт
CRLF = Символы.ВК + Символы.ПС;
Поток = Новый ПотокВПамяти;
Запись = Новый ЗаписьДанных(Поток);
Для Каждого ПутьКФайлу Из МассивПутейКФайлам Цикл
Файл = Новый Файл(ПутьКФайлу);
ИмяФайла = Файл.Имя;
Mime = ?(НРег(Файл.Расширение) = ".pdf", "application/pdf", "application/octet-stream");
Заголовок = "--" + Boundary + CRLF
+ "Content-Disposition: form-data; name=\"files[]\"; filename=\"" + ИмяФайла + "\"" + CRLF
+ "Content-Type: " + Mime + CRLF + CRLF;
Запись.ЗаписатьСтроку(Заголовок, КодировкаТекста.UTF8);
Запись.Записать(Новый ДвоичныеДанные(ПутьКФайлу));
Запись.ЗаписатьСтроку(CRLF, КодировкаТекста.UTF8);
КонецЦикла;
Если WebhookURL <> "" Тогда
Запись.ЗаписатьСтроку("--" + Boundary + CRLF
+ "Content-Disposition: form-data; name=\"webhook_url\"" + CRLF + CRLF
+ WebhookURL + CRLF, КодировкаТекста.UTF8);
КонецЕсли;
Если MetadataJSON <> "" Тогда
Запись.ЗаписатьСтроку("--" + Boundary + CRLF
+ "Content-Disposition: form-data; name=\"metadata\"" + CRLF + CRLF
+ MetadataJSON + CRLF, КодировкаТекста.UTF8);
КонецЕсли;
Если ClientOperationID <> "" Тогда
Запись.ЗаписатьСтроку("--" + Boundary + CRLF
+ "Content-Disposition: form-data; name=\"client_operation_id\"" + CRLF + CRLF
+ ClientOperationID + CRLF, КодировкаТекста.UTF8);
КонецЕсли;
Запись.ЗаписатьСтроку("--" + Boundary + "--" + CRLF, КодировкаТекста.UTF8);
Запись.Закрыть();
Возврат Поток.ЗакрытьИПолучитьДвоичныеДанные();
КонецФункции
4. Створити операцію: один документ
Функция JDOC_СоздатьОперациюОдинФайл(ПутьКФайлу, APIКлюч, IdempotencyKey = "", WebhookURL = "") Экспорт
Если IdempotencyKey = "" Тогда IdempotencyKey = JDOC_НовыйIdempotencyKey("upload-one"); КонецЕсли;
Boundary = "----JDOC1C" + СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
Файлы = Новый Массив;
Файлы.Добавить(ПутьКФайлу);
Тело = JDOC_СобратьMultipart(Файлы, Boundary, WebhookURL);
Запрос = Новый HTTPЗапрос("/api/v1/operations");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + APIКлюч);
Запрос.Заголовки.Вставить("Idempotency-Key", IdempotencyKey);
Запрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
Запрос.УстановитьТелоИзДвоичныхДанных(Тело);
Ответ = JDOC_Соединение().ОтправитьДляОбработки(Запрос);
JDOC_ПроверитьHTTP(Ответ);
Возврат JDOC_ПрочитатьJSON(Ответ);
КонецФункции
5. Створити операцію: кілька документів
Можна передати до 100 файлів за один запит.
Функция JDOC_СоздатьОперациюНесколькоФайлов(МассивПутейКФайлам, APIКлюч, IdempotencyKey = "", WebhookURL = "") Экспорт
Если МассивПутейКФайлам.Количество() > 100 Тогда
ВызватьИсключение "JDOC принимает до 100 файлов за один запрос.";
КонецЕсли;
Если IdempotencyKey = "" Тогда IdempotencyKey = JDOC_НовыйIdempotencyKey("upload-batch"); КонецЕсли;
Boundary = "----JDOC1C" + СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
Тело = JDOC_СобратьMultipart(МассивПутейКФайлам, Boundary, WebhookURL);
Запрос = Новый HTTPЗапрос("/api/v1/operations");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + APIКлюч);
Запрос.Заголовки.Вставить("Idempotency-Key", IdempotencyKey);
Запрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
Запрос.УстановитьТелоИзДвоичныхДанных(Тело);
Ответ = JDOC_Соединение().ОтправитьДляОбработки(Запрос);
JDOC_ПроверитьHTTP(Ответ);
Возврат JDOC_ПрочитатьJSON(Ответ);
КонецФункции
6. Отримати операцію, результати і webhook-статус
Функция JDOC_ПолучитьОперацию(OperationID, APIКлюч) Экспорт
Запрос = Новый HTTPЗапрос("/api/v1/operations/" + OperationID);
Запрос.Заголовки.Вставить("Authorization", "Bearer " + APIКлюч);
Ответ = JDOC_Соединение().Получить(Запрос);
JDOC_ПроверитьHTTP(Ответ);
Возврат JDOC_ПрочитатьJSON(Ответ);
КонецФункции
Функция JDOC_ПолучитьРезультатыОперации(OperationID, APIКлюч) Экспорт
Запрос = Новый HTTPЗапрос("/api/v1/operations/" + OperationID + "/results");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + APIКлюч);
Ответ = JDOC_Соединение().Получить(Запрос);
JDOC_ПроверитьHTTP(Ответ);
Возврат JDOC_ПрочитатьJSON(Ответ);
КонецФункции
Функция JDOC_ПолучитьРезультатДокумента(DocumentID, APIКлюч) Экспорт
Запрос = Новый HTTPЗапрос("/api/v1/documents/" + DocumentID + "/result");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + APIКлюч);
Ответ = JDOC_Соединение().Получить(Запрос);
JDOC_ПроверитьHTTP(Ответ);
Возврат JDOC_ПрочитатьJSON(Ответ);
КонецФункции
Функция JDOC_ПолучитьWebhookСтатус(OperationID, APIКлюч) Экспорт
Запрос = Новый HTTPЗапрос("/api/v1/operations/" + OperationID + "/webhook");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + APIКлюч);
Ответ = JDOC_Соединение().Получить(Запрос);
JDOC_ПроверитьHTTP(Ответ);
Возврат JDOC_ПрочитатьJSON(Ответ);
КонецФункции
7. Дочекатися готового результату
Функция JDOC_ДочекатисяРезультату(OperationID, APIКлюч, ТаймаутСекунд = 180, ПаузаСекунд = 5) Экспорт
Начало = ТекущаяДата();
Пока Истина Цикл
Операция = JDOC_ПолучитьОперацию(OperationID, APIКлюч);
Если Операция.status = "PROCESSED" Или Операция.status = "PROCESSED_WITH_WARNINGS" Тогда
Возврат Операция;
КонецЕсли;
Если Операция.status = "FAILED" Или Операция.status = "CANCELLED"
Или Операция.status = "COMPLETED_WITH_ERRORS" Тогда
Возврат Операция;
КонецЕсли;
Если ТекущаяДата() - Начало > ТаймаутСекунд Тогда
ВызватьИсключение "JDOC: истек таймаут ожидания.";
КонецЕсли;
Пауза(ПаузаСекунд);
КонецЦикла;
КонецФункции
8. Webhook: що отримує 1С/BAS
Якщо ви налаштували webhook у кабінеті, JDOC надсилає POST-запит у вашу систему після завершення обробки. Повний результат краще забирати через GET-запит за operation_id або document_id.
Основні headers
| Header | Опис |
|---|---|
X-DocParser-Event | Тип події. |
X-DocParser-Operation-Id | ID операції. |
X-DocParser-Document-Id | ID документа, якщо подія документна. |
X-DocParser-Event-Id | ID події для дедуплікації. |
X-DocParser-Timestamp | Timestamp підпису. |
X-DocParser-Signature | Підпис sha256=.... |
Приклад payload
{
"event_type": "operation.completed",
"event_id": "evt_xxx",
"operation_id": "op_xxx",
"status": "PROCESSED",
"summary": {
"files_total": 1,
"processed": 1,
"processed_with_warnings": 0,
"rejected": 0,
"failed": 0,
"cancelled": 0
},
"documents": [
{
"document_id": "doc_xxx",
"filename": "document.pdf",
"status": "PROCESSED",
"billing": {
"billable": true,
"documents_charged": 1
}
}
]
}
Перевірка підпису
Підпис рахується як HMAC-SHA256 від рядка timestamp + "." + raw_body секретом webhook.
Функция JDOC_WebhookПідписДійсний(ТелоJSON, Timestamp, Signature, Secret) Экспорт
// Псевдокод: реалізація HMAC залежить від вашої конфігурації 1С/BAS
СтрокаДляПодписи = Timestamp + "." + ТелоJSON;
ОжидаемаяПодпись = "sha256=" + HMAC_SHA256_HEX(Secret, СтрокаДляПодписи);
Возврат ОжидаемаяПодпись = Signature;
КонецФункции
9. Що читати з JSON
| Дані | Поле |
|---|---|
| Номер документа | documents[0].result.document.number |
| Дата | documents[0].result.document.date |
| Контрагенти | documents[0].result.parties |
| Рядки | documents[0].result.line_items |
| Суми | documents[0].result.totals |
| ПДВ | documents[0].result.taxes |
| Попередження | documents[0].warnings |
10. Підтримка інтеграції
Якщо потрібна допомога з API або 1С/BAS, напишіть на support@jdoc.net.ua.