Отправка счёта 1С
Как выставить счёт в 1С
Часто необходимо предоставить клиенту возможность удалённо оплатить заказ, причём не сразу, а тогда, когда будет удобно. В таких случаях, обычно, пользуются выставлением счетов для оплаты. Выставленный счёт высылается клиенту по электронной почте, клиент открывает письмо и переходит по ссылке для оплаты в любое удобное время. Иногда полезно ограничить допустимый срок оплаты, например, при резервировании товара. В случае использования нашего решения такая возможность выставления счетов по электронной почте присутствует изначально, в личном кабинете. Однако при использовании 1С было бы неплохо автоматизировать процесс, особенно при большом количестве заказов. Это выполнимо с использованием нашего JSON API.
При выставлении счёта возможно указать следующие параметры:
Тип | Параметр | Назначение | Обязательный |
1. | pay_amount | Сумма заказа к оплате | Да |
2. | clientid | Идентификатор клиента | Нет |
3. | orderid | Номер заказа | Нет |
4. | service_name | Наименование услуги | Нет |
5. | client_email | E-mail адрес клиента | Да |
6. | client_phone | Телефон клиента | Нет |
7. | expiry | Срок действия счёта в формате YYYY-MM-DD (не включительно) | Нет |
8. | token | Токен безопасности | Да |
Таблица 1. Параметры запроса «Подготовка счёта» |
Для автоматического выставления счёта через API необходимо сформировать и отправить два запроса к серверу системы с необходимым набором данных из этого списка. Первый — непосредственно для формирования счёта, а второй — для его отправки клиенту.
Рассмотрим алгоритм работы более подробно:
- Получить актуальный токен для доступа к JSON API.
- Подготовить набор данных для формирования запроса.
- Сформировать запрос для предварительного просмотра с корректными заголовками.
- Выполнить запрос для предварительного просмотра и проверить корректность ответа.
- Сформировать запрос для отправки счёта с корректными заголовками.
- Выполнить запрос для отправки счёта и проверить корректность ответа.
Пример кода для 1С
Ниже рассмотрим пример реализации данного алгоритма для 1С:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
Функция ВыгрузитьЗаказыPayKeeper(МассивЗаказов) СоединениеHTTP = Новый HTTPСоединение("_____.server.paykeeper.ru", , "Пользователь_ЛК", "Пароль", , , Новый ЗащищенноеСоединениеOpenSSL); Заголовки = Новый Соответствие; Токен = ПолучитьТокенPayKeeper(СоединениеHTTP, Заголовки); Возврат ОтправитьДанныеPayKeeper(СоединениеHTTP, Заголовки, Токен, МассивЗаказов); КонецФункции Функция ПолучитьТокенPayKeeper(СоединениеHTTP, Заголовки) ЗапросHTTP = Новый HTTPЗапрос("/info/settings/token/", Заголовки); ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP); ЧтениеJSON = Новый ЧтениеJSON; ЧтениеJSON.УстановитьСтроку(ОтветHTTP.ПолучитьТелоКакСтроку()); Попытка ОбъектJSON = ПрочитатьJSON(ЧтениеJSON); Исключение Сообщить("Ошибка при получении токена безопасности"); Возврат ""; КонецПопытки; Токен = ""; Если ОбъектJSON.Свойство("token", Токен) Тогда Возврат Токен; Иначе Сообщить(ОбъектJSON.msg); Возврат ""; КонецЕсли; КонецФункции Функция ОтправитьДанныеPayKeeper(СоединениеHTTP, Заголовки, Токен, ДанныеДляОтправки) ЗапросHTTP = Новый HTTPЗапрос("/change/invoice/preview/", Заголовки); ЗапросHTTP.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded"); Для Каждого ДанныеДляОтправкиСтрока Из ДанныеДляОтправки Цикл ТелоЗапроса = "token=" + Токен + "&clientid=" + ДанныеДляОтправкиСтрока.clientid + "&orderid=" + ДанныеДляОтправкиСтрока.orderid + "&service_name=" + ДанныеДляОтправкиСтрока.service_name + "&client_email=" + ДанныеДляОтправкиСтрока.client_email + "&client_phone=" + ДанныеДляОтправкиСтрока.client_phone + "&expiry=" + Формат(ДанныеДляОтправкиСтрока.expiry, "ДФ=гггг-ММ-дд") + "&pay_amount=" + ДанныеДляОтправкиСтрока.pay_amount; ЗапросHTTP.УстановитьТелоИзСтроки(ТелоЗапроса); ОтветHTTP = СоединениеHTTP.ОтправитьДляОбработки(ЗапросHTTP); ЧтениеJSON = Новый ЧтениеJSON; ЧтениеJSON.УстановитьСтроку(ОтветHTTP.ПолучитьТелоКакСтроку()); Попытка ОтветОбъект = ПрочитатьJSON(ЧтениеJSON); Исключение Сообщить("Ошибка при выставлении счёта"); Продолжить; КонецПопытки; РезультатЗапроса = ""; Если ОтветОбъект.Свойство("result", РезультатЗапроса) Тогда Если РезультатЗапроса = "fail" Тогда Сообщить(ОтветОбъект.msg); Продолжить; КонецЕсли; КонецЕсли; ЗапросHTTPОтправить = Новый HTTPЗапрос("/change/invoice/send/", Заголовки); ТелоЗапросаОтправить = "token=" + Токен + "&id=" + ОтветОбъект.invoice_id; ЗапросHTTPОтправить.УстановитьТелоИзСтроки(ТелоЗапросаОтправить); ОтветHTTPОтправить = СоединениеHTTP.ОтправитьДляОбработки(ЗапросHTTPОтправить); ЧтениеJSON.УстановитьСтроку(ОтветHTTPОтправить.ПолучитьТелоКакСтроку()); Попытка ОтветОбъект = ПрочитатьJSON(ЧтениеJSON); Исключение Сообщить("Ошибка при отправке счёта"); Продолжить; КонецПопытки; Если ОтветОбъект.Свойство("result", РезультатЗапроса) Тогда Если РезультатЗапроса = "fail" Тогда Сообщить(ОтветОбъект.msg); Продолжить; КонецЕсли; КонецЕсли; КонецЦикла; КонецФункции ТестовыеДанные = Новый Массив; ТестовыеДанные.Добавить(Новый Структура("clientid, orderid, service_name, client_email, client_phone, expiry, pay_amount", "Иванов Иван Иванович", "123-1", "Тестовая услуга", "test@yourdomain.com", "+79876543210", "20191020200103", "100.03")); ТестовыеДанные.Добавить(Новый Структура("clientid, orderid, service_name, client_email, client_phone, expiry, pay_amount", "Петров Пётр Петрович", "123-2", "Тестовый товар", "example@yourdomain.com", "+79876543210", "20191031101158", "10.50")); ВыгрузитьЗаказыPayKeeper(ТестовыеДанные); |
В функцию ВыгрузитьЗаказыPayKeeper() передаётся подготовленный массив с заказами, по которым будут отправлены счета.
В этой функции устанавливается соединение с сервером PayKeeper, с использованием логина и пароля любого пользователя личного кабинета, и получается токен для работы с личным кабинетом по JSON API:
1 2 3 4 5 6 7 |
Функция ВыгрузитьЗаказыPayKeeper(МассивЗаказов) СоединениеHTTP = Новый HTTPСоединение("_____.server.paykeeper.ru", , "Пользователь_ЛК", "Пароль", , , Новый ЗащищенноеСоединениеOpenSSL); Заголовки = Новый Соответствие; Токен = ПолучитьТокенPayKeeper(СоединениеHTTP, Заголовки); |
Затем созданное соединение используется для отправки счетов:
1 |
Возврат ОтправитьДанныеPayKeeper(СоединениеHTTP, Заголовки, Токен, МассивЗаказов); |
В функции отправки ОтправитьДанныеPayKeeper(); для каждого элемента в массиве заказов формируется и отправляется POST-запрос с необходимыми данными для метода 3.4 JSON API. Обратите внимание на заголовок Content-Type для данных запросов. Он обязательно должен быть application/x-www-form-urlencoded, иначе система сообщит об ошибке.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
ЗапросHTTP = Новый HTTPЗапрос("/change/invoice/preview/", Заголовки); ЗапросHTTP.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded"); Для Каждого ДанныеДляОтправкиСтрока Из ДанныеДляОтправки Цикл ТелоЗапроса = "token=" + Токен + "&clientid=" + ДанныеДляОтправкиСтрока.clientid + "&orderid=" + ДанныеДляОтправкиСтрока.orderid + "&service_name=" + ДанныеДляОтправкиСтрока.service_name + "&client_email=" + ДанныеДляОтправкиСтрока.client_email + "&client_phone=" + ДанныеДляОтправкиСтрока.client_phone + "&expiry=" + Формат(ДанныеДляОтправкиСтрока.expiry, "ДФ=гггг-ММ-дд") + "&pay_amount=" + ДанныеДляОтправкиСтрока.pay_amount; ЗапросHTTP.УстановитьТелоИзСтроки(ТелоЗапроса); ОтветHTTP = СоединениеHTTP.ОтправитьДляОбработки(ЗапросHTTP); ЧтениеJSON = Новый ЧтениеJSON; ЧтениеJSON.УстановитьСтроку(ОтветHTTP.ПолучитьТелоКакСтроку()); Попытка ОтветОбъект = ПрочитатьJSON(ЧтениеJSON); Исключение Сообщить("Ошибка при выставлении счёта"); Продолжить; КонецПопытки; РезультатЗапроса = ""; Если ОтветОбъект.Свойство("result", РезультатЗапроса) Тогда Если РезультатЗапроса = "fail" Тогда Сообщить(ОтветОбъект.msg); Продолжить; КонецЕсли; КонецЕсли; |
Важно! Для конфигураций 1С, работающих в режиме совместимости, строка формирования запроса должна быть:
1 |
ЗапросHTTP.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); |
В случае успешного завершения данного запроса сразу выполняется запрос 3.5 JSON API для отправки счёта клиенту:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
ЗапросHTTPОтправить = Новый HTTPЗапрос("/change/invoice/send/", Заголовки); ТелоЗапросаОтправить = "token=" + Токен + "&id=" + ОтветОбъект.invoice_id; ЗапросHTTPОтправить.УстановитьТелоИзСтроки(ТелоЗапросаОтправить); ОтветHTTPОтправить = СоединениеHTTP.ОтправитьДляОбработки(ЗапросHTTPОтправить); ЧтениеJSON.УстановитьСтроку(ОтветHTTPОтправить.ПолучитьТелоКакСтроку()); Попытка ОтветОбъект = ПрочитатьJSON(ЧтениеJSON); Исключение Сообщить("Ошибка при отправке счёта"); Продолжить; КонецПопытки; Если ОтветОбъект.Свойство("result", РезультатЗапроса) Тогда Если РезультатЗапроса = "fail" Тогда Сообщить(ОтветОбъект.msg); Продолжить; КонецЕсли; КонецЕсли; |
В случае, если вы планируете самостоятельно формировать письмо со счётом клиенту, а не отправлять его средствами PayKeeper, можно исключить эту последнюю секцию кода, осуществляющую запрос 3.5 и использовать параметр invoice_url из ответа по запросу 3.4 для отправки ссылки на оплату клиенту.
Этот код является примером реализации автоматической отправки счетов из 1С с использованием JSON API, однако вполне может использоваться в реальном решении по интеграции с нашей системой.