Регистрация чека после оплаты
Когда использовать отдельную регистрацию чека
По умолчанию Robokassa формирует чек вместе с операцией оплаты. Если состав чека нужно определить после платежа, отделите оплату от фискализации:
- Запустите оплату без параметра
Receipt. - Передайте
IsWithoutFreeSale=true, чтобы Robokassa не сформировала автоматический чек с позицией «Свободная продажа». - Дождитесь успешной оплаты.
- Зарегистрируйте чек отдельным запросом
Receipt/Register.
Такой сценарий подходит, например, для продажи подарочных сертификатов, учета бонусных баллов и скидок, а также для аванса с последующей доплатой.
IsWithoutFreeSale не создает отложенный чек автоматически. После успешной
оплаты магазин должен самостоятельно отправить запрос Receipt/Register.
Отключение автоматического чека
Параметр IsWithoutFreeSale необязательный и принимает значение true или
false. Он не участвует в расчете SignatureValue.
Для GET-запроса добавьте параметр в платежную ссылку:
https://auth.robokassa.ru/Merchant/Index.aspx?MerchantLogin=your-shop-login&OutSum=1000&InvId=1001&SignatureValue=your-signature&IsWithoutFreeSale=true
Для POST-запроса передайте его вместе с остальными полями формы:
IsWithoutFreeSale=true
Не передавайте Receipt, если чек должен быть сформирован только отдельным
запросом. Если одновременно передать номенклатуру, фискализация может начаться
при создании платежа.
При использовании CreateInvoice передайте IsWithoutFreeSale: true в
Payload и не добавляйте InvoiceItems. Подробнее о формате запроса см. в
документации Invoice API.
Регистрация чека
- Метод:
POST - Адрес:
https://services.robokassa.ru/Fiscalization.Api.External/Receipt/Register - Content-Type:
application/json - Тело запроса: подписанная JWT-строка
Сформируйте JWT так же, как для Invoice API: закодируйте Header и Payload в
Base64Url, подпишите их HMAC и передайте итоговый токен в теле запроса как
JSON-строку. В качестве секретного ключа используйте
MerchantLogin:Пароль#1. Подробный алгоритм приведен в разделе
«Формат запросов Invoice API».
JSON в примерах ниже — это Payload до Base64Url-кодирования и подписания.
Пример Payload
{
"ShopLocator": {
"Identifier": "your-shop-login"
},
"Receipts": [
{
"OpId": 123456789,
"Url": "https://shop.example",
"TaxScheme": "Osn",
"Type": "Sell",
"VatType": "None",
"Items": [
{
"Name": "Аванс",
"Quantity": 1,
"Sum": 1000,
"Cost": 1000,
"BonusSum": 0,
"VatType": "None",
"PaymentMethod": "Advance",
"PaymentObject": "Payment"
}
],
"Payments": [
{
"Type": "Cashless",
"Sum": 1000
}
],
"Client": {
"Email": "buyer@example.com"
}
}
]
}
Идентификация магазина
В ShopLocator передайте один из идентификаторов магазина. Для обычной
интеграции используйте Identifier.
| Параметр | Описание |
|---|---|
Identifier | MerchantLogin магазина. Рекомендуемый способ идентификации. |
Параметры чека
В одном запросе можно зарегистрировать несколько чеков. Для каждой операции
создайте отдельный элемент массива Receipts со своим OpId и составом
Items.
| Параметр | Описание |
|---|---|
OpId | Robox ID успешно оплаченной операции. |
Url | Необязательный URL главной страницы магазина. Передавайте полный адрес без URL-кодирования. |
TaxScheme | Система налогообложения. Регистр символов важен. |
Type | Тип чека. Для продажи используйте Sell. |
VatType | Ставка НДС для чека. Регистр символов важен. |
Items | Массив товарных позиций. |
CorrectionInfo | Данные чека коррекции. Не передавайте для обычного чека. |
Payments | Распределение суммы чека по типам платежа. |
Client | Email и телефон покупателя. Передайте хотя бы один контакт. |
Возможные значения TaxScheme: Osn, UsnIncome, UsnIncomeOutcome, Envd,
Esn, Patent, AusnIncome, AusnIncomeOutcome.
Возможные значения VatType: None, Vat0, Vat10, Vat18, Vat110,
Vat118, Vat20, Vat120, Vat12, Vat8, Vat5, Vat105, Vat7,
Vat107, Vat22, Vat122.
Позиции чека
Основные параметры товарной позиции:
| Параметр | Описание |
|---|---|
Name | Наименование товара или услуги, не более 128 символов. Специальные символы экранируйте по правилам JSON. |
Quantity | Количество товара или услуги. |
Sum | Полная сумма позиции. |
Cost | Цена единицы товара или услуги. |
BonusSum | Часть стоимости позиции, оплаченная бонусами. |
VatType | Ставка НДС позиции. |
PaymentMethod | Признак способа расчета, например Advance или FullPayment. |
PaymentObject | Признак предмета расчета, например Payment, Commodity или Service. |
NomenclatureCode | Код маркировки. Передавайте значение со сканера без дополнительного кодирования. |
AgentInfo | Данные агента. |
SupplierInfo | Наименование, ИНН и телефоны поставщика. |
IsNonAgentItem | Необязательный признак отключения агентской схемы для отдельной позиции. |
Распределение платежей
В массиве Payments укажите, какими средствами оплачен чек.
Значение Type | Описание |
|---|---|
Cash | Наличные. |
Cashless | Безналичная оплата. |
Advance | Зачет ранее внесенного аванса. |
Credit | Оплата в кредит. |
Another | Иная форма оплаты. |
В Sum передайте сумму соответствующего типа платежа. Если типов несколько,
сумма всех элементов Payments должна соответствовать итоговой сумме чека.
Данные покупателя
В блоке Client передайте Email, Phone или оба значения:
{
"Client": {
"Email": "buyer@example.com",
"Phone": "79999999999"
}
}
Связанная фискализация
FiscalParentOpId связывает новую операцию оплаты с родительской операцией.
Используйте параметр, когда покупатель сначала вносит аванс, а затем доплачивает
остаток после определения состава и полной стоимости заказа.
Для GET-запроса добавьте параметр в платежную ссылку:
https://auth.robokassa.ru/Merchant/Index.aspx?MerchantLogin=your-shop-login&OutSum=1000&InvId=1001&SignatureValue=your-signature&IsWithoutFreeSale=true&FiscalParentOpId=58334807
Для POST-запроса передайте его вместе с остальными полями формы:
FiscalParentOpId=58334807
Например, покупатель внес аванс 1000 рублей, а итоговая стоимость услуги составила 1500 рублей:
- Создайте первую операцию на 1000 рублей без
Receiptи сIsWithoutFreeSale=true. - После оплаты зарегистрируйте через
Receipt/Registerчек с признакамиAdvanceиPayment. - Создайте вторую операцию на сумму доплаты 500 рублей.
- Передайте
FiscalParentOpIdсо значениемOpIdпервой операции иIsWithoutFreeSale=true. - После доплаты зарегистрируйте итоговый чек на 1500 рублей с фактической номенклатурой.
- В
Paymentsитогового чека укажитеAdvanceна 1000 рублей иCashlessилиCashна 500 рублей.
FiscalParentOpId можно передать при запуске оплаты через GET- или POST-запрос
к Merchant/Index.aspx, а также в Payload метода CreateInvoice. Параметр не
участвует в расчете SignatureValue обычного запроса на оплату.
Пример итогового чека
{
"ShopLocator": {
"Identifier": "your-shop-login"
},
"Receipts": [
{
"OpId": 123456790,
"Url": "https://shop.example",
"TaxScheme": "Osn",
"Type": "Sell",
"VatType": "None",
"Items": [
{
"Name": "Мастер-класс флористики",
"Quantity": 1,
"Sum": 1500,
"Cost": 1500,
"BonusSum": 0,
"VatType": "None",
"PaymentMethod": "FullPayment",
"PaymentObject": "Service"
}
],
"Payments": [
{
"Type": "Advance",
"Sum": 1000
},
{
"Type": "Cashless",
"Sum": 500
}
],
"Client": {
"Email": "buyer@example.com"
}
}
]
}
Ответ сервиса
Успешный HTTP-запрос возвращает код 200. Проверяйте как общий признак
IsSuccess, так и результат регистрации каждого чека:
{
"IsSuccess": true,
"Data": {
"ReceiptRegistrationResults": [
{
"IsSuccess": true,
"OpId": 123456789,
"ReceiptId": 987654,
"ReceiptType": "Sell",
"Errors": []
}
]
},
"Errors": []
}
Возможные типы ошибок:
| Тип | Описание |
|---|---|
InternalError | Внутренняя ошибка сервиса. Повторите запрос позже или обратитесь в поддержку. |
ValidationError | Запрос не прошел проверку. Проверьте JWT и параметры Payload. |
ProcessingError | Операция с указанным OpId не найдена или недоступна магазину. |
При некорректном JWT сервис возвращает HTTP 400:
{
"IsSuccess": false,
"Errors": [
{
"Text": "Incorrect JWT",
"Type": "ValidationError"
}
]
}