При покупках в интернет-магазинах клиенты, чаще всего приобретают более одного товара. В такой ситуации, для соответствия 54-ФЗ в налоговую необходимо передавать чек покупки со сведениями обо всех приобретённых товарах и услугах. Обычно сформировать список покупок в конкретном заказе не составляет труда, поскольку при оформлении заказа в большинстве современных решений для интернет-магазина используется так называемая корзина товаров (по аналогии с корзинкой для товаров в супермаркетах), которую покупатель наполняет, просматривая витрину интернет-магазина.
Для формирования чека нужно при инициализации оплаты передать содержимое этой корзины. Чтобы это сделать, нужно сформировать JSON-массив объектов товарных позиций и передать в параметре cart POST-запроса на создание платежа, вместе с остальными параметрами платежа.
Формат одного объекта товарной позиции следующий:
Поле | Назначение | Обязательное |
name | Наименование экземпляра товара. Строка, не более 128 символов длиной. | Да |
price | Стоимость единичного экземпляра товара | Да |
quantity | Количество экземпляров товара в данной позиции | Да |
sum | Полная сумма к уплате по данной товарной позиции, включая НДС | Да |
tax | Код налога, применяющегося к данной позиции | Да |
item_type | Код признака предмета расчёта (категория товара/услуги). Значение по умолчанию – «ТОВАР» | Нет |
payment_type | Код признака способа расчёта. Значение по умолчанию – «Оплата в момент передачи». До версии 2.6.0 — «Предоплата 100%» | Нет |
Следующие поля требуются только в отдельных случаях | ||
item_code | Код маркировки без непечатаемых символов | Нет |
item_code_b64 | Код маркировки с двоичными разделителями, закодированный в base64 | Нет |
items_in_package | Количество экземпляров товара в общей упаковке (Только для маркированных товаров, продающихся из общей упаковки) | Нет |
items_sold_from_package | Количество проданных единиц товаров (если нет возможности передать это число в quantity и указать настоящую стоимость за единицу в price) | Нет |
measure | Единица измерения товара для мерных товаров. См. таблицу 10. | Нет |
item_country | Страна происхождения товара, трёхциферный код по ОКСМ. Нужно передавать строкой из трёх символов, если код короче трёх символов, дополнить пробелами справа. Пример: "398" | Нет |
customs_declaration | Номер грузовой таможенной декларации | Нет |
excise | Сумма акциза | Нет |
Следующие два поля нужны при работе по агентской схеме | ||
agent | Объект с информацией об агенте | Нет |
supplier | Объект с информацией о поставщике | Нет |
Таблица 1. Поля объекта товарной позиции |
Параметры item_type и payment_type обязательные, но PayKeeper подставит значения по умолчанию, если они не переданы. Параметры item_code, item_country, customs_declaration, excise могут быть обязательны в особых случаях.
Если применяется агентская схема работы, а все элементы корзины имеют одинакового поставщика или агента, то информацию о них достаточно указать в общих свойствах чека. Иначе, если в каждой товарной позиции свой агент или поставщик, то по каждому из них должны быть заполнены свойства agent и supplier.
Для поля tax предусмотрены следующие возможные коды:
Код | Значение |
none | НДС не облагается |
vat0 | НДС 0% |
vat10 | НДС 10% |
vat20 | НДС 20% |
vat110 | НДС 10/110 |
vat120 | НДС 20/120 |
Таблица 2. Типы налогов |
Все поля данного объекта должны быть в кодировке UTF-8.
Также, необходимо обратить внимание — ставки «НДС 0%» и «НДС не облагается» применяются в разных случаях. Для предприятий, работающих по упрощённой схеме налогообложения, нужно указывать none — «НДС не облагается».
Сумма полных стоимостей товарных позиций должна быть равна полной стоимости заказа.
Для соответствия ФФД 1.05 для каждой товарной позиции указывать код признака предмета расчёта и код признака расчёта. Для этих целей введены два необязательных поля: item_type и payment_type соответственно.
Для поля item_type (фискальный тег 1212) предусмотрены следующие возможные коды:
Код | Значение |
goods | Товар |
service | Услуга |
work | Работа |
excise | Подакцизный товар |
ip | Интеллектуальная деятельность, права на интеллектуальную собственность |
payment | Аванс, задаток, предоплата, взнос или другой платёж |
agent | Вознаграждение агента |
property_right | Передача имущественного права |
non_operating | Внереализационный доход |
sales_tax | Торговый сбор |
resort_fee | Курортный сбор |
other | Иной предмет расчёта |
exc_uncoded | О реализуемом подакцизном товаре, подлежащем маркировке средством идентификации, не имеющем кода маркировки |
exc_coded | О реализуемом подакцизном товаре, подлежащем маркировке средством идентификации, имеющем код маркировки |
goods_uncoded | О реализуемом товаре, подлежащем маркировке средством идентификации, не имеющем кода маркировки, за исключением подакцизного товара |
goods_coded | О реализуемом товаре, подлежащем маркировке средством идентификации, имеющем код маркировки, за исключением подакцизного товара |
Таблица 3. Признаки предметов расчёта |
Для поля payment_type (фискальный тег 1214) предусмотрены следующие возможные коды:
Код | Значение |
prepay | Предоплата 100% |
part_prepay | Частичная предоплата |
advance | Аванс |
full | Полная оплата в момент передачи предмета расчёта |
part_credit | Передача товара с последующей частичной оплатой в кредит |
credit | Передача товара без оплаты с последующей полной оплатой в кредит |
credit_payment | Оплата кредита |
Таблица 4. Признаки способа расчёта |
Формат фискальных документов 1.05 позволяет передавать дополнительную информацию о продаже и товарах в случаях, если платёж принимается агентом. Если в чеке все товарные позиции реализуются одним агентом от одного поставщика, при инициализации платежа можно передать POST-параметр receipt_properties, содержащий JSON-кодированный объект дополнительных свойств чека, чтобы не дублировать эти же значения в каждой товарной позиции. Кроме того, в некоторых отраслях требуется передача расширенной информации о плательщике. В настоящее время поддерживаются следующие поля объекта:
Поле | Назначение | Обязательное |
agent | Объект с параметрами агента | Да, если платёж принимает агент |
supplier | Объект с параметрами поставщика | Да, если платёж принимает агент |
client | Объект с информацией о плательщике | В отдельных отраслях |
Таблица 5. Дополнительные атрибуты чека |
Передача объекта агента и поставщика не обязательна, если в настройках сервера PayKeeper на стадии настройки 54-ФЗ уже были указаны атрибуты агента по умолчанию. Тогда они будут применяться для каждого чека и каждой товарной позиции.
Если ККТ работает с ФФД 1.2, поля agent и supplier передавать нельзя, они будут проигнорированы. Агентские признаки нужно передавать только в товарных позициях.
Объект с информацией об агенте может включаться в общие свойства чека или указываться для отдельной товарной позиции. Он имеет следующие свойства:
Поле | Назначение | Обязательное |
type | Тип агента | Да |
phones | Массив строк номеров телефонов агента в формате +79101234567 | Для bank_(sub)agent и payment_(sub)agent |
operation | Наименование операции платёжного агента или субагента | Для банковских платёжных агентов или субагентов bank_(sub)agent |
inn | ИНН оператора перевода | |
name | Наименование оператора перевода | |
address | Адрес оператора перевода | |
transfer_phones | Телефоны оператора перевода платежа | |
receiver_phones | Телефоны оператора по приёму платежа | Для платёжных агентов или субагентов payment_(sub)agent |
Таблица 6. Описание агента |
Сумма длин номеров телефонов в каждом из параметров не должна быть более 19 символов. Возможные значения поля типа агента:
Поле | Назначение |
bank_agent | Банковский платёжный агент |
bank_subagent | Банковский платёжный субагент |
payment_agent | Платёжный агент |
payment_subagent | Платёжный субагент |
attorney | Поверенный |
commissionaire | Комиссионер |
other | Другой агент |
Таблица 7. Виды агентов |
Объект с информацией о поставщике товара может присутствовать в общих свойствах чека, а может добавляться к отдельным товарным позициям. Имеет следующие свойства:
Поле | Назначение |
phones | Массив номеров телефонов поставщика в формате +79101234567 |
inn | ИНН поставщика |
name | Наименование поставщика |
Таблица 8. Свойства объекта поставщика |
Сумма длин номеров телефонов не должна превышать 19 символов.
Объект с информацией о плательщике может присутствовать в общих свойствах чека. Его вид следующий:
Поле | Назначение |
identity | Название организации-плательщика, или ФИО плательщика и его данные |
inn | ИНН плательщика |
Таблица 9. Информация о плательщике |
Наличие этой структуры требуется в отдельных областях.
При использовании онлайн кассы АТОЛ и протокола ФФД 1.2 в свойствах плательщика можно также указать два необязательных поля: document_code и document_type — тэг 1245 и тэг 1246 соответственно.
Для некоторых видов товаров введена обязательная маркировка кодами «Честный Знак» или иными кодами. Если товар промаркирован, в чеке при продаже товара нужно передать код маркировки. Если код data matrix системы «Честный Знак» считывается штрих-сканером в режиме эмуляции клавиатуры, то при считывании потеряются байты 0x1d в коде маркировки, которые служат разделителями тегов внутри кода. Такое значение нужно передавать в поле item_code, и система автоматически вставит в переданный коду байты 0x1d, сделав его корректным.
Если сканер работает в режиме эмуляции COM-порта, то будут переданы все двоичные значения, и код нужно будет обернуть в base64 и передать в поле item_code_b64. Если переданы непустые значения в обоих полях одновременно, item_code и item_code_b64, то приоритетным будет считаться именно поле item_code_b64.
Пример корректного заполнения поля item_code:
1 |
item_code:"0108027281101631215gVjLruMq9S-<9100BE92YvJc9bbSguRaesv7jBHNn7q4lH5j68OMbfSIzO6DvkySCZC65pH4Z+P3RWhoNJGE9jIB9f1TddUqiF4KjkgYuA==" |
В этой строке нет непечатаемых байтов.
Пример корректного заполнения поля item_code_b64:
1 |
item_code_b64:"MDEwNDY0MDA3ODAxNjM3MjIxO2hMbG0lM0h2b0pIaB05MUZGRDAdOTJkR1Z6ZE1nZ1hFaFNKTmx3ekRXWjIzZldVcWJuSkhYaFpvOFpETjY4UWQ0PQ==" |
В этой строке, если её раскодировать из base64, будут присутствовать байты 0x1d:
1 2 3 4 5 6 7 8 9 |
$ echo "MDEwNDY0MDA3ODAxNjM3MjIxO2hMbG0lM0h2b0pIaB05MUZGRDAdOTJkR1Z6ZE1nZ1hFaFNKTmx3ekRXWjIzZldVcWJuSkhYaFpvOFpETjY4UWQ0PQ==" | openssl base64 -d | hexdump -C 00000000 30 31 30 34 36 34 30 30 37 38 30 31 36 33 37 32 |0104640078016372| 00000010 32 31 3b 68 4c 6c 6d 25 33 48 76 6f 4a 48 68 1d |21;hLlm%3HvoJHh.| 00000020 39 31 46 46 44 30 1d 39 32 64 47 56 7a 64 4d 67 |91FFD0.92dGVzdMg| 00000030 67 58 45 68 53 4a 4e 6c 77 7a 44 57 5a 32 33 66 |gXEhSJNlwzDWZ23f| 00000040 57 55 71 62 6e 4a 48 58 68 5a 6f 38 5a 44 4e 36 |WUqbnJHXhZo8ZDN6| 00000050 38 51 64 34 3d |8Qd4=| 00000055 |
В случае, если кодом «Честный Знак» промаркирована упаковка с несколькими экземплярами товара, при продаже такого товара нужно дополнительно передавать количество товаров в общей упаковке. Для этого нужно передать дополнительно свойство items_in_package объекта товарной позиции (см. таблицу 1). Например, если продаётся 3 коробочки детского молока из блока, в котором всего 8 пачек, необходимо передать в соответствующем элементе товарной корзины количество quantity = 3, items_in_package = 8
В некоторых случаях товарных систем возможно, что цена реализуемых единиц товара не подсчитывается за единицу товара, и ТСП не может передать реальную цену в price. В этом случае нужно передать сумму к реализации в sum, цену price передать равной sum , количество товара quantity указать равным 1, а реальное количество товаров из упаковки передать в поле items_sold_from_package. Кроме этого случая, items_sold_from_package нужно передавать равным null или не передавать вообще.
Для соответствия ФФД 1.2 в случае использования онлайн-кассы АТОЛ для каждой товарной позиции необходимо указывать меру количества предмета расчёта measure (тэг 2108).
Для поля measure предусмотрены следующие возможные коды:
Код | Значение |
pcs | Штуки или единицы |
g | Грамм |
kg | Килограмм |
t | Тонна |
cm | Сантиметр |
dm | Дециметр |
m | Метр |
sq_cm | Квадратный сантиметр |
sq_dm | Квадратный дециметр |
sq_m | Квадратный метр |
ml | Миллилитр |
l | Литр |
cbm | Кубический метр |
kwh | Киловатт час |
ggclr | Гигакалория |
day | Сутки |
hour | Час |
min | Минута |
sec | Секунда |
Kb | Килобайт |
Mb | Мегабайт |
Gb | Гигабайт |
Tb | Терабайт |
other | Применяется при использовании иных единиц измерения |
Таблица 10. Мера количества предмета расчёта |
Указать список товарных позиций и дополнительные свойства чека можно и при выставлении счёта через наш JSON API. В этом случае на размер результирующего объекта cart накладываются некоторые ограничения — в данный момент максимальная длина текста в переменной service_name составляет 10240 символов. Передавать объект нужно в переменной service_name с особыми метками:
1 |
;PKC|JSON_массив_объектов_товарных_позиций|;PKRP|JSON_объект_дополнительных_свойств_чека_если_нужно|; |
Формирование корзины на PHP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
"cart" => json_encode( array ( array ( "name" => 'Стол обеденный 2x3', "price" => 10.01, "quantity" => 1, "sum" => 10.01, "tax" => 'vat20', "item_type" => 'goods', "payment_type" => 'prepay' ), array ( "name" => 'Книга о вкусной и здоровой пище', "price" => 1.01, "quantity" => 3, "sum" => 3.03, "tax" => 'vat10' ) ) ) |
Формирование корзины на PHP, с созданием счёта через 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 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 |
<?php # Логин и пароль любого пользователя личного кабинета $user = "user"; $password = "password"; # имя или IP-адрес вашего сервера с PayKeeper $server = "example.server.paykeeper.ru"; # параметры платежа. Обязательной является только сумма. $payment_data = array ( "pay_amount" => 7.50, "clientid" => "Иванов Иван Иванович", "orderid" => "Заказ № 10", "client_email" => "test@example.com", # передача корзины товаров для формирования чека по 54-ФЗ "service_name" => ";PKC|".json_encode( array ( array ( "name" => 'Стол обеденный 2x3', "price" => 1.50, "quantity" => 1, "sum" => 1.50, "tax" => 'none', ), array ( "name" => 'Книга о вкусной и здоровой пище', "price" => 2, "quantity" => 3, "sum" => 6, "tax" => 'none', ) ))."|", "client_phone" => "8 (910) 123-45-67" ); $auth_header = array ( 'Authorization: Basic '.base64_encode("$user:$password") ); $context = stream_context_create(array ( 'http' => array ( 'header' => $auth_header ) ) ); $result = json_decode(file_get_contents("http://$server/info/settings/token", FALSE, $context), TRUE); $token = $result['token']; $request = array_merge($payment_data, array ('token'=>$token)); $request_string = http_build_query($request); $request_headers = array_merge($auth_header, array("Content-type: application/x-www-form-urlencoded")); $context = stream_context_create(array ( 'http' => array ( 'method' => 'POST', 'header' => $request_headers, 'content' => $request_string ) ) ); $result = json_decode(file_get_contents("http://$server/change/invoice/preview", FALSE, $context), TRUE); $invoice_id = $result['invoice_id']; # в этой переменной прямая ссылка на оплату с заданными параметрами. $link = "http://$server/bill/$invoice_id/"; echo $link; ?> |
Рассмотренные выше примеры кода позволяют сформировать и передать товарную корзину для дальнейшего корректного формирования чека, в соответствии с 54-ФЗ, на стороне поддерживаемого PayKeeper кассового решения.