Отправка счёта 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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
Функция ВыгрузитьЗаказы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() передаётся подготовленный массив с заказами, по которым будут отправлены счета.
В этой функции устанавливается соединение с сервером платёжной системы, с использованием логина и пароля любого пользователя личного кабинета, и получается токен для работы с личным кабинетом по JSON API:
1 2 3 4 5 6 7 8 9 10 |
Функция ВыгрузитьЗаказы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 36 37 38 39 40 41 42 |
Запрос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 25 26 27 28 29 30 |
ЗапросHTTPОтправить = Новый HTTPЗапрос("/change/invoice/send/", Заголовки); ТелоЗапросаОтправить= "token=" + Токен + "&id=" + ОтветОбъект.invoice_id; ЗапросHTTPОтправить.УстановитьТелоИзСтроки(ТелоЗапросаОтправить); ОтветHTTPОтправить= СоединениеHTTP.ОтправитьДляОбработки(ЗапросHTTPОтправить); ЧтениеJSON.УстановитьСтроку(ОтветHTTPОтправить.ПолучитьТелоКакСтроку()); Попытка ОтветОбъект= ПрочитатьJSON(ЧтениеJSON); Исключение Сообщить("Ошибка при отправке счёта"); Продолжить; КонецПопытки; Если ОтветОбъект.Свойство("result", РезультатЗапроса) Тогда Если РезультатЗапроса = "fail" Тогда Сообщить(ОтветОбъект.msg); Продолжить; КонецЕсли; КонецЕсли; |
В случае, если вы планируете самостоятельно формировать письмо со счётом клиенту, а не отправлять его средствами платёжной системы, можно исключить эту последнюю секцию кода, осуществляющую запрос 3.5 и использовать параметр invoice_url из ответа по запросу 3.4 для отправки ссылки на оплату клиенту.
Этот код является примером реализации автоматической отправки счетов из 1С с использованием JSON API, однако вполне может использоваться в реальном решении по интеграции с нашей системой.